示例#1
0
def test_multiset_permutation_5():
    # n_multiset_permutation for spin-adapted operators is always one
    a = SecondQuantizedOperator("g0,v1,p2", "p0,a1,c2", 'spin-adapted')
    p_cre = [[Index('g0'), Index('v1'), Index('p2')]]
    p_ann = [[Index('p0')], [Index('a1')], [Index('c2')]]
    assert not a.exist_permute_format(p_cre, p_ann)
    assert a.n_multiset_permutation(p_cre, p_ann) == 1
示例#2
0
def test_possible_excitation():
    assert SecondQuantizedOperator("g0, g1", "g2, p0").is_possible_excitation()
    assert SecondQuantizedOperator("p0, p1", "c0, h0").is_possible_excitation()
    assert not SecondQuantizedOperator("c0, h0",
                                       "p0, p1").is_possible_excitation()
    assert not SecondQuantizedOperator("a0, A0", "a1, A1",
                                       'si').is_possible_excitation()
def process_composite_contractions(contraction, elementary_contractions,
                                   n_indices, expand_hole, base_order_map,
                                   upper_indices_set, lower_indices_set):
    """
    Process a single composite contraction expressed in terms of indices of elementary contractions.
    :param contraction: a composite contraction
    :param elementary_contractions: a list of density cumulants / hole densities
    :param n_indices: the total number of indices
    :param expand_hole: expand hole densities to Kronecker delta minus one density if True
    :param base_order_map: the index map to ordering index, e.g., {"ug0": 0, "lg0": 1, ...}, u/l for upper/lower
    :param upper_indices_set: the set of all creation operators
    :param lower_indices_set: the set of all annihilation operators
    :return: a list of contractions in terms of (sign, list_of_densities, sq_op)
    """
    list_of_densities = []
    current_order = []

    n_open = 0
    for con in contraction:
        ele_con = elementary_contractions[con]
        list_of_densities.append(ele_con)
        n_open += ele_con.n_upper

        if isinstance(ele_con, HoleDensity):
            current_order += [
                f"l{ele_con.lower_indices[0].name}",
                f"u{ele_con.upper_indices[0].name}"
            ]
        else:
            current_order += [f"u{i.name}" for i in ele_con.upper_indices]
            current_order += [
                f"l{i.name}" for i in ele_con.lower_indices[::-1]
            ]
    n_open = n_indices - 2 * n_open

    # sort the open indices
    if n_open != 0:
        contracted = set(current_order)
        open_upper_indices = IndicesSpinOrbital(
            sorted(Index(i[1:]) for i in upper_indices_set - contracted))
        open_lower_indices = IndicesSpinOrbital(
            sorted(Index(i[1:]) for i in lower_indices_set - contracted))
        current_order += [f"u{i.name}" for i in open_upper_indices]
        current_order += [f"l{i.name}" for i in open_lower_indices[::-1]]

        sq_op = SecondQuantizedOperator(open_upper_indices, open_lower_indices)
    else:
        sq_op = SecondQuantizedOperator.make_empty()

    # expand hole densities to delta - lambda_1
    sign_densities_pairs = expand_hole_densities(
        list_of_densities) if expand_hole else [(1, list_of_densities)]

    # determine sign
    sign = (-1)**Permutation([base_order_map[i]
                              for i in current_order]).inversions()

    return [(sign * _s, list_of_densities, sq_op)
            for _s, list_of_densities in sign_densities_pairs]
示例#4
0
def test_latex_permute_format_2():
    a = SecondQuantizedOperator("g0,v1,p3", "p0,a1,p2", 'spin-integrated')
    p_cre = [[Index('g0')], [Index('p3')], [Index('v1')]]
    p_ann = [[Index('p0'), Index('p2')], [Index('a1')]]
    n_perm, perm, latex_str = a.latex_permute_format(p_cre, p_ann)
    assert n_perm == 18
    assert perm == '{\\cal P} ( g_{0} / p_{3} / v_{1} ) {\\cal P} ( p_{0} p_{2} / a_{1} )'
    assert latex_str == 'a^{ g_{0} v_{1} p_{3} }_{ p_{0} a_{1} p_{2} }'
