def test_nh_energy():
    """Checks total relativistic energy with NH."""
    eref = -57.681266930627
    norb = 6
    nele, h1e, h2e = build_nh_data()

    elec_hamil = general_hamiltonian.General((h1e, h2e))
    maxb = min(norb, nele)
    minb = nele - maxb
    ndim = int(binom(norb * 2, nele))
    hci = np.zeros((ndim, ndim), dtype=np.complex128)

    for i in range(0, ndim):
        wfn = fqe.get_number_conserving_wavefunction(nele, norb)
        cnt = 0
        for nbeta in range(minb, maxb + 1):
            coeff = wfn.get_coeff((nele, nele - 2 * nbeta))
            size = coeff.size
            if cnt <= i < cnt + size:
                coeff.flat[i - cnt] = 1.0
            cnt += size

        result = wfn.apply(elec_hamil)

        cnt = 0
        for nbeta in range(minb, maxb + 1):
            coeff = result.get_coeff((nele, nele - 2 * nbeta))
            for j in range(coeff.size):
                hci[cnt + j, i] = coeff.flat[j]
            cnt += coeff.size

    assert np.std(hci - hci.T.conj()) < 1.0e-8

    eigenvals, eigenvecs = np.linalg.eigh(hci)

    assert np.isclose(eref, eigenvals[0], atol=1e-8)

    orig = eigenvecs[:, 0]
    wfn = fqe.get_number_conserving_wavefunction(nele, norb)
    cnt = 0
    for nbeta in range(minb, maxb + 1):
        nalpha = nele - nbeta
        vdata = np.zeros(
            (int(binom(norb, nalpha)), int(binom(norb, nbeta))),
            dtype=np.complex128,
        )
        for i in range(vdata.size):
            vdata.flat[i] = orig[cnt + i]
        wfn._civec[(nele, nalpha - nbeta)].coeff += vdata
        cnt += vdata.size

    hwfn = wfn.apply(elec_hamil)
    ecalc = fqe.vdot(wfn, hwfn).real
    assert np.isclose(eref, ecalc, atol=1e-8)
Exemplo n.º 2
0
    def test_apply_generated_unitary(self):
        """APply the generated unitary transformation from the fqe namespace
        """
        norb = 4
        nele = 3
        time = 0.001
        ops = FermionOperator('1^ 3^ 5 0', 2.0 - 2.j) + FermionOperator(
            '0^ 5^ 3 1', 2.0 + 2.j)

        wfn = fqe.get_number_conserving_wavefunction(nele, norb)
        wfn.set_wfn(strategy='random')
        wfn.normalize()

        reference = fqe.apply_generated_unitary(wfn, time, 'taylor', ops)

        h1e = numpy.zeros((2 * norb, 2 * norb), dtype=numpy.complex128)
        h2e = hamiltonian_utils.nbody_matrix(ops, norb)
        h2e = hamiltonian_utils.antisymm_two_body(h2e)
        hamil = general_hamiltonian.General(tuple([h1e, h2e]))
        compute = wfn.apply_generated_unitary(time, 'taylor', hamil)

        for key in wfn.sectors():
            with self.subTest(key=key):
                diff = reference._civec[key].coeff - compute._civec[key].coeff
                err = linalg.norm(diff)
                self.assertTrue(err < 1.e-8)
Exemplo n.º 3
0
 def test_fqe_control_dot_vdot(self):
     """Find the dot product of two wavefunctions.
     """
     wfn1 = fqe.get_number_conserving_wavefunction(4, 8)
     wfn1.set_wfn(strategy='ones')
     wfn1.normalize()
     self.assertAlmostEqual(fqe.vdot(wfn1, wfn1), 1. + .0j)
     self.assertAlmostEqual(fqe.dot(wfn1, wfn1), 1. + .0j)
     wfn1.set_wfn(strategy='random')
     wfn1.normalize()
     self.assertAlmostEqual(fqe.vdot(wfn1, wfn1), 1. + .0j)
