Exemplo n.º 1
0
def test_sparse_operator2():
    """Test the SparseHamiltonian class"""

    import pytest
    import forte
    import forte.utils
    import psi4
    from forte import det

    geom = """
     H
     H 1 1.0
    """
    scf_energy, psi4_wfn = forte.utils.psi4_scf(geom,
                                                basis='DZ',
                                                reference='RHF')
    forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={})

    as_ints = forte_objs['as_ints']

    ham_op = forte.SparseHamiltonian(as_ints)

    ref = forte.StateVector({det("20"): 1.0})
    Href1 = ham_op.compute(ref, 0.0)
    Href2 = ham_op.compute_on_the_fly(ref, 0.0)
    assert Href1[det("20")] == pytest.approx(-1.094572, abs=1e-6)
    assert Href2[det("20")] == pytest.approx(-1.094572, abs=1e-6)

    psi4.core.clean()
Exemplo n.º 2
0
def det(s):
    return forte.det(s)
Exemplo n.º 3
0
def test_sparse_operator():
    import forte
    import pytest
    from forte import det

    # test get/set
    sop = forte.SparseOperator()
    sop.add_term_from_str('[]')
    sop.add_term_from_str('[0a+ 0b+ 0b- 0a-]')
    to_str = sop.str()
    assert to_str == []
    to_latex = sop.latex()
    assert to_latex == r'0.000000\; 0.000000\;\hat{a}_{0 \alpha}^\dagger\hat{a}_{0 \beta}^\dagger\hat{a}_{0 \beta}\hat{a}_{0 \alpha}'

    sop = forte.SparseOperator(antihermitian=True)
    sop.add_term_from_str('[1a+ 1b+ 0b- 0a-]', 1.0)
    to_str = sop.str()
    assert to_str == ['1.000000000000 * [ 1a+ 1b+ 0b- 0a- ]', '-1.000000000000 * [ 0a+ 0b+ 1b- 1a- ]']
    to_latex = sop.latex()
    assert to_latex == r'+\;\hat{a}_{1 \alpha}^\dagger\hat{a}_{1 \beta}^\dagger\hat{a}_{0 \beta}\hat{a}_{0 \alpha} -\;\hat{a}_{0 \alpha}^\dagger\hat{a}_{0 \beta}^\dagger\hat{a}_{1 \beta}\hat{a}_{1 \alpha}'

    sop = forte.SparseOperator()
    sop.add_term_from_str('[]')
    sop.add_term_from_str('[0a+ 0b+ 0b- 0a-]')

    coeff = sop.coefficients()
    assert coeff == pytest.approx([0.0, 0.0], abs=1e-9)
    sop.set_coefficient(0, 0.5)
    sop.set_coefficient(1, 0.3)
    coeff = sop.coefficients()
    assert coeff == pytest.approx([0.5, 0.3], abs=1e-9)
    # remove one term from sop
    sop.pop_term()
    # check the size
    assert sop.size() == 1
    # copy a term into a new operator
    sop2 = forte.SparseOperator()
    sop2.add_term(sop.term(0))

    # test apply operator against safe implementation
    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 0a-]', 0.0)
    sop.add_term_from_str('[1a+ 0a-]', 0.1)
    sop.add_term_from_str('[1b+ 0b-]', 0.3)
    sop.add_term_from_str('[1a+ 1b+ 0b- 0a-]', 0.5)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    wfn_safe = forte.apply_operator_safe(sop, ref)
    assert wfn == wfn_safe

    sop = forte.SparseOperator(antihermitian=True)
    sop.add_term_from_str('[2a+ 0a-]', 0.0)
    sop.add_term_from_str('[1a+ 0a-]', 0.1)
    sop.add_term_from_str('[1b+ 0b-]', 0.3)
    sop.add_term_from_str('[1a+ 1b+ 0b- 0a-]', 0.7)
    ref = forte.StateVector({det("20"): 1.0, det("02"): 0.5})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("20")] == pytest.approx(-0.35, abs=1e-9)
    assert wfn[det("02")] == pytest.approx(0.7, abs=1e-9)
    assert wfn[det("+-")] == pytest.approx(0.25, abs=1e-9)
    assert wfn[det("-+")] == pytest.approx(-0.05, abs=1e-9)

    # wfn_safe = forte.apply_operator_safe(sop,ref)
    # assert wfn == wfn_safe

    ### Operator ordering tests ###

    # test repeated operator exception
    sop = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[0a+ 0a+]', 1.0)

    sop = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[1b+ 1b+]', 1.0)

    sop = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[5a- 5a-]', 1.0)

    sop = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[3b- 3b-]', 1.0)

    # test ordering exception
    sop = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[0a+ 0b+ 0a- 0b-]', 1.0)

    # test ordering exception
    sop = forte.SparseOperator(antihermitian=True)
    with pytest.raises(RuntimeError):
        sop.add_term_from_str('[]', 1.0)

    # test ordering: 0a+ 0b+ 0b- 0a- |2> = +|2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0b+ 0b- 0a-]', 1.0)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test ordering: 0a+ 0b+ 0a- 0b- |2> = -|2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0b+ 0a- 0b-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(-1.0, abs=1e-9)

    # test ordering: 0b+ 0a+ 0b- 0a- |2> = -|2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0a+ 0b- 0a-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(-1.0, abs=1e-9)

    # test ordering: 0b+ 0a+ 0a- 0b- |2> = +|2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0a+ 0a- 0b-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test ordering: 3a+ 4a+ 2b+ 1b- 0a- |22000> = + 3a+ 4a+ 2b+ 1b- |-2000>
    # 3a+ 4a+ 2b+ 1b- 0a- |22000> = + 3a+ 4a+ 2b+ 1b- |-2000>
    #                             = + 3a+ 4a+ 2b+ |-+000>
    #                             = + 3a+ 4a+ |-+-00>
    #                             = - 3a+ |-+-0+>
    #                             = + 3a+ |-+-++>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[3a+ 4a+ 2b+ 1b- 0a-]', 1.0)
    ref = forte.StateVector({det("22"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("-+-++")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 1a+]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("++")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 1a+ 2a+]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 1a+ 2a+ 3a+]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("++++")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 1a+ 2a+ 3a+ 4a+]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++++")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 0a+ 3a+ 1a+ 4a+]', 1.0, allow_reordering=True)
    wfn = forte.apply_operator(sop, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++++")] == pytest.approx(-1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a-]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-2222")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[1a- 0a-]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("--222")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("---22")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[3a- 2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("----2")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[4a- 3a- 2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-----")] == pytest.approx(1.0, abs=1e-9)

    sop = forte.SparseOperator()
    sop.add_term_from_str('[1a- 3a- 2a- 4a- 0a-]', 1.0, allow_reordering=True)
    wfn = forte.apply_operator(sop, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-----")] == pytest.approx(-1.0, abs=1e-9)

    ### Test for cases that are supposed to return zero ###
    # test destroying empty orbitals: (0a+ 0b+ 0b- 0a-) |0> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0b+ 0b- 0a-]', 1.0)
    dtest = det("00")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test destroying empty orbitals: (0a+ 0b+ 0b- 0a-) |0> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0b+ 0b-]', 1.0)
    dtest = det("00")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test creating in filled orbitals: (0a+ 1a+ 0a-) |22> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[1a+ 0a+ 0a-]', 1.0, allow_reordering=True)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test creating in filled orbitals: (0a+ 1a+ 0a-) |22> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[1b+ 0a+ 0a-]', 1.0, allow_reordering=True)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    ### Number operator tests ###
    # test number operator: (0a+ 0a-) |0> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("0")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test number operator: (0a+ 0a-) |+> = |+>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0a+ 0a-) |-> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("-")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test number operator: (0a+ 0a-) |2> = |2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("2")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0b+ 0b-) |0> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("0")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test number operator: (0b+ 0b-) |+> = 0
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    # test number operator: (0b+ 0b-) |-> = |->
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("-")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0b+ 0b-) |2> = |2>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0b+ 0b-]', 1.0)
    ref = forte.StateVector({det("2"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("2")] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (2a+ 2a- + 2b+ 2b-) |222> = |222>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 2a-]', 1.0)
    sop.add_term_from_str('[2b+ 2b-]', 1.0)
    ref = forte.StateVector({det("222"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("222")] == pytest.approx(2.0, abs=1e-9)

    # test number operator: (2a+ 2a- + 2b+ 2b-) |22+> = |22+>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 2a-]', 1.0)
    sop.add_term_from_str('[2b+ 2b-]', 1.0)
    ref = forte.StateVector({det("22+"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("22+")] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (2a+ 2a- + 2b+ 2b-) |22-> = |22->
    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 2a-]', 1.0)
    sop.add_term_from_str('[2b+ 2b-]', 1.0)
    ref = forte.StateVector({det("22-"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("22-")] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (2a+ 2a- + 2b+ 2b-) |220> = |220>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[2a+ 2a-]', 1.0)
    sop.add_term_from_str('[2b+ 2b-]', 1.0)
    ref = forte.StateVector({det("220"): 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert dtest not in wfn

    ### Excitation operator tests ###
    # test excitation operator: (3a+ 0a-) |2200> = 3a+ |-200> = -|-20+>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[3a+ 0a-]', 1.0)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("-20+")] == pytest.approx(-1.0, abs=1e-9)

    # test excitation operator: (0a- 3a+) |22> = 0a- |220+> = |-20+>
    sop = forte.SparseOperator()
    sop.add_term_from_str('[0a- 3a+]', 1.0, allow_reordering=True)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("-20+")] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (3b+ 0b-) |2200> = 3b+ |+200> = |+20->
    sop = forte.SparseOperator()
    sop.add_term_from_str('[3b+ 0b-]', 1.0)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(sop, ref)
    assert wfn[det("+20-")] == pytest.approx(-1.0, abs=1e-9)
Exemplo n.º 4
0
def test_sparse_vector():
    import pytest
    import forte
    from forte import det

    ### Overlap tests ###
    ref = forte.StateVector({
        det(""): 1.0,
        det("+"): 1.0,
        det("-"): 1.0,
        det("2"): 1.0,
        det("02"): 1.0
    })
    ref2 = forte.StateVector({det("02"): 0.3})
    ref3 = forte.StateVector({det("002"): 0.5})
    assert forte.overlap(ref, ref) == pytest.approx(5.0, abs=1e-9)
    assert forte.overlap(ref, ref2) == pytest.approx(0.3, abs=1e-9)
    assert forte.overlap(ref2, ref) == pytest.approx(0.3, abs=1e-9)
    assert forte.overlap(ref, ref3) == pytest.approx(0.0, abs=1e-9)

    ref_str = ref.str(2)

    ### Number projection tests ###
    proj1 = forte.StateVector({det("2"): 1.0, det("02"): 1.0})
    test_proj1 = forte.apply_number_projector(1, 1, ref)
    assert proj1 == test_proj1

    proj2 = forte.StateVector({det(""): 1.0})
    test_proj2 = forte.apply_number_projector(0, 0, ref)
    assert proj2 == test_proj2

    proj3 = forte.StateVector({det("+"): 1.0})
    test_proj3 = forte.apply_number_projector(1, 0, ref)
    assert proj3 == test_proj3

    proj4 = forte.StateVector({det("-"): 1.0})
    test_proj4 = forte.apply_number_projector(0, 1, ref)
    assert proj4 == test_proj4
Exemplo n.º 5
0
def test_sparse_ci4():
    import pytest
    from forte import det

    ### Test the linear operator ###
    op = forte.SparseOperator()
    ref = forte.StateVector({det("22"): 1.0})
    op.add_term_from_str('[2a+ 0a-]', 0.1)
    op.add_term_from_str('[2b+ 0b-]', 0.2)
    op.add_term_from_str('[2a+ 0a-]', 0.2)
    op.add_term_from_str('[2b+ 0b-]', 0.1)
    op.add_term_from_str('[2a+ 2b+ 0b- 0a-]', 0.15)
    op.add_term_from_str('[3a+ 3b+ 1b- 1a-]', -0.21)
    op.add_term_from_str('[1a+ 1b+ 3b- 3a-]', 0.13 * 0.17)

    wfn = forte.apply_operator(op, ref)
    assert det("2200") not in wfn
    assert wfn[det("+2-0")] == pytest.approx(-0.3, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.3, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(0.15, abs=1e-9)
    assert wfn[det("2002")] == pytest.approx(-0.21, abs=1e-9)

    ### Test the exponential operator with excitation operator ###
    op = forte.SparseOperator()
    ref = forte.StateVector({det("22"): 1.0})
    op.add_term_from_str('[2a+ 0a-]', 0.1)
    op.add_term_from_str('[2b+ 0b-]', 0.1)
    op.add_term_from_str('[2a+ 2b+ 0b- 0a-]', 0.15)
    op.add_term_from_str('[3a+ 3b+ 1b- 1a-]', -0.077)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref)
    assert wfn[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(0.16, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("2002")] == pytest.approx(-0.077, abs=1e-9)
    assert wfn[det("+0-2")] == pytest.approx(-0.0077, abs=1e-9)
    assert wfn[det("-0+2")] == pytest.approx(-0.0077, abs=1e-9)

    wfn = exp.compute(op, ref, algorithm='onthefly')
    assert wfn[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(0.16, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("2002")] == pytest.approx(-0.077, abs=1e-9)
    assert wfn[det("+0-2")] == pytest.approx(-0.0077, abs=1e-9)
    assert wfn[det("-0+2")] == pytest.approx(-0.0077, abs=1e-9)

    wfn = exp.compute(op, ref, algorithm='ontheflystd')
    assert wfn[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(0.16, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.1, abs=1e-9)
    assert wfn[det("2002")] == pytest.approx(-0.077, abs=1e-9)
    assert wfn[det("+0-2")] == pytest.approx(-0.0077, abs=1e-9)
    assert wfn[det("-0+2")] == pytest.approx(-0.0077, abs=1e-9)

    ### Test the exponential operator with antihermitian operator ###
    op = forte.SparseOperator(antihermitian=True)
    ref = forte.StateVector({det("22"): 1.0})
    op.add_term_from_str('[2a+ 0a-]', 0.1)
    op.add_term_from_str('[2b+ 0b-]', 0.1)
    op.add_term_from_str('[2a+ 2b+ 0b- 0a-]', 0.15)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref)
    assert wfn[det("-2+0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(+0.158390400605, abs=1e-9)
    assert wfn[det("2200")] == pytest.approx(+0.978860446763, abs=1e-9)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref, algorithm='onthefly')
    assert wfn[det("-2+0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(+0.158390400605, abs=1e-9)
    assert wfn[det("2200")] == pytest.approx(+0.978860446763, abs=1e-9)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref, algorithm='ontheflystd')
    assert wfn[det("-2+0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("+2-0")] == pytest.approx(-0.091500564912, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(+0.158390400605, abs=1e-9)
    assert wfn[det("2200")] == pytest.approx(+0.978860446763, abs=1e-9)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref)
    wfn2 = exp.compute(op, wfn, scaling_factor=-1.0)
    assert wfn2[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn2[det("0220")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("+2-0")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("-2+0")] == pytest.approx(0.0, abs=1e-9)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref, algorithm='onthefly')
    wfn2 = exp.compute(op, wfn, scaling_factor=-1.0, algorithm='onthefly')
    assert wfn2[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn2[det("0220")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("+2-0")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("-2+0")] == pytest.approx(0.0, abs=1e-9)

    exp = forte.SparseExp()
    wfn = exp.compute(op, ref, algorithm='ontheflystd')
    wfn2 = exp.compute(op, wfn, scaling_factor=-1.0, algorithm='ontheflystd')
    assert wfn2[det("2200")] == pytest.approx(1.0, abs=1e-9)
    assert wfn2[det("0220")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("+2-0")] == pytest.approx(0.0, abs=1e-9)
    assert wfn2[det("-2+0")] == pytest.approx(0.0, abs=1e-9)

    ### Test the factorized exponential operator ###
    op = forte.SparseOperator(antihermitian=True)
    op.add_term_from_str('[2a+ 0a-]', 0.1)
    op.add_term_from_str('[2b+ 0b-]', 0.2)
    op.add_term_from_str('[2a+ 2b+ 0b- 0a-]', 0.15)
    ref = forte.StateVector({det("22"): 1.0})

    factexp = forte.SparseFactExp()
    wfn = factexp.compute(op, ref)

    assert wfn[det("+2-0")] == pytest.approx(-0.197676811654, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.097843395007, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(+0.165338757995, abs=1e-9)
    assert wfn[det("2200")] == pytest.approx(+0.961256283877, abs=1e-9)

    wfn2 = factexp.compute(op, wfn, inverse=True)

    assert wfn2[det("2200")] == pytest.approx(1.0, abs=1e-9)

    factexp = forte.SparseFactExp()
    wfn = factexp.compute(op, ref, algorithm='onthefly')

    assert wfn[det("+2-0")] == pytest.approx(-0.197676811654, abs=1e-9)
    assert wfn[det("-2+0")] == pytest.approx(-0.097843395007, abs=1e-9)
    assert wfn[det("0220")] == pytest.approx(+0.165338757995, abs=1e-9)
    assert wfn[det("2200")] == pytest.approx(+0.961256283877, abs=1e-9)

    wfn2 = factexp.compute(op, wfn, inverse=True, algorithm='onthefly')

    assert wfn2[det("2200")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator(antihermitian=True)
    op.add_term_from_str('[1a+ 0a-]', 0.1)
    op.add_term_from_str('[1a+ 1b+ 0b- 0a-]', -0.3)
    op.add_term_from_str('[1b+ 0b-]', 0.05)
    op.add_term_from_str('[2a+ 2b+ 1b- 1a-]', -0.07)

    dtest = det("20")
    ref = forte.StateVector({det("20"): 0.5, det("02"): 0.8660254038})
    factexp = forte.SparseFactExp()
    wfn = factexp.compute(op, ref)

    assert wfn[det("200")] == pytest.approx(0.733340213919, abs=1e-9)
    assert wfn[det("+-0")] == pytest.approx(-0.049868863373, abs=1e-9)
    assert wfn[det("002")] == pytest.approx(-0.047410073759, abs=1e-9)
    assert wfn[det("020")] == pytest.approx(0.676180171388, abs=1e-9)
    assert wfn[det("-+0")] == pytest.approx(0.016058887563, abs=1e-9)

    wfn = factexp.compute(op, ref, algorithm='onthefly')

    assert wfn[det("200")] == pytest.approx(0.733340213919, abs=1e-9)
    assert wfn[det("+-0")] == pytest.approx(-0.049868863373, abs=1e-9)
    assert wfn[det("002")] == pytest.approx(-0.047410073759, abs=1e-9)
    assert wfn[det("020")] == pytest.approx(0.676180171388, abs=1e-9)
    assert wfn[det("-+0")] == pytest.approx(0.016058887563, abs=1e-9)
Exemplo n.º 6
0
def test_sparse_ci3():
    import forte
    import pytest
    from forte import det

    ### Operator ordering tests ###
    # test ordering: 0a+ 0b+ 0b- 0a- |2> = +|2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0b+ 0b- 0a-]', 1.0)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test ordering: 0a+ 0b+ 0a- 0b- |2> = -|2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0b+ 0a- 0b-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(-1.0, abs=1e-9)

    # test ordering: 0b+ 0a+ 0b- 0a- |2> = -|2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0a+ 0b- 0a-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(-1.0, abs=1e-9)

    # test ordering: 0b+ 0a+ 0a- 0b- |2> = +|2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0a+ 0a- 0b-]', 1.0, allow_reordering=True)
    dtest = det("20")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test ordering: 3a+ 4a+ 2b+ 1b- 0a- |22000> = + 3a+ 4a+ 2b+ 1b- |-2000>
    # 3a+ 4a+ 2b+ 1b- 0a- |22000> = + 3a+ 4a+ 2b+ 1b- |-2000>
    #                             = + 3a+ 4a+ 2b+ |-+000>
    #                             = + 3a+ 4a+ |-+-00>
    #                             = - 3a+ |-+-0+>
    #                             = + 3a+ |-+-++>
    op = forte.SparseOperator()
    op.add_term_from_str('[3a+ 4a+ 2b+ 1b- 0a-]', 1.0)
    ref = forte.StateVector({det("22"): 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[det("-+-++")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a+]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 1a+]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("++")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 1a+ 2a+]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 1a+ 2a+ 3a+]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("++++")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 1a+ 2a+ 3a+ 4a+]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++++")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[2a+ 0a+ 3a+ 1a+ 4a+]', 1.0, allow_reordering=True)
    wfn = forte.apply_operator(op, forte.StateVector({det(""): 1.0}))
    assert wfn[det("+++++")] == pytest.approx(-1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[0a-]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-2222")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[1a- 0a-]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("--222")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("---22")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[3a- 2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("----2")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[4a- 3a- 2a- 1a- 0a-]', 1.0)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-----")] == pytest.approx(1.0, abs=1e-9)

    op = forte.SparseOperator()
    op.add_term_from_str('[1a- 3a- 2a- 4a- 0a-]', 1.0, allow_reordering=True)
    wfn = forte.apply_operator(op, forte.StateVector({det("22222"): 1.0}))
    assert wfn[det("-----")] == pytest.approx(-1.0, abs=1e-9)

    ### Test for cases that are supposed to return zero ###
    # test destroying empty orbitals: (0a+ 0b+ 0b- 0a-) |0> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0b+ 0b- 0a-]', 1.0)
    dtest = det("00")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test destroying empty orbitals: (0a+ 0b+ 0b- 0a-) |0> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0b+ 0b-]', 1.0)
    dtest = det("00")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test creating in filled orbitals: (0a+ 1a+ 0a-) |22> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[1a+ 0a+ 0a-]', 1.0, allow_reordering=True)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test creating in filled orbitals: (0a+ 1a+ 0a-) |22> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[1b+ 0a+ 0a-]', 1.0, allow_reordering=True)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    ### Number operator tests ###
    # test number operator: (0a+ 0a-) |0> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("0")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test number operator: (0a+ 0a-) |+> = |+>
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0a+ 0a-) |-> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("-")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test number operator: (0a+ 0a-) |2> = |2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0a+ 0a-]', 1.0)
    dtest = det("2")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0b+ 0b-) |0> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("0")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test number operator: (0b+ 0b-) |+> = 0
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("+")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert dtest not in wfn

    # test number operator: (0b+ 0b-) |-> = |->
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0b-]', 1.0)
    dtest = det("-")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[dtest] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (0b+ 0b-) |2> = |2>
    op = forte.SparseOperator()
    op.add_term_from_str('[0b+ 0b-]', 1.0)
    ref = forte.StateVector({det("2"): 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[det("2")] == pytest.approx(1.0, abs=1e-9)

    # make sure that the  number operator throws an exception: (2a+ 2a- + 2b+ 2b-) |222> = |222>
    op = forte.SparseOperator()
    with pytest.raises(RuntimeError):
        op.add_term_from_str('[2a+ 2a-] + [2b+ 2b-]', 1.0)

    ### Excitation operator tests ###
    # test excitation operator: (3a+ 0a-) |2200> = 3a+ |-200> = -|-20+>
    op = forte.SparseOperator()
    op.add_term_from_str('[3a+ 0a-]', 1.0)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[det("-20+")] == pytest.approx(-1.0, abs=1e-9)

    # test excitation operator: (0a- 3a+) |22> = 0a- |220+> = |-20+>
    op = forte.SparseOperator()
    op.add_term_from_str('[0a- 3a+]', 1.0, allow_reordering=True)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[det("-20+")] == pytest.approx(1.0, abs=1e-9)

    # test number operator: (3b+ 0b-) |2200> = 3b+ |+200> = |+20->
    op = forte.SparseOperator()
    op.add_term_from_str('[3b+ 0b-]', 1.0)
    dtest = det("22")
    ref = forte.StateVector({dtest: 1.0})
    wfn = forte.apply_operator(op, ref)
    assert wfn[det("+20-")] == pytest.approx(-1.0, abs=1e-9)