示例#5
0
def test_init():
    id_type = 'spin-orbital'
    assert SecondQuantizedOperator([], []).is_empty()
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", id_type)
    assert a.cre_ops == Indices.make_indices("g0,g1,g2", id_type)
    assert a.ann_ops == Indices.make_indices("p0,p1,p2", id_type)
    assert a.n_ann == 3
    assert a.n_cre == 3
示例#6
0
def test_latex_permute_format_1():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'spin-orbital')
    p_cre = [[Index(i) for i in "g0,g1,g2".split(',')]]
    p_ann = [[Index(i) for i in "p0,p1,p2".split(',')]]
    n_perm, perm, latex_str = a.latex_permute_format(p_cre, p_ann)
    assert n_perm == 1
    assert perm == ''
    assert latex_str == 'a^{ g_{0} g_{1} g_{2} }_{ p_{0} p_{1} p_{2} }'
示例#7
0
def test_multiset_permutation_2():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'spin-integrated')
    p_cre = [[Index(i) for i in "g0,g1,g2".split(',')]]
    p_ann = [[Index('p0')], [Index('p1')], [Index('p2')]]
    assert a.exist_permute_format(p_cre, p_ann)
    assert a.n_multiset_permutation(p_cre, p_ann) == 6

    p_ann = [[Index('p0'), Index('p1')], [Index('p2')]]
    assert a.n_multiset_permutation(p_cre, p_ann) == 3
示例#8
0
def test_ambit_permute_format_2():
    a = SecondQuantizedOperator("g0,g1,c2", "p0,p1,p2", 'spin-integrated')
    p_cre = [[Index('g0'), Index('g1')], [Index('c2')]]
    p_ann = [[Index('p0'), Index('p1'), Index('p2')]]
    ref = {(1, '["p0,p1,p2,g0,g1,c2"]'), (-1, '["p0,p1,p2,g0,c2,g1"]'),
           (1, '["p0,p1,p2,c2,g0,g1"]')}
    for pair in a.ambit_permute_format(p_cre, p_ann, cre_first=False):
        assert pair in ref
        ref.remove(pair)
    assert len(ref) == 0
示例#9
0
def test_latex_permute_format_3():
    # TODO: is this necessary?
    # ignore multiset permutations for mixed spin indices
    a = SecondQuantizedOperator("g0,v1,p2", "p0,a1,P2", 'spin-integrated')
    p_cre = [[Index('g0')], [Index('p2')], [Index('v1')]]
    p_ann = [[Index('p0'), Index('P2')], [Index('a1')]]
    n_perm, perm, latex_str = a.latex_permute_format(p_cre, p_ann)
    assert n_perm == 6
    assert perm == '{\\cal P} ( g_{0} / p_{2} / v_{1} )'
    assert latex_str == 'a^{ g_{0} v_{1} p_{2} }_{ p_{0} a_{1} P_{2} }'
示例#10
0
def test_eq():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'spin-orbital')
    b = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'so')
    assert a is not b
    assert a == b

    with pytest.raises(TypeError):
        assert a == IndicesPair("g0,g1,g2", "p0,p1,p2", 'spin-orbital')
    with pytest.raises(TypeError):
        assert a == SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2",
                                            'spin-integrated')
