def test_d2_g2_mapping(): n_density, rdm_generator, transform, molecule = system_h4() density = AntiSymmOrbitalDensity(n_density, molecule.n_qubits) tpdm_aa, tpdm_bb, tpdm_ab, _ = density.construct_tpdm() tqdm_aa, tqdm_bb, tqdm_ab, _ = density.construct_thdm() phdm_ab, phdm_ba, phdm_aabb = density.construct_phdm() opdm_a, opdm_b = density.construct_opdm() bas_aa, bas_ab = geminal_spin_basis(molecule.n_orbitals) opdm_a = Tensor(opdm_a, name='ck_a') opdm_b = Tensor(opdm_b, name='ck_b') tpdm_aa = Tensor(tpdm_aa, name='cckk_aa', basis=bas_aa) tpdm_bb = Tensor(tpdm_bb, name='cckk_bb', basis=bas_aa) tpdm_ab = Tensor(tpdm_ab, name='cckk_ab', basis=bas_ab) tqdm_aa = Tensor(tqdm_aa, name='kkcc_aa', basis=bas_aa) tqdm_bb = Tensor(tqdm_bb, name='kkcc_bb', basis=bas_aa) tqdm_ab = Tensor(tqdm_ab, name='kkcc_ab', basis=bas_ab) phdm_ab = Tensor(phdm_ab, name='ckck_ab') phdm_ba = Tensor(phdm_ba, name='ckck_ba') phdm_aabb = Tensor( phdm_aabb, name='ckck_aabb' ) # What basis do we want to use for super blocks like this? rdms = MultiTensor([ opdm_a, opdm_b, tpdm_aa, tpdm_bb, tpdm_ab, tqdm_aa, tqdm_bb, tqdm_ab, phdm_ab, phdm_ba, phdm_aabb ]) dual_basis = d2_g2_mapping(molecule.n_orbitals) rdms.dual_basis = dual_basis A, _, c = rdms.synthesize_dual_basis() Amat = A.todense() cmat = c.todense() primal_vec = rdms.vectorize_tensors() residual = Amat.dot(primal_vec) - cmat assert np.allclose(residual, np.zeros_like(residual))
def test_d2_g2_mapping(): n_density, rdm_generator, transform, molecule = system_h4() # n_density, rdm_generator = system_hubbard() # n_density, rdm_generator, transform, molecule = system() dim = 4 density = AntiSymmOrbitalDensity(n_density, 2 * dim) tpdm_aa, tpdm_bb, tpdm_ab, _ = density.construct_tpdm() tqdm_aa, tqdm_bb, tqdm_ab, _ = density.construct_thdm() phdm_ab, phdm_ba, phdm_aabb = density.construct_phdm() # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i, 1), (2 * j + 1, 0), (2 * l + 1, 1), (2 * k, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(fop, n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # # print(rdm_val, phdm_ab[i * dim + j, k * dim + l]) # assert np.isclose(rdm_val, phdm_ab[i * dim + j, k * dim + l]) # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i + 1, 1), (2 * j, 0), (2 * l, 1), (2 * k + 1, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(fop, n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # assert np.isclose(rdm_val, phdm_ba[i * dim + j, k * dim + l]) # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i, 1), (2 * j, 0), (2 * k, 1), (2 * l, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(of.jordan_wigner(fop), n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # assert np.isclose(rdm_val, phdm_aabb[i * dim + j, l * dim + k]) # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i + 1, 1), (2 * j + 1, 0), (2 * k + 1, 1), (2 * l + 1, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(of.jordan_wigner(fop), n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # # print((i, j, k, l), rdm_val, phdm_aabb[i * dim + j + dim**2, l * dim + k + dim**2]) # assert np.isclose(rdm_val, phdm_aabb[i * dim + j + dim**2, l * dim + k + dim**2]) # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i, 1), (2 * j, 0), (2 * k + 1, 1), (2 * l + 1, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(of.jordan_wigner(fop), n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # assert np.isclose(rdm_val, phdm_aabb[i * dim + j, l * dim + k + dim**2]) # for i, j, k, l in product(range(dim), repeat=4): # fop = ((2 * i + 1, 1), (2 * j + 1, 0), (2 * l, 1), (2 * k, 0)) # fop = of.FermionOperator(fop) # opmat = of.get_sparse_operator(of.jordan_wigner(fop), n_qubits=2 * dim) # rdm_val = (np.trace(n_density @ opmat)) # # print((i, j, k, l), rdm_val, phdm_aabb[i * dim + j + dim**2, k * dim + l]) # assert np.isclose(rdm_val, phdm_aabb[i * dim + j + dim**2, k * dim + l]) # for i, j, k, l in product(range(dim), repeat=4): # assert np.isclose(phdm_aabb[i * dim + j + dim**2, k * dim + l], # phdm_aabb[k * dim + l, i * dim + j + dim**2] # ) assert of.is_hermitian(phdm_ab) assert of.is_hermitian(phdm_ba) assert of.is_hermitian(phdm_aabb) w, v = np.linalg.eigh(phdm_ab) assert np.all(w > -1.0E-14) w, v = np.linalg.eigh(phdm_ba) assert np.all(w > -1.0E-14) w, v = np.linalg.eigh(phdm_aabb) assert np.all(w > -1.0E-14) opdm_a, opdm_b = density.construct_opdm() bas_aa, bas_ab = geminal_spin_basis(dim) opdm_a = Tensor(opdm_a, name='ck_a') opdm_b = Tensor(opdm_b, name='ck_b') tpdm_aa = Tensor(tpdm_aa, name='cckk_aa', basis=bas_aa) tpdm_bb = Tensor(tpdm_bb, name='cckk_bb', basis=bas_aa) tpdm_ab = Tensor(tpdm_ab, name='cckk_ab', basis=bas_ab) tqdm_aa = Tensor(tqdm_aa, name='kkcc_aa', basis=bas_aa) tqdm_bb = Tensor(tqdm_bb, name='kkcc_bb', basis=bas_aa) tqdm_ab = Tensor(tqdm_ab, name='kkcc_ab', basis=bas_ab) phdm_ab = Tensor(phdm_ab, name='ckck_ab', basis=bas_ab) phdm_ba = Tensor(phdm_ba, name='ckck_ba', basis=bas_ab) phdm_aabb = Tensor( phdm_aabb, name='ckck_aabb' ) # What basis do we want to use for super blocks like this? rdms = MultiTensor([ opdm_a, opdm_b, tpdm_aa, tpdm_bb, tpdm_ab, tqdm_aa, tqdm_bb, tqdm_ab, phdm_ab, phdm_ba, phdm_aabb ]) dual_basis = d2_g2_mapping(dim) rdms.dual_basis = dual_basis A, _, c = rdms.synthesize_dual_basis() Amat = A.todense() cmat = c.todense() primal_vec = rdms.vectorize_tensors() residual = Amat.dot(primal_vec) - cmat assert np.allclose(residual, np.zeros_like(residual))
def dqg_run_bpsdp(): import sys from openfermion.hamiltonians import MolecularData from openfermionpsi4 import run_psi4 from openfermionpyscf import run_pyscf from openfermion.utils import map_one_pdm_to_one_hole_dm, \ map_two_pdm_to_two_hole_dm, map_two_pdm_to_particle_hole_dm print('Running System Setup') basis = 'sto-6g' # basis = '6-31g' multiplicity = 1 # charge = 0 # geometry = [('H', [0.0, 0.0, 0.0]), ('H', [0, 0, 0.75])] # charge = 1 # geometry = [('H', [0.0, 0.0, 0.0]), ('He', [0, 0, 0.75])] charge = 0 bd = 1.2 # geometry = [('H', [0.0, 0.0, 0.0]), ('H', [0, 0, bd]), # ('H', [0.0, 0.0, 2 * bd]), ('H', [0, 0, 3 * bd])] # geometry = [['H', [0, 0, 0]], ['H', [1.2, 0, 0]], # ['H', [0, 1.2, 0]], ['H', [1.2, 1.2, 0]]] # geometry = [['He', [0, 0, 0]], ['H', [0, 0, 1.2]]] # geometry = [['Be' [0, 0, 0]], [['B', [1.2, 0, 0]]]] geometry = [['N', [0, 0, 0]], ['N', [0, 0, 1.1]]] molecule = MolecularData(geometry, basis, multiplicity, charge) # Run Psi4. # molecule = run_psi4(molecule, # run_scf=True, # run_mp2=False, # run_cisd=False, # run_ccsd=False, # run_fci=True, # delete_input=True) molecule = run_pyscf(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True) print('nuclear_repulsion', molecule.nuclear_repulsion) print('gs energy ', molecule.fci_energy) print("hf energy ", molecule.hf_energy) nuclear_repulsion = molecule.nuclear_repulsion gs_energy = molecule.fci_energy import openfermion as of hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=[0], active_indices=[1, 2, 3, 4]) print(type(hamiltonian)) print(hamiltonian) nuclear_repulsion = hamiltonian.constant hamiltonian.constant = 0 ham = of.get_sparse_operator(hamiltonian).toarray() w, v = np.linalg.eigh(ham) idx = 0 gs_energy = w[idx] n_density = v[:, [idx]] @ v[:, [idx]].conj().T from representability.fermions.density.antisymm_sz_density import AntiSymmOrbitalDensity density = AntiSymmOrbitalDensity(n_density, 8) opdm_a, opdm_b = density.construct_opdm() tpdm_aa, tpdm_bb, tpdm_ab, _ = density.construct_tpdm() true_tpdm = density.get_tpdm(density.rho, density.dim) true_tpdm = true_tpdm.transpose(0, 1, 3, 2) test_tpdm = unspin_adapt(tpdm_aa, tpdm_bb, tpdm_ab) assert np.allclose(true_tpdm, test_tpdm) tqdm_aa, tqdm_bb, tqdm_ab, _ = density.construct_thdm() phdm_ab, phdm_ba, phdm_aabb = density.construct_phdm() Na = np.round(opdm_a.trace()).real Nb = np.round(opdm_b.trace()).real one_body_ints, two_body_ints = hamiltonian.one_body_tensor, hamiltonian.two_body_tensor two_body_ints = np.einsum('ijkl->ijlk', two_body_ints) n_electrons = Na + Nb print('n_electrons', n_electrons) dim = one_body_ints.shape[0] spatial_basis_rank = dim // 2 bij_bas_aa, bij_bas_ab = geminal_spin_basis(spatial_basis_rank) opdm_a_interaction, opdm_b_interaction, v2aa, v2bb, v2ab = \ spin_adapted_interaction_tensor_rdm_consistent(two_body_ints, one_body_ints) dual_basis = sz_adapted_linear_constraints( spatial_basis_rank, Na, Nb, ['ck', 'kc', 'cckk', 'ckck', 'kkcc'], S=1, M=-1) print("constructed dual basis") opdm_a = Tensor(opdm_a, name='ck_a') opdm_b = Tensor(opdm_b, name='ck_b') oqdm_a = Tensor(np.eye(dim // 2) - opdm_a.data, name='kc_a') oqdm_b = Tensor(np.eye(dim // 2) - opdm_b.data, name='kc_b') tpdm_aa = Tensor(tpdm_aa, name='cckk_aa', basis=bij_bas_aa) tpdm_bb = Tensor(tpdm_bb, name='cckk_bb', basis=bij_bas_aa) tpdm_ab = Tensor(tpdm_ab, name='cckk_ab', basis=bij_bas_ab) tqdm_aa = Tensor(tqdm_aa, name='kkcc_aa', basis=bij_bas_aa) tqdm_bb = Tensor(tqdm_bb, name='kkcc_bb', basis=bij_bas_aa) tqdm_ab = Tensor(tqdm_ab, name='kkcc_ab', basis=bij_bas_ab) phdm_ab = Tensor(phdm_ab, name='ckck_ab', basis=bij_bas_ab) phdm_ba = Tensor(phdm_ba, name='ckck_ba', basis=bij_bas_ab) phdm_aabb = Tensor(phdm_aabb, name='ckck_aabb') dtensor = MultiTensor([ opdm_a, opdm_b, oqdm_a, oqdm_b, tpdm_aa, tpdm_bb, tpdm_ab, tqdm_aa, tqdm_bb, tqdm_ab, phdm_ab, phdm_ba, phdm_aabb ]) copdm_a = opdm_a_interaction copdm_b = opdm_b_interaction coqdm_a = Tensor(np.zeros((spatial_basis_rank, spatial_basis_rank)), name='kc_a') coqdm_b = Tensor(np.zeros((spatial_basis_rank, spatial_basis_rank)), name='kc_b') ctpdm_aa = v2aa ctpdm_bb = v2bb ctpdm_ab = v2ab ctqdm_aa = Tensor(np.zeros_like(v2aa.data), name='kkcc_aa', basis=bij_bas_aa) ctqdm_bb = Tensor(np.zeros_like(v2bb.data), name='kkcc_bb', basis=bij_bas_aa) ctqdm_ab = Tensor(np.zeros_like(v2ab.data), name='kkcc_ab', basis=bij_bas_ab) cphdm_ab = Tensor(np.zeros((spatial_basis_rank**2, spatial_basis_rank**2)), name='ckck_ab', basis=bij_bas_ab) cphdm_ba = Tensor(np.zeros((spatial_basis_rank**2, spatial_basis_rank**2)), name='ckck_ba', basis=bij_bas_ab) cphdm_aabb = Tensor(np.zeros( (2 * spatial_basis_rank**2, 2 * spatial_basis_rank**2)), name='ckck_aabb') ctensor = MultiTensor([ copdm_a, copdm_b, coqdm_a, coqdm_b, ctpdm_aa, ctpdm_bb, ctpdm_ab, ctqdm_aa, ctqdm_bb, ctqdm_ab, cphdm_ab, cphdm_ba, cphdm_aabb ]) print( (ctensor.vectorize_tensors().T @ dtensor.vectorize_tensors())[0, 0].real) print(gs_energy) ctensor.dual_basis = dual_basis A, _, b = ctensor.synthesize_dual_basis() print("size of dual basis", len(dual_basis.elements)) print(A @ dtensor.vectorize_tensors() - b) nc, nv = A.shape A.eliminate_zeros() nnz = A.nnz from sdpsolve.sdp import SDP from sdpsolve.solvers.bpsdp import solve_bpsdp from sdpsolve.solvers.bpsdp.bpsdp_old import solve_bpsdp from sdpsolve.utils.matreshape import vec2block sdp = SDP() sdp.nc = nc sdp.nv = nv sdp.nnz = nnz sdp.blockstruct = list(map(lambda x: int(np.sqrt(x.size)), ctensor.tensors)) sdp.nb = len(sdp.blockstruct) sdp.Amat = A.real sdp.bvec = b.todense().real sdp.cvec = ctensor.vectorize_tensors().real sdp.Initialize() epsilon = 1.0E-7 sdp.epsilon = float(epsilon) sdp.epsilon_inner = float(epsilon) / 100 sdp.disp = True sdp.iter_max = 70000 sdp.inner_solve = 'CG' sdp.inner_iter_max = 2 # # sdp_data = solve_bpsdp(sdp) solve_bpsdp(sdp) # # create all the psd-matrices for the # variable_dictionary = {} # for tensor in ctensor.tensors: # linear_dim = int(np.sqrt(tensor.size)) # variable_dictionary[tensor.name] = cvx.Variable(shape=(linear_dim, linear_dim), PSD=True, name=tensor.name) # print("constructing constraints") # constraints = [] # for dbe in dual_basis: # single_constraint = [] # for tname, v_elements, p_coeffs in dbe: # active_indices = get_var_indices(ctensor.tensors[tname], v_elements) # single_constraint.append(variable_dictionary[tname][active_indices] * p_coeffs) # constraints.append(cvx.sum(single_constraint) == dbe.dual_scalar) # print('constraints constructed') # print("constructing the problem") # objective = cvx.Minimize( # cvx.trace(copdm_a.data @ variable_dictionary['ck_a']) + # cvx.trace(copdm_b.data @ variable_dictionary['ck_b']) + # cvx.trace(ctpdm_aa.data @ variable_dictionary['cckk_aa']) + # cvx.trace(ctpdm_bb.data @ variable_dictionary['cckk_bb']) + # cvx.trace(ctpdm_ab.data @ variable_dictionary['cckk_ab'])) # cvx_problem = cvx.Problem(objective, constraints=constraints) # print('problem constructed') # cvx_problem.solve(solver=cvx.SCS, verbose=True, eps=0.5E-5, max_iters=100000) # rdms_solution = vec2block(sdp.blockstruct, sdp.primal) print(gs_energy) # print(cvx_problem.value + nuclear_repulsion) # print(sdp_data.primal_value() + nuclear_repulsion) print(sdp.primal.T @ sdp.cvec) print(nuclear_repulsion) rdms = vec2block(sdp.blockstruct, sdp.primal) tpdm = unspin_adapt(rdms[4], rdms[5], rdms[6]) print(np.einsum('ijij', tpdm)) tpdm = np.einsum('ijkl->ijlk', tpdm)