Exemplo n.º 4
0
def test_vbc_time_evolve():
    molecule = build_h4square_moleculardata()
    oei, tei = molecule.get_integrals()
    nele = molecule.n_electrons
    nalpha = nele // 2
    nbeta = nele // 2
    sz = 0
    norbs = oei.shape[0]
    nso = 2 * norbs
    fqe_wf = fqe.Wavefunction([[nele, sz, norbs]])
    fqe_wf.set_wfn(strategy='random')
    fqe_wf.normalize()
    nfqe_wf = fqe.get_number_conserving_wavefunction(nele, norbs)
    nfqe_wf.sector((nele, sz)).coeff = fqe_wf.sector((nele, sz)).coeff
    _, tpdm = nfqe_wf.sector((nele, sz)).get_openfermion_rdms()
    d3 = nfqe_wf.sector((nele, sz)).get_three_pdm()

    adapt = VBC(oei, tei, nalpha, nbeta, iter_max=50)
    acse_residual = two_rdo_commutator_symm(adapt.reduced_ham.two_body_tensor,
                                            tpdm, d3)
    sos_op = adapt.get_takagi_tensor_decomp(acse_residual, None)

    test_wf = copy.deepcopy(nfqe_wf)
    test_wf = sos_op.time_evolve(test_wf)

    true_wf = copy.deepcopy(nfqe_wf)
    for v, cc in zip(sos_op.basis_rotation, sos_op.charge_charge):
        vc = v.conj()
        new_tensor = np.einsum('pi,si,ij,qj,rj->pqrs', v, vc, -1j * cc, v, vc)
        if np.isclose(np.linalg.norm(new_tensor), 0):
            continue
        fop = of.FermionOperator()
        for p, q, r, s in product(range(nso), repeat=4):
            op = ((p, 1), (s, 0), (q, 1), (r, 0))
            fop += of.FermionOperator(op, coefficient=new_tensor[p, q, r, s])
        fqe_op = build_hamiltonian(1j * fop, conserve_number=True)
        true_wf = true_wf.time_evolve(1, fqe_op)
    true_wf = evolve_fqe_givens_unrestricted(true_wf, sos_op.one_body_rotation)

    assert np.isclose(abs(fqe.vdot(true_wf, test_wf))**2, 1)
Exemplo n.º 5
0
    def test_save_read(self):
        """Check that the wavefunction can be properly archived and
        retieved
        """
        numpy.random.seed(seed=409)
        wfn = get_number_conserving_wavefunction(3, 3)
        wfn.set_wfn(strategy='random')
        wfn.save('test_save_read')
        read_wfn = Wavefunction()
        read_wfn.read('test_save_read')
        for key in read_wfn.sectors():
            self.assertTrue(
                numpy.allclose(read_wfn._civec[key].coeff,
                               wfn._civec[key].coeff))
        self.assertEqual(read_wfn._symmetry_map, wfn._symmetry_map)
        self.assertEqual(read_wfn._conserved, wfn._conserved)
        self.assertEqual(read_wfn._conserve_spin, wfn._conserve_spin)
        self.assertEqual(read_wfn._conserve_number, wfn._conserve_number)
        self.assertEqual(read_wfn._norb, wfn._norb)

        os.remove('test_save_read')

        wfn = get_spin_conserving_wavefunction(2, 6)
        wfn.set_wfn(strategy='random')
        wfn.save('test_save_read')
        read_wfn = Wavefunction()
        read_wfn.read('test_save_read')
        for key in read_wfn.sectors():
            self.assertTrue(
                numpy.allclose(read_wfn._civec[key].coeff,
                               wfn._civec[key].coeff))
        self.assertEqual(read_wfn._symmetry_map, wfn._symmetry_map)
        self.assertEqual(read_wfn._conserved, wfn._conserved)
        self.assertEqual(read_wfn._conserve_spin, wfn._conserve_spin)
        self.assertEqual(read_wfn._conserve_number, wfn._conserve_number)
        self.assertEqual(read_wfn._norb, wfn._norb)

        os.remove('test_save_read')