示例#11
0
def test_simplify():
    list_of_tensors = [
        make_tensor('H', "g0", "g0"),
        make_tensor('t', "h0", "p0"),
        make_tensor('t', "p1", "h1"),
        make_tensor('L', 'h0', 'g0'),
        make_tensor('L', 'g0, p1', 'p0, h1')
    ]
    a = Term(list_of_tensors, SecondQuantizedOperator.make_empty(), -1)
    a.simplify()
    assert a.is_void()

    list_of_tensors = [
        make_tensor('H', "g0", "g0"),
        make_tensor('t', "h0", "p0"),
        make_tensor('t', "p1", "h1"),
        make_tensor('L', 'g0', 'h1'),
        make_tensor('L', 'h0', 'g0'),
        make_tensor('K', 'p0', 'p1')
    ]
    a = Term(list_of_tensors, SecondQuantizedOperator.make_empty())
    a.simplify()
    assert a.list_of_tensors == [
        make_tensor('H', 'h6', 'h6'),
        make_tensor('t', 'p1', 'h3'),
        make_tensor('t', 'h4', 'p1'),
        make_tensor('L', 'h6', 'h3'),
        make_tensor('L', 'h4', 'h6')
    ]
    assert a.sq_op == SecondQuantizedOperator.make_empty()
    assert a.indices_set == {Index(i) for i in ['h6', 'p1', 'h3', 'h4']}
    assert a.diagonal_indices == {Index('h6'): 4}

    list_of_tensors = [
        make_tensor('H', "g0", "g0"),
        make_tensor('t', "h0", "p0"),
        make_tensor('t', "p1", "c1"),
        make_tensor('L', 'g0', 'c1'),
        make_tensor('K', 'p0', 'p1')
    ]
    a = Term(list_of_tensors, SecondQuantizedOperator('h0', 'g0'))
    a.simplify()
    assert a.list_of_tensors == [
        make_tensor('H', "c2", "c2"),
        make_tensor('t', "p1", "c2"),
        make_tensor('t', "h0", "p1")
    ]
    assert a.sq_op == SecondQuantizedOperator('h0', 'c2')
    assert a.indices_set == {Index(i) for i in ['c2', 'p1', 'h0']}
    assert a.diagonal_indices == {Index('c2'): 4}
示例#12
0
def test_canonicalize_2():
    # H^{ v_{0} }_{ v_{1} } T^{ v_{1} }_{ c_{1} } T^{ v_{2} }_{ c_{0} } T^{ c_{0} c_{1} }_{ v_{0} v_{2} }
    indices_type = 'so'
    list_of_tensors = [
        make_tensor('Hamiltonian', "v0", "v1", indices_type),
        make_tensor('cluster_amplitude', "v1", "c1", indices_type),
        make_tensor('cluster_amplitude', "v2", "c0", indices_type),
        make_tensor('cluster_amplitude', "c0,c1", "v0,v2", indices_type)
    ]
    sq_op = SecondQuantizedOperator.make_empty(indices_type)
    a = Term(list_of_tensors, sq_op)

    # H^{ v_{0} }_{ v_{1} } T^{ c_{0} }_{ v_{2} } T^{ c_{1} }_{ v_{0} } T^{ v_{1} v_{2} }_{ c_{0} c_{1} }
    list_of_tensors = [
        make_tensor('Hamiltonian', "v0", "v1", indices_type),
        make_tensor('cluster_amplitude', "c0", "v2", indices_type),
        make_tensor('cluster_amplitude', "c1", "v0", indices_type),
        make_tensor('cluster_amplitude', "v1,v2", "c0,c1", indices_type)
    ]
    b = Term(list_of_tensors, sq_op)

    ref = Term([
        make_tensor('Hamiltonian', "v1", "v0", indices_type),
        make_tensor('cluster_amplitude', "c0", "v0", indices_type),
        make_tensor('cluster_amplitude', "c1", "v2", indices_type),
        make_tensor('cluster_amplitude', "c0,c1", "v1,v2", indices_type)
    ], sq_op, -1)
    assert ref == a.canonicalize() == b.canonicalize()
示例#13
0
def test_canonicalize_4():
    list_of_tensors = [
        make_tensor('Hamiltonian', "g0,g1,c0", "g2,p0,v0"),
        make_tensor('cluster_amplitude', "p0,p1,g3", "a0,h1,a1"),
        make_tensor('Kronecker', "v0", "p1"),
        make_tensor('cumulant', "h1", "c0"),
        make_tensor('cumulant', "a1", "g3"),
        make_tensor('cumulant', "g2,a0", "g0,g1")
    ]
    a = Term(list_of_tensors, SecondQuantizedOperator.make_empty())

    ref = Term([
        make_tensor('H', "c0,a1,a2", "p0,v0,a0"),
        make_tensor('t', "c0,a4,a5", "p0,v0,a3"),
        make_tensor('L', "a4", "a3"),
        make_tensor('L', "a1,a2", "a0,a5")
    ], SecondQuantizedOperator.make_empty())
    assert a.canonicalize() == ref
