def test_dmat_to_full1(): dmat = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) full = numpy.zeros((3,3), float) dmat_to_full(dmat, full) expected_full = numpy.array([[1.0, 2.0, 4.0], [2.0, 3.0, 5.0], [4.0, 5.0, 6.0]]) error = abs(full - expected_full).max() assert(error < 1e-10)
def compute_naturals(dmat, num_dof): # transform the dmat into conventional storage full = numpy.zeros((num_dof, num_dof), float) dmat_to_full(dmat, full) # use numpy for diagonalization occupations, orbitals = numpy.linalg.eigh(full) # repack the arrays from the eigenvalue analysis in final order occupations = numpy.array(occupations[::-1]) orbitals = numpy.array(orbitals.transpose()[::-1]) return occupations, orbitals
def check_hf_overlap_matrices(scheme): scheme.do_charges() scheme.do_atgrids_overlap_matrix() num_dof = scheme.context.wavefn.num_orbitals full = numpy.zeros((num_dof, num_dof), float) dmat_to_full(scheme.context.wavefn.density_matrix, full) for i in xrange(scheme.molecule.size): overlap = scheme.atgrids[i].overlap_matrix error = abs(overlap - overlap.transpose()).max() assert (error < 1e-10) population = (full * overlap).sum() check_population = scheme.populations[i] error = abs(population - check_population) assert (error < 1e-10)
def check_hf_overlap_matrices(scheme): scheme.do_charges() scheme.do_atgrids_overlap_matrix() num_dof = scheme.context.wavefn.num_orbitals full = numpy.zeros((num_dof,num_dof), float) dmat_to_full(scheme.context.wavefn.density_matrix, full) for i in xrange(scheme.molecule.size): overlap = scheme.atgrids[i].overlap_matrix error = abs(overlap-overlap.transpose()).max() assert(error<1e-10) population = (full*overlap).sum() check_population = scheme.populations[i] error = abs(population-check_population) assert(error<1e-10)
def test_dmat_to_full2(): num_dof = 10 size = (num_dof*(num_dof+1))/2 dmat = numpy.random.normal(0, 1, size) full = numpy.zeros((num_dof,num_dof), float) dmat_to_full(dmat, full) expected_full = numpy.zeros((num_dof,num_dof), float) counter = 0 for i in xrange(num_dof): row = dmat[counter:counter+i+1] expected_full[i,:i+1] = row expected_full[:i+1,i] = row counter += i+1 error = abs(full - expected_full).max() assert(error < 1e-10)
def test_compute_naturals(): num_dof = 10 # generate random symmetric matric A = numpy.random.normal(0,1,(num_dof, num_dof)) A = A + A.transpose() # diagonalize to get the fake orbitals check_orbitals = numpy.linalg.eigh(A)[1].transpose() # invent occupation numbers check_occupations = numpy.random.normal(0, 1, num_dof) check_occupations.sort() check_occupations = check_occupations[::-1] # reconstruct the full density matrix check_foo = check_orbitals.transpose() full = numpy.dot(check_occupations*check_foo, check_foo.transpose()) # intermediate test occupations, foo = numpy.linalg.eigh(full) occupations = occupations[::-1] foo = foo[:,::-1] orbitals = foo.transpose() error = abs(occupations - check_occupations).max() assert(error<1e-10) overlap = abs(numpy.dot(orbitals, check_orbitals.transpose()).round()) error = abs(overlap - numpy.identity(num_dof)).max() assert(error<1e-10) # make it compact size = (num_dof*(num_dof+1))/2 dmat = numpy.zeros(size, float) counter = 0 for i in xrange(num_dof): dmat[counter:counter+i+1] = full[i,:i+1] counter += i+1 check_full = numpy.zeros((num_dof, num_dof), float) dmat_to_full(dmat, check_full) error = abs(full - check_full).max() assert(error<1e-10) # run the routine to be tested occupations, orbitals = compute_naturals(dmat, num_dof) error = abs(occupations - check_occupations).max() assert(error<1e-10) overlap = abs(numpy.dot(orbitals, check_orbitals.transpose()).round()) error = abs(overlap - numpy.identity(num_dof)).max() assert(error<1e-10)
def test_compute_naturals(): num_dof = 10 # generate random symmetric matric A = numpy.random.normal(0, 1, (num_dof, num_dof)) A = A + A.transpose() # diagonalize to get the fake orbitals check_orbitals = numpy.linalg.eigh(A)[1].transpose() # invent occupation numbers check_occupations = numpy.random.normal(0, 1, num_dof) check_occupations.sort() check_occupations = check_occupations[::-1] # reconstruct the full density matrix check_foo = check_orbitals.transpose() full = numpy.dot(check_occupations * check_foo, check_foo.transpose()) # intermediate test occupations, foo = numpy.linalg.eigh(full) occupations = occupations[::-1] foo = foo[:, ::-1] orbitals = foo.transpose() error = abs(occupations - check_occupations).max() assert (error < 1e-10) overlap = abs(numpy.dot(orbitals, check_orbitals.transpose()).round()) error = abs(overlap - numpy.identity(num_dof)).max() assert (error < 1e-10) # make it compact size = (num_dof * (num_dof + 1)) / 2 dmat = numpy.zeros(size, float) counter = 0 for i in xrange(num_dof): dmat[counter:counter + i + 1] = full[i, :i + 1] counter += i + 1 check_full = numpy.zeros((num_dof, num_dof), float) dmat_to_full(dmat, check_full) error = abs(full - check_full).max() assert (error < 1e-10) # run the routine to be tested occupations, orbitals = compute_naturals(dmat, num_dof) error = abs(occupations - check_occupations).max() assert (error < 1e-10) overlap = abs(numpy.dot(orbitals, check_orbitals.transpose()).round()) error = abs(overlap - numpy.identity(num_dof)).max() assert (error < 1e-10)
def do_bond_orders(self): # first try to load the results from the work dir bond_orders_name = "%s_bond_orders" % self.prefix valences_name = "%s_valences" % self.prefix self.bond_orders = self.work.load(bond_orders_name, (self.molecule.size, self.molecule.size)) self.valences = self.work.load(valences_name) if self.bond_orders is None or self.valences is None: self.do_charges() self.do_atgrids_overlap_matrix() self.bond_orders = numpy.zeros((self.molecule.size, self.molecule.size)) self.valences = numpy.zeros(self.molecule.size) num_dof = self.wavefn.num_orbitals full = numpy.zeros((num_dof, num_dof), float) dmat_to_full(self.wavefn.density_matrix, full) if self.wavefn.spin_density_matrix is None: full_alpha = 0.5*full full_beta = full_alpha else: full_alpha = numpy.zeros((num_dof, num_dof), float) full_beta = numpy.zeros((num_dof, num_dof), float) dmat_to_full( 0.5*(self.wavefn.density_matrix + self.wavefn.spin_density_matrix), full_alpha ) dmat_to_full( 0.5*(self.wavefn.density_matrix - self.wavefn.spin_density_matrix), full_beta ) pb = log.pb("Computing bond orders", (self.molecule.size*(self.molecule.size+1))/2) for i in xrange(self.molecule.size): for j in xrange(i+1): pb() if i==j: # compute valence tmp = numpy.dot(full, self.atgrids[i].overlap_matrix) self.valences[i] = 2*self.populations[i] - (tmp*tmp.transpose()).sum() else: # compute bond order bo = ( numpy.dot(full_alpha, self.atgrids[i].overlap_matrix)* numpy.dot(full_alpha, self.atgrids[j].overlap_matrix).transpose() ).sum() if full_alpha is full_beta: bo *= 2 else: bo += ( numpy.dot(full_beta, self.atgrids[i].overlap_matrix)* numpy.dot(full_beta, self.atgrids[j].overlap_matrix).transpose() ).sum() bo *= 2 self.bond_orders[i,j] = bo self.bond_orders[j,i] = bo pb() self.work.dump(bond_orders_name, self.bond_orders) self.work.dump(valences_name, self.valences) self.free_valences = self.valences - self.bond_orders.sum(axis=1) self.output.dump_atom_matrix("%s_bond_orders.txt" % self.prefix, self.bond_orders, "Bond order") self.output.dump_atom_scalars("%s_valences.txt" % self.prefix, self.valences, "Valences") self.output.dump_atom_scalars("%s_free_valences.txt" % self.prefix, self.free_valences, "Free valences")