Exemplo n.º 6
0
def test_generalized_doubles_takagi():
    molecule = build_lih_moleculardata()
    oei, tei = molecule.get_integrals()
    nele = 4
    nalpha = 2
    nbeta = 2
    sz = 0
    norbs = oei.shape[0]
    nso = 2 * norbs
    fqe_wf = fqe.Wavefunction([[nele, sz, norbs]])
    fqe_wf.set_wfn(strategy='hartree-fock')
    fqe_wf.normalize()
    _, tpdm = fqe_wf.sector((nele, sz)).get_openfermion_rdms()
    d3 = fqe_wf.sector((nele, sz)).get_three_pdm()

    soei, stei = spinorb_from_spatial(oei, tei)
    astei = np.einsum('ijkl', stei) - np.einsum('ijlk', stei)
    molecular_hamiltonian = of.InteractionOperator(0, soei, 0.25 * astei)
    reduced_ham = make_reduced_hamiltonian(molecular_hamiltonian,
                                           nalpha + nbeta)
    acse_residual = two_rdo_commutator_symm(reduced_ham.two_body_tensor, tpdm,
                                            d3)
    for p, q, r, s in product(range(nso), repeat=4):
        if p == q or r == s:
            continue
        assert np.isclose(acse_residual[p, q, r, s],
                          -acse_residual[s, r, q, p].conj())

    Zlp, Zlm, _, one_body_residual = doubles_factorization_takagi(acse_residual)
    test_fop = get_fermion_op(one_body_residual)
    # test the first four factors
    for ll in range(4):
        test_fop += 0.25 * get_fermion_op(Zlp[ll])**2
        test_fop += 0.25 * get_fermion_op(Zlm[ll])**2

        op1mat = Zlp[ll]
        op2mat = Zlm[ll]
        w1, v1 = sp.linalg.schur(op1mat)
        w1 = np.diagonal(w1)
        assert np.allclose(v1 @ np.diag(w1) @ v1.conj().T, op1mat)

        v1c = v1.conj()
        w2, v2 = sp.linalg.schur(op2mat)
        w2 = np.diagonal(w2)
        assert np.allclose(v2 @ np.diag(w2) @ v2.conj().T, op2mat)
        oww1 = np.outer(w1, w1)

        fqe_wf = fqe.Wavefunction([[nele, sz, norbs]])
        fqe_wf.set_wfn(strategy='hartree-fock')
        fqe_wf.normalize()
        nfqe_wf = fqe.get_number_conserving_wavefunction(nele, norbs)
        nfqe_wf.sector((nele, sz)).coeff = fqe_wf.sector((nele, sz)).coeff

        this_generatory = np.einsum('pi,si,ij,qj,rj->pqrs', v1, v1c, oww1, v1,
                                    v1c)
        fop = of.FermionOperator()
        for p, q, r, s in product(range(nso), repeat=4):
            op = ((p, 1), (s, 0), (q, 1), (r, 0))
            fop += of.FermionOperator(op,
                                      coefficient=this_generatory[p, q, r, s])

        fqe_fop = build_hamiltonian(1j * fop, norb=norbs, conserve_number=True)
        exact_wf = fqe.apply_generated_unitary(nfqe_wf, 1, 'taylor', fqe_fop)

        test_wf = fqe.algorithm.low_rank.evolve_fqe_givens_unrestricted(
            nfqe_wf,
            v1.conj().T)
        test_wf = fqe.algorithm.low_rank.evolve_fqe_charge_charge_unrestricted(
            test_wf, -oww1.imag)
        test_wf = fqe.algorithm.low_rank.evolve_fqe_givens_unrestricted(
            test_wf, v1)

        assert np.isclose(abs(fqe.vdot(test_wf, exact_wf))**2, 1)