示例#14
0
def test_canonicalize_1():
    list_of_tensors = [
        make_tensor('H', "g0", "g0"),
        make_tensor('t', "h0", "p0"),
        make_tensor('t', "p1", "c1"),
        make_tensor('L', 'g0', 'c1'),
        make_tensor('K', 'p0', 'p1')
    ]
    a = Term(list_of_tensors, SecondQuantizedOperator('h0', 'g0'))
    with pytest.raises(NotImplementedError):
        assert a.canonicalize()
示例#15
0
def test_latex_1():
    list_of_tensors = [
        make_tensor('H', 'v0, v1', 'c0, c1'),
        make_tensor('t', 'c0, c1', 'v0, v1')
    ]
    sq_op = SecondQuantizedOperator.make_empty()
    a = Term(list_of_tensors, sq_op, 0.25)
    assert a.latex(
    ) == "1/4 H^{ v_{0} v_{1} }_{ c_{0} c_{1} } T^{ c_{0} c_{1} }_{ v_{0} v_{1} }"
    assert a.latex(
        dollar=True
    ) == "$1/4 H^{ v_{0} v_{1} }_{ c_{0} c_{1} } T^{ c_{0} c_{1} }_{ v_{0} v_{1} }$"
示例#16
0
def test_ambit_1():
    list_of_tensors = [
        make_tensor('H', 'v0, v1', 'c0, c1'),
        make_tensor('t', 'c0, c1', 'v0, v1')
    ]
    sq_op = SecondQuantizedOperator.make_empty()
    a = Term(list_of_tensors, sq_op, 0.25)
    assert a.ambit(
        name='X'
    ) == 'X0 += (1.0 / 4.0) * H2["v0,v1,c0,c1"] * T2["c0,c1,v0,v1"];'

    list_of_tensors = [
        make_tensor('H', 'v0, v1', 'g0, c1'),
        make_tensor('t', 'c0, c1', 'v0, v1')
    ]
    sq_op = make_sq('g0', 'c0')
    a = Term(list_of_tensors, sq_op, 0.5)
    assert a.ambit(
    ) == 'C1["c0,g0"] += (1.0 / 2.0) * H2["v0,v1,g0,c1"] * T2["c0,c1,v0,v1"];'
示例#17
0
def process_composite_categorized(com_cat, ele_con, compatible,
                                  upper_indices_set, lower_indices_set,
                                  base_order_map, n_indices, expand_hole):
    """
    Process one composite categorized contraction.
    :param com_cat: a list of connected operator indices
    :param ele_con: an ElementaryContractionCategorized object
    :param compatible: compatible elementary contractions
    :param upper_indices_set: the set of all creation operators
    :param lower_indices_set: the set of all annihilation operators
    :param base_order_map: the Index map to ordering index
    :param n_indices: the total number of cre and ann operators
    :param expand_hole: expand hole densities to Kronecker delta minus one density if True
    :return: a list of contractions in terms of (sign, list_of_densities, sq_op)
    """
    n_open = n_indices - sum(len(i) for i in com_cat)
    out = []

    for coded_cons in ele_con.composite_contractions(Counter(com_cat),
                                                     compatible):
        contractions = [ele_con.decode(i) for i in coded_cons]

        # cre/ann ordering of the current composite contraction
        current_order = []
        for con in contractions:
            if isinstance(con, HoleDensity):
                current_order += [
                    f"l{con.lower_indices[0].name}",
                    f"u{con.upper_indices[0].name}"
                ]
            else:
                current_order += [f"u{i.name}" for i in con.upper_indices]
                current_order += [
                    f"l{i.name}" for i in con.lower_indices[::-1]
                ]

        # sort open indices
        if n_open != 0:
            contracted = set(current_order)
            open_upper = IndicesSpinOrbital(
                sorted(Index(i[1:]) for i in upper_indices_set - contracted))
            open_lower = IndicesSpinOrbital(
                sorted(Index(i[1:]) for i in lower_indices_set - contracted))
            current_order += [f"u{i.name}" for i in open_upper]
            current_order += [f"l{i.name}" for i in open_lower[::-1]]

            sq_op = SecondQuantizedOperator(open_upper, open_lower)
        else:
            sq_op = SecondQuantizedOperator.make_empty()

        # determine sign of current ordering
        sign = (-1)**Permutation([base_order_map[i]
                                  for i in current_order]).inversions()

        # expand hole density to delta - 1-cumulant
        sign_densities = expand_hole_densities(
            contractions) if expand_hole else [(1, contractions)]

        # append results
        out += [(sign * _s, cons, sq_op) for _s, cons in sign_densities]

    return out
