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()
def det(s): return forte.det(s)
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)
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
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)
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)