Exemplo n.º 7
0
def test_random_evolution():
    sdim = 2
    nele = 2
    generator = generate_antisymm_generator(2 * sdim)
    nso = generator.shape[0]
    for p, q, r, s in product(range(nso), repeat=4):
        if p < q and s < r:
            assert np.isclose(generator[p, q, r, s], -generator[q, p, r, s])

    generator_mat = np.reshape(np.transpose(generator, [0, 3, 1, 2]),
                               (nso**2, nso**2)).astype(np.float)
    _, sigma, _ = np.linalg.svd(generator_mat)

    ul, vl, _, ul_ops, vl_ops, _ = \
        doubles_factorization_svd(generator)

    rwf = fqe.get_number_conserving_wavefunction(nele, sdim)
    # rwf = fqe.Wavefunction([[nele, 0, sdim]])
    rwf.set_wfn(strategy='random')
    rwf.normalize()

    sigma_idx = np.where(sigma > 1.0E-13)[0]
    for ll in sigma_idx:
        Smat = ul[ll] + vl[ll]
        Dmat = ul[ll] - vl[ll]

        S = ul_ops[ll] + vl_ops[ll]
        D = ul_ops[ll] - vl_ops[ll]
        op1 = S + 1j * of.hermitian_conjugated(S)
        op2 = S - 1j * of.hermitian_conjugated(S)
        op3 = D + 1j * of.hermitian_conjugated(D)
        op4 = D - 1j * of.hermitian_conjugated(D)

        op1mat = Smat + 1j * Smat.T
        op2mat = Smat - 1j * Smat.T
        op3mat = Dmat + 1j * Dmat.T
        op4mat = Dmat - 1j * Dmat.T

        o1_rwf = rwf.time_evolve(1 / 16, 1j * op1**2)
        ww, vv = np.linalg.eig(op1mat)
        assert np.allclose(vv @ np.diag(ww) @ vv.conj().T, op1mat)
        trwf = evolve_fqe_givens_unrestricted(rwf, vv.conj().T)
        v_pq = np.outer(ww, ww)
        for p, q in product(range(nso), repeat=2):
            fop = of.FermionOperator(((p, 1), (p, 0), (q, 1), (q, 0)),
                                     coefficient=-v_pq[p, q].imag)
            trwf = trwf.time_evolve(1 / 16, fop)
        trwf = evolve_fqe_givens_unrestricted(trwf, vv)
        assert np.isclose(fqe.vdot(o1_rwf, trwf), 1)

        o_rwf = rwf.time_evolve(1 / 16, 1j * op2**2)
        ww, vv = np.linalg.eig(op2mat)
        assert np.allclose(vv @ np.diag(ww) @ vv.conj().T, op2mat)
        trwf = evolve_fqe_givens_unrestricted(rwf, vv.conj().T)
        v_pq = np.outer(ww, ww)
        for p, q in product(range(nso), repeat=2):
            fop = of.FermionOperator(((p, 1), (p, 0), (q, 1), (q, 0)),
                                     coefficient=-v_pq[p, q].imag)
            trwf = trwf.time_evolve(1 / 16, fop)
        trwf = evolve_fqe_givens_unrestricted(trwf, vv)
        assert np.isclose(fqe.vdot(o_rwf, trwf), 1)

        o_rwf = rwf.time_evolve(-1 / 16, 1j * op3**2)
        ww, vv = np.linalg.eig(op3mat)
        assert np.allclose(vv @ np.diag(ww) @ vv.conj().T, op3mat)
        trwf = evolve_fqe_givens_unrestricted(rwf, vv.conj().T)
        v_pq = np.outer(ww, ww)
        for p, q in product(range(nso), repeat=2):
            fop = of.FermionOperator(((p, 1), (p, 0), (q, 1), (q, 0)),
                                     coefficient=-v_pq[p, q].imag)
            trwf = trwf.time_evolve(-1 / 16, fop)
        trwf = evolve_fqe_givens_unrestricted(trwf, vv)
        assert np.isclose(fqe.vdot(o_rwf, trwf), 1)

        o_rwf = rwf.time_evolve(-1 / 16, 1j * op4**2)
        ww, vv = np.linalg.eig(op4mat)
        assert np.allclose(vv @ np.diag(ww) @ vv.conj().T, op4mat)
        trwf = evolve_fqe_givens_unrestricted(rwf, vv.conj().T)
        v_pq = np.outer(ww, ww)
        for p, q in product(range(nso), repeat=2):
            fop = of.FermionOperator(((p, 1), (p, 0), (q, 1), (q, 0)),
                                     coefficient=-v_pq[p, q].imag)
            trwf = trwf.time_evolve(-1 / 16, fop)
        trwf = evolve_fqe_givens_unrestricted(trwf, vv)
        assert np.isclose(fqe.vdot(o_rwf, trwf), 1)