示例#18
0
def test_multiset_permutation_4():
    a = SecondQuantizedOperator("g0,v1,p2", "p0,a1,c2", 'spin-orbital')
    p_cre = [[Index('g0'), Index('v1'), Index('p2')]]
    p_ann = [[Index('p0'), Index('a1'), Index('c2')]]
    assert not a.exist_permute_format(p_cre, p_ann)
    assert a.n_multiset_permutation(p_cre, p_ann) == 1
示例#19
0
def test_multiset_permutation_3():
    a = SecondQuantizedOperator("g0,v1,p2", "p0,a1,p2", 'spin-integrated')
    p_cre = [[Index('g0')], [Index('v1')], [Index('p2')]]
    p_ann = [[Index('p0'), Index('p2')], [Index('a1')]]
    assert a.exist_permute_format(p_cre, p_ann)
    assert a.n_multiset_permutation(p_cre, p_ann) == 18
示例#20
0
def test_ambit_permute_format_3():
    # TODO: is this necessary?
    # ignore all input partitions for mixed spin indices
    a = SecondQuantizedOperator("g0,G1,c2", "p0,p1,P2", 'spin-integrated')
    for pair in a.ambit_permute_format([], [], cre_first=True):
        assert pair == (1, '["g0,G1,c2,p0,p1,P2"]')
示例#21
0
def test_canonicalize():
    a = SecondQuantizedOperator("G2, p0, p1", "g0, A0, h2, A2", 'si')
    c, sign = a.canonicalize()
    assert c == SecondQuantizedOperator("p0, p1, G2", "g0, h2, A0, A2", 'si')
    assert sign == -1
示例#22
0
def test_base_strong_generating_set():
    with pytest.raises(ValueError):
        SecondQuantizedOperator("", "", 'si').base_strong_generating_set()
示例#23
0
def test_is_spin_conserving():
    assert SecondQuantizedOperator("p0", "p0", 'si').is_spin_conserving()
    assert not SecondQuantizedOperator("p0", "H0", 'si').is_spin_conserving()
    with pytest.raises(ValueError):
        assert SecondQuantizedOperator("p0", "p0, p1",
                                       'so').is_spin_conserving()
示例#24
0
def test_is_particle_conserving():
    assert SecondQuantizedOperator("G0,G1,g2", "p0,P1,P2",
                                   'spin-integrated').is_particle_conserving()
    assert SecondQuantizedOperator("p0", "p0", 'so').is_particle_conserving()
    assert not SecondQuantizedOperator("p0", "p0, p1",
                                       'so').is_particle_conserving()
示例#25
0
def test_ge():
    a = SecondQuantizedOperator("G0,G1,g2", "p0,P1,P2", 'spin-integrated')
    assert a >= SecondQuantizedOperator("g0,g1,g2", "p0,P1,p2,p3", 'si')
    with pytest.raises(TypeError):
        assert a >= 1
示例#26
0
def test_lt():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,P1,p2", 'spin-integrated')
    assert a < SecondQuantizedOperator("g0,g1,g2", "p0,P1,p2,p3", 'si')
    assert a < SecondQuantizedOperator("g0,g1,g2", "p0,P2,p2", 'si')