Exemplo n.º 8
0
    def test_wavefunction_print(self):
        """Check printing routine for the wavefunction.
        """
        numpy.random.seed(seed=409)
        wfn = get_number_conserving_wavefunction(3, 3)
        sector_alpha_dim, sector_beta_dim = wfn.sector((3, -3)).coeff.shape
        coeffs = numpy.arange(1,
                              sector_alpha_dim * sector_beta_dim + 1).reshape(
                                  (sector_alpha_dim, sector_beta_dim))
        wfn.sector((3, -3)).coeff = coeffs

        sector_alpha_dim, sector_beta_dim = wfn.sector((3, -1)).coeff.shape
        coeffs = numpy.arange(1,
                              sector_alpha_dim * sector_beta_dim + 1).reshape(
                                  (sector_alpha_dim, sector_beta_dim))
        wfn.sector((3, -1)).coeff = coeffs

        sector_alpha_dim, sector_beta_dim = wfn.sector((3, 1)).coeff.shape
        coeffs = numpy.arange(1,
                              sector_alpha_dim * sector_beta_dim + 1).reshape(
                                  (sector_alpha_dim, sector_beta_dim))
        wfn.sector((3, 1)).coeff = coeffs

        sector_alpha_dim, sector_beta_dim = wfn.sector((3, 3)).coeff.shape
        coeffs = numpy.arange(1,
                              sector_alpha_dim * sector_beta_dim + 1).reshape(
                                  (sector_alpha_dim, sector_beta_dim))
        wfn.sector((3, 3)).coeff = coeffs

        ref_string = 'Sector N = 3 : S_z = -3\n' + \
                     "a'000'b'111' 1\n" + \
                     "Sector N = 3 : S_z = -1\n" + \
                     "a'001'b'011' 1\n" + \
                     "a'001'b'101' 2\n" + \
                     "a'001'b'110' 3\n" + \
                     "a'010'b'011' 4\n" + \
                     "a'010'b'101' 5\n" + \
                     "a'010'b'110' 6\n" + \
                     "a'100'b'011' 7\n" + \
                     "a'100'b'101' 8\n" + \
                     "a'100'b'110' 9\n" + \
                     "Sector N = 3 : S_z = 1\n" + \
                     "a'011'b'001' 1\n" + \
                     "a'011'b'010' 2\n" + \
                     "a'011'b'100' 3\n" + \
                     "a'101'b'001' 4\n" + \
                     "a'101'b'010' 5\n" + \
                     "a'101'b'100' 6\n" + \
                     "a'110'b'001' 7\n" + \
                     "a'110'b'010' 8\n" + \
                     "a'110'b'100' 9\n" + \
                     "Sector N = 3 : S_z = 3\n" + \
                     "a'111'b'000' 1\n"
        save_stdout = sys.stdout
        sys.stdout = chkprint = StringIO()
        wfn.print_wfn()
        sys.stdout = save_stdout
        outstring = chkprint.getvalue()
        self.assertEqual(outstring, ref_string)

        wfn.print_wfn(fmt='occ')
        ref_string = "Sector N = 3 : S_z = -3\n" + \
                     "bbb 1\n" + \
                     "Sector N = 3 : S_z = -1\n" + \
                     ".b2 1\n" + \
                     "b.2 2\n" + \
                     "bba 3\n" + \
                     ".2b 4\n" + \
                     "bab 5\n" + \
                     "b2. 6\n" + \
                     "abb 7\n" + \
                     "2.b 8\n" + \
                     "2b. 9\n" + \
                     "Sector N = 3 : S_z = 1\n" + \
                     ".a2 1\n" + \
                     ".2a 2\n" + \
                     "baa 3\n" + \
                     "a.2 4\n" + \
                     "aba 5\n" + \
                     "2.a 6\n" + \
                     "aab 7\n" + \
                     "a2. 8\n" + \
                     "2a. 9\n" + \
                     "Sector N = 3 : S_z = 3\n" + \
                     "aaa 1\n"
        save_stdout = sys.stdout
        sys.stdout = chkprint = StringIO()
        wfn.print_wfn(fmt='occ')
        sys.stdout = save_stdout
        outstring = chkprint.getvalue()
        self.assertEqual(outstring, ref_string)