示例#27
0
def compute_operator_contractions_general(ops_list,
                                          max_cu=3,
                                          max_n_open=6,
                                          min_n_open=0,
                                          expand_hole=True,
                                          n_process=1,
                                          batch_size=1):
    """
    Generate operator contractions for a list of SQOperator (disconnected contractions are included).
    :param ops_list: a list of SecondQuantizedOperator to be contracted
    :param max_cu: max level of cumulant
    :param max_n_open: max number of open indices for contractions kept for return
    :param min_n_open: min number of open indices for contractions kept for return
    :param expand_hole: expand hole density to Kronecker delta and 1-cumulant if True
    :param n_process: the number of processes launched by multiprocessing
    :param batch_size: the chunk size for multiprocessing
    :return: a list of contractions in terms of (sign, list_of_densities, sq_op)
    """
    max_cu_allowed = check_max_cu(ops_list, max_cu)

    # original ordering of the second-quantized operators
    base_order_map, upper_indices_set, lower_indices_set = generate_base_order_map(
        ops_list)
    n_indices = len(base_order_map)

    # un-contracted term
    if min_n_open <= n_indices <= max_n_open:
        sq_op = SecondQuantizedOperator(
            sorted(Index(i[1:]) for i in upper_indices_set),
            sorted(Index(i[1:]) for i in lower_indices_set))
        current_order = [base_order_map[f"u{i.name}"] for i in sq_op.cre_ops]
        current_order += [
            base_order_map[f"l{i.name}"] for i in sq_op.ann_ops[::-1]
        ]
        sign = (-1)**Permutation(current_order).inversions()
        yield [(sign, [], sq_op)]

    # max/min numbers of contracted indices
    max_n_con, min_n_con = n_indices - min_n_open, n_indices - max_n_open

    elementary_contractions = compute_elementary_contractions_list(
        ops_list, max_cu_allowed)
    compatible = compute_compatible_elementary_contractions_list(
        elementary_contractions)

    n_ele_con = len(elementary_contractions)
    if n_ele_con > 1000:
        sys.setrecursionlimit(n_ele_con)

    if n_process == 1:
        for con in composite_contractions_backtrack(set(range(n_ele_con)),
                                                    set(), compatible, 0,
                                                    elementary_contractions,
                                                    (min_n_con, max_n_con)):
            yield process_composite_contractions(con, elementary_contractions,
                                                 n_indices, expand_hole,
                                                 base_order_map,
                                                 upper_indices_set,
                                                 lower_indices_set)
    else:
        composite = [
            list(i)
            for i in composite_contractions_backtrack(set(range(
                n_ele_con)), set(), compatible, 0, elementary_contractions, (
                    min_n_con, max_n_con))
        ]

        n_process = min(n_process, multiprocessing.cpu_count())
        if batch_size == 0:
            n_upper, n_lower = len(upper_indices_set), len(lower_indices_set)
            batch_size = estimate_batch_size(n_upper, n_lower, max_n_con,
                                             min_n_con, n_process)

        with multiprocessing.Pool(n_process, maxtasksperchild=1000) as pool:
            tasks = [(process_composite_contractions,
                      (con, elementary_contractions, n_indices, expand_hole,
                       base_order_map, upper_indices_set, lower_indices_set))
                     for con in composite]

            imap_unordered_it = pool.imap_unordered(calculate_star,
                                                    tasks,
                                                    chunksize=batch_size)
            for results in imap_unordered_it:
                yield results
示例#28
0
def test_multiset_permutation_1():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'spin-orbital')
    p_cre = [[Index(i) for i in "g0,g1,g2".split(',')]]
    p_ann = [[Index(i) for i in "p0,p1,p2".split(',')]]
    assert not a.exist_permute_format(p_cre, p_ann)
    assert a.n_multiset_permutation(p_cre, p_ann) == 1
示例#29
0
def test_ne():
    a = SecondQuantizedOperator("g0,g1,g2", "p0,p1,p2", 'so')
    assert a != SecondQuantizedOperator(["g0", "v1", "p2"], ["p0", "a1", "p2"])
示例#30
0
def test_void():
    a = SecondQuantizedOperator("G2, p0, p1", "g0, A0, h2", 'si')
    b = a.void()
    assert a.indices_type == b.indices_type
    assert b.size == 0
    assert b is not SecondQuantizedOperator.make_empty('si')