コード例 #1
0
def t1_tpdm_component(p, q, r, i, j, k):
    """
    Iterate through two-RDM mapping components of T1 map

    :param Int p: index for T1 term
    :param Int q: index for T1 term
    :param Int r: index for T1 term
    :param Int i: index for T1 term
    :param Int j: index for T1 term
    :param Int k: index for T1 term
    :return: Generator yielding DualbasisElements
    """
    terms = [
        DualElementStructGenerator(1.0, [(i, p)], 'cckk', (q, r, j, k)),
        DualElementStructGenerator(-1.0, [(i, q)], 'cckk', (p, r, j, k)),
        DualElementStructGenerator(1.0, [(i, r)], 'cckk', (p, q, j, k)),
        DualElementStructGenerator(-1.0, [(j, p)], 'cckk', (q, r, i, k)),
        DualElementStructGenerator(1.0, [(j, q)], 'cckk', (p, r, i, k)),
        DualElementStructGenerator(-1.0, [(j, r)], 'cckk', (p, q, i, k)),
        DualElementStructGenerator(1.0, [(k, p)], 'cckk', (q, r, i, j)),
        DualElementStructGenerator(-1.0, [(k, q)], 'cckk', (p, r, i, j)),
        DualElementStructGenerator(1.0, [(k, r)], 'cckk', (p, q, i, j))
    ]

    # create the generator that yeilds the next non-zero 2-RDM component
    for desg_term in terms:
        dbe = DualBasisElement()
        delta_val = 1.0
        for krond_pair in desg_term.deltas:
            delta_val *= kdelta(*krond_pair)
        if np.isclose(delta_val, 1.0):
            dbe.add_element(desg_term.tensor_name, desg_term.tensor_element,
                            desg_term.coeff)
            yield dbe
コード例 #2
0
def d2bb_d1b_mapping(dim, normalization):
    """
    Construct dual basis for contracting d2 -> d1

    :param dim: linear dimension of the 1-RDM
    :param normalization: normalization constant for coeff of D1 elememnts
    :return: the dual basis of the contraction
    :rtype: DualBasis
    """
    db_basis = DualBasis()
    dbe_list = []
    dim /= 2
    dim = int(dim)
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            for r in range(dim):
                # duplicate entries get summed in DualBasisElement
                dbe.add_element('cckk',
                                (2 * i + 1, 2 * r + 1, 2 * j + 1, 2 * r + 1),
                                0.5)
                dbe.add_element('cckk',
                                (2 * j + 1, 2 * r + 1, 2 * i + 1, 2 * r + 1),
                                0.5)

            # D1 terms
            dbe.add_element('ck', (2 * i + 1, 2 * j + 1), -0.5 * normalization)
            dbe.add_element('ck', (2 * j + 1, 2 * i + 1), -0.5 * normalization)
            dbe.simplify()
            db_basis += dbe
            # dbe_list.append(dbe)

    # return DualBasis(elements=dbe_list)  # db_basis
    return db_basis
コード例 #3
0
def d1_q1_mapping(dim):
    """
    Map the ck to kc

    D1 + Q1 = I

    :param dim: linear dimension of the 1-RDM
    :return: the dual basis of the mapping
    :rtype: DualBasis
    """
    db = DualBasis()
    dbe_list = []
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            if i != j:
                dbe.add_element('ck', (i, j), 0.5)
                dbe.add_element('ck', (j, i), 0.5)
                dbe.add_element('kc', (j, i), 0.5)
                dbe.add_element('kc', (i, j), 0.5)
                dbe.dual_scalar = 0.0
            else:
                dbe.add_element('ck', (i, j), 1.0)
                dbe.add_element('kc', (i, j), 1.0)
                dbe.dual_scalar = 1.0

            # db += dbe
            dbe_list.append(dbe)

    return DualBasis(elements=dbe_list)  # db
コード例 #4
0
def _trace_map(tname, dim, normalization):
    dbe = DualBasisElement()
    for i, j in product(range(dim), repeat=2):
        if i < j:
            dbe.add_element(tname, (i, j, i, j), 1.0)
    dbe.dual_scalar = normalization
    return dbe
コード例 #5
0
def trace_d2_bb(dim, Nb):
    dbe = DualBasisElement()
    for i, j in product(range(dim), repeat=2):
        if i < j:
            dbe.add_element('cckk_bb', (i, j, i, j), 2.0)
    dbe.dual_scalar = Nb * (Nb - 1)
    return dbe
コード例 #6
0
def antisymmetry_constraints(dim):
    """
    The dual basis elements representing the antisymmetry constraints

    :param dim: spinless Fermion basis rank
    :return: the dual basis of antisymmetry_constraints
    :rtype: DualBasis
    """
    # dual_basis = DualBasis()
    dbe_list = []
    for p, q, r, s in product(range(dim), repeat=4):
        if p * dim + q <= r * dim + s:
            if p < q and r < s:
                tensor_elements = [
                    tuple(indices) for indices in _coord_generator(p, q, r, s)
                ]
                tensor_names = ['cckk'] * len(tensor_elements)
                tensor_coeffs = [0.5] * len(tensor_elements)
                dbe = DualBasisElement()
                for n, e, c in zip(tensor_names, tensor_elements,
                                   tensor_coeffs):
                    dbe.add_element(n, e, c)

                # dual_basis += dbe
                dbe_list.append(dbe)

    return DualBasis(elements=dbe_list)
コード例 #7
0
def nb_constraint(dim, nb):
    """
    :param dim:
    :param sz:
    :return:
    """
    dbe = DualBasisElement()
    for i in range(dim // 2):
        dbe.add_element('ck', (2 * i + 1, 2 * i + 1), 1.0)
    dbe.dual_scalar = nb
    return DualBasis(elements=[dbe])
コード例 #8
0
def d2_to_t1_from_iterator(dim):
    """
    Generate T1 from the iteratively generated dbe elements

    :param dim:
    :return:
    """
    db = []
    # NOTE: Figure out why join_elements is not working
    for p, q, r, i, j, k in product(range(dim), repeat=6):
        if p != q and q != r and p != r and i != j and j != k and i != k:
            print(p, q, r, i, j, k)
            dbe = DualBasisElement()
            dbe.dual_scalar -= t1_dual_scalar(p, q, r, i, j, k)
            for element in t1_opdm_component(p, q, r, i, j, k):
                # dbe.join_elements(element)
                # print(element.primal_tensors_names, element.primal_elements, element.primal_coeffs)
                dbe.add_element(element.primal_tensors_names[0],
                                element.primal_elements[0],
                                element.primal_coeffs[0])
            for element in t1_tpdm_component(p, q, r, i, j, k):
                # dbe.join_elements(element)
                # print(element.primal_tensors_names, element.primal_elements, element.primal_coeffs)
                dbe.add_element(element.primal_tensors_names[0],
                                element.primal_elements[0],
                                element.primal_coeffs[0])
            dbe.add_element('t1', (p, q, r, i, j, k), -1.0)

            db.append(dbe)

    return DualBasis(elements=db)
コード例 #9
0
    def d2q2element_ab(p, q, r, s, factor, tname_d1_1, tname_d1_2, tname_d2,
                       tname_q2):
        if tname_d1_1 != 'ck_a':
            raise TypeError("For some reason I am expecting a ck_a. Ask Nick")

        dbe = DualBasisElement()
        dbe.add_element(tname_d1_1, (p, r), krond[q, s] * factor)
        dbe.add_element(tname_d1_2, (q, s), krond[p, r] * factor)
        dbe.add_element(tname_q2, (r, s, p, q), 1.0 * factor)
        dbe.add_element(tname_d2, (p, q, r, s), -1.0 * factor)
        dbe.dual_scalar = krond[q, s] * krond[p, r] * factor
        return dbe
コード例 #10
0
def s_representability_d2ab(dim, N, M, S):
    """
    Constraint for S-representability

    PHYSICAL REVIEW A 72, 052505 2005


    :param dim: number of spatial basis functions
    :param N: Total number of electrons
    :param M: Sz expected value
    :param S: S(S + 1) is eigenvalue of S^{2}
    :return:
    """
    dbe = DualBasisElement()
    for i, j in product(range(dim), repeat=2):
        dbe.add_element('cckk_ab', (i, j, j, i), 1.0)
    dbe.dual_scalar = N / 2.0 + M**2 - S * (S + 1)
    return dbe
コード例 #11
0
def _d1_q1_mapping(tname_d1, tname_q1, dim):
    db = DualBasis()
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            if i != j:
                dbe.add_element(tname_d1, (i, j), 0.5)
                dbe.add_element(tname_d1, (j, i), 0.5)
                dbe.add_element(tname_q1, (i, j), 0.5)
                dbe.add_element(tname_q1, (j, i), 0.5)
                dbe.dual_scalar = 0.0
            else:
                dbe.add_element(tname_d1, (i, j), 1.0)
                dbe.add_element(tname_q1, (i, j), 1.0)
                dbe.dual_scalar = 1.0

            db += dbe  # .simplify()

    return db
コード例 #12
0
def t1_opdm_component(p, q, r, i, j, k):
    """
    Iterate through one-RDM mapping components of T1 map

    :param Int p: Index for T1 matrix
    :param Int q: Index for T1 matrix
    :param Int r: Index for T1 matrix
    :param Int i: Index for T1 matrix
    :param Int j: Index for T1 matrix
    :param Int k: Index for T1 matrix
    :return: yield non-zero elements
    """
    terms = [
        DualElementStructGenerator(1.0, [(i, p), (j, q)], 'ck', (r, k)),
        DualElementStructGenerator(-1.0, [(i, p), (j, r)], 'ck', (q, k)),
        DualElementStructGenerator(-1.0, [(i, p), (k, q)], 'ck', (r, j)),
        DualElementStructGenerator(1.0, [(i, p), (k, r)], 'ck', (q, j)),
        DualElementStructGenerator(-1.0, [(i, q), (j, p)], 'ck', (r, k)),
        DualElementStructGenerator(1.0, [(i, q), (j, r)], 'ck', (p, k)),
        DualElementStructGenerator(1.0, [(i, q), (k, p)], 'ck', (r, j)),
        DualElementStructGenerator(-1.0, [(i, q), (k, r)], 'ck', (p, j)),
        DualElementStructGenerator(1.0, [(i, r), (j, p)], 'ck', (q, k)),
        DualElementStructGenerator(-1.0, [(i, r), (j, q)], 'ck', (p, k)),
        DualElementStructGenerator(-1.0, [(i, r), (k, p)], 'ck', (q, j)),
        DualElementStructGenerator(1.0, [(i, r), (k, q)], 'ck', (p, j)),
        DualElementStructGenerator(1.0, [(j, p), (k, q)], 'ck', (r, i)),
        DualElementStructGenerator(-1.0, [(j, p), (k, r)], 'ck', (q, i)),
        DualElementStructGenerator(-1.0, [(j, q), (k, p)], 'ck', (r, i)),
        DualElementStructGenerator(1.0, [(j, q), (k, r)], 'ck', (p, i)),
        DualElementStructGenerator(1.0, [(j, r), (k, p)], 'ck', (q, i)),
        DualElementStructGenerator(-1.0, [(j, r), (k, q)], 'ck', (p, i))
    ]
    # Create the generator that yeilds the next non-zero 1-RDM component
    for desg_term in terms:
        dbe = DualBasisElement()
        delta_val = 1.0
        for krond_pair in desg_term.deltas:
            delta_val *= kdelta(*krond_pair)
        if np.isclose(delta_val, 1.0):
            dbe.add_element(desg_term.tensor_name, desg_term.tensor_element,
                            desg_term.coeff)
            yield dbe
コード例 #13
0
def _contraction_base(tname_d2, tname_d1, dim, normalization, offset):
    db = DualBasis()
    for i in range(dim):
        for j in range(i + offset, dim):
            dbe = DualBasisElement()
            for r in range(dim):
                dbe.add_element(tname_d2, (i, r, j, r), 0.5)
                dbe.add_element(tname_d2, (j, r, i, r), 0.5)

            dbe.add_element(tname_d1, (i, j), -0.5 * normalization)
            dbe.add_element(tname_d1, (j, i), -0.5 * normalization)
            dbe.dual_scalar = 0

            dbe.simplify()
            db += dbe

    return db
コード例 #14
0
    def g2d2map_aabb(p, q, r, s, dim, key, factor=1.0):
        """
        Accept pqrs of G2 and map to D2
        """
        dbe = DualBasisElement()
        # this is ugly.  :(
        quad = {'aabb': [0, 1], 'bbaa': [1, 0]}
        dbe.add_element('ckck_aabb', (p * dim + q + quad[key][0] * dim**2,
                                      r * dim + s + quad[key][1] * dim**2),
                        1.0 * factor)
        dbe.add_element('ckck_aabb',
                        (r * dim + s + quad[key[::-1]][0] * dim**2,
                         p * dim + q + quad[key[::-1]][1] * dim**2),
                        1.0 * factor)

        dbe.add_element('cckk_ab', (p, s, q, r), -1.0 * factor)
        dbe.add_element('cckk_ab', (q, r, p, s), -1.0 * factor)
        dbe.dual_scalar = 0.0
        return dbe
コード例 #15
0
    def g2d2map_aa_or_bb(p, q, r, s, dim, key, factor=1.0):
        """
        Accept pqrs of G2 and map to D2
        """
        dbe = DualBasisElement()
        quad = {'aa': [0, 0], 'bb': [1, 1]}
        dbe.add_element('ckck_aabb', (p * dim + q + quad[key][0] * dim**2,
                                      r * dim + s + quad[key][1] * dim**2),
                        -1.0 * factor)
        dbe.add_element('ck_' + key[0], (p, r), krond[q, s] * factor)
        if p != s and r != q:
            gem1 = tuple(sorted([p, s]))
            gem2 = tuple(sorted([r, q]))
            parity = (-1)**(p < s) * (-1)**(r < q)
            dbe.add_element('cckk_' + key,
                            (gem1[0], gem1[1], gem2[0], gem2[1]),
                            parity * -0.5 * factor)

        dbe.dual_scalar = 0
        return dbe
コード例 #16
0
def sz_constraint(dim, sz):
    """
    Sz constraint is on the 1-RDM
    :param dim:
    :param sz:
    :return:
    """
    dbe = DualBasisElement()
    for i in range(dim // 2):
        dbe.add_element('ck', (2 * i, 2 * i), 0.5)
        dbe.add_element('ck', (2 * i + 1, 2 * i + 1), -0.5)
    dbe.dual_scalar = sz
    return DualBasis(elements=[dbe])
コード例 #17
0
    def d2q2element(p, q, r, s, factor):
        """
        Build the dual basis element for symmetric form of 2-marginal

        :param p: tensor index
        :param q: tensor index
        :param r: tensor index
        :param s: tensor index
        :param factor: scaling coeff for a symmetric constraint
        :return: the dual basis of the mapping
        """
        dbe = DualBasisElement()
        dbe.add_element('cckk', (p, q, r, s), -1.0 * factor)
        dbe.add_element('kkcc', (r, s, p, q), +1.0 * factor)
        dbe.add_element('ck', (p, r), krond[q, s] * factor)
        dbe.add_element('ck', (q, s), krond[p, r] * factor)
        dbe.add_element('ck', (p, s), -1. * krond[q, r] * factor)
        dbe.add_element('ck', (q, r), -1. * krond[p, s] * factor)
        dbe.dual_scalar = (krond[q, s] * krond[p, r] -
                           krond[q, r] * krond[p, s]) * factor

        return dbe
コード例 #18
0
def trace_constraint(dim, normalization):
    """
    Generate the trace constraint on the 2-RDM

    :param dim: spinless Fermion basis rank
    :return: the dual basis element
    :rtype: DualBasisElement
    """
    tensor_elements = [(i, j, i, j) for i, j in product(range(dim), repeat=2)]
    tensor_names = ['cckk'] * (dim**2)
    tensor_coeffs = [1.0] * (dim**2)
    bias = 0
    return DualBasisElement(tensor_names=tensor_names,
                            tensor_elements=tensor_elements,
                            tensor_coeffs=tensor_coeffs,
                            bias=bias,
                            scalar=normalization)
コード例 #19
0
def sz_representability(dim, M):
    """
    Constraint for S_z-representability

    Helgaker, Jorgensen, Olsen. Sz is one-body RDM constraint

    :param dim: number of spatial basis functions
    :param M: Sz expected value
    :return:
    """
    dbe = DualBasisElement()
    for i in range(dim):
        dbe.add_element('ck_a', (i, i), 0.5)
        dbe.add_element('ck_b', (i, i), -0.5)
    dbe.dual_scalar = M
    return dbe
コード例 #20
0
def d2ab_d1b_mapping(dim, Na):
    """
    Map the d2_spin-adapted 2-RDM to the D1 rdm

    :param Nb: number of beta electrons
    :param dim:
    :return:
    """
    db = DualBasis()
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            for r in range(dim):
                dbe.add_element('cckk_ab', (r, i, r, j), 0.5)
                dbe.add_element('cckk_ab', (r, j, r, i), 0.5)

            dbe.add_element('ck_b', (i, j), -0.5 * Na)
            dbe.add_element('ck_b', (j, i), -0.5 * Na)
            dbe.dual_scalar = 0

            dbe.simplify()
            db += dbe

    return db
コード例 #21
0
    def g2d2map(p, q, r, s, factor=1):
        """
        Build the dual basis element for a symmetric 2-marginal

        :param p: tensor index
        :param q: tensor index
        :param r: tensor index
        :param s: tensor index
        :param factor: weighting of the element
        :return: the dual basis element
        """
        dbe = DualBasisElement()
        dbe.add_element('ck', (p, r), -1. * krond[q, s] * factor)
        dbe.add_element('ckck', (p, s, r, q), 1.0 * factor)
        dbe.add_element('cckk', (p, q, r, s), 1.0 * factor)
        dbe.dual_scalar = 0

        return dbe
コード例 #22
0
def d2_e2_mapping(dim, bas_aa, bas_ab, measured_tpdm_aa, measured_tpdm_bb,
                  measured_tpdm_ab):
    """
    Generate constraints such that the error matrix and the d2 matrices look like the measured matrices

    :param dim: spatial basis dimension
    :param measured_tpdm_aa: two-marginal of alpha-alpha spins
    :param measured_tpdm_bb: two-marginal of beta-beta spins
    :param measured_tpdm_ab: two-marginal of alpha-beta spins
    :return:
    """
    db = DualBasis()
    # first constrain the aa-matrix
    aa_dim = dim * (dim - 1) / 2
    ab_dim = dim**2

    # map the aa matrix to the measured_tpdm_aa
    for p, q, r, s in product(range(dim), repeat=4):
        if p < q and r < s and bas_aa[(p, q)] <= bas_aa[(r, s)]:
            dbe = DualBasisElement()

            # two elements of D2aa
            dbe.add_element('cckk_aa', (p, q, r, s), 0.5)
            dbe.add_element('cckk_aa', (r, s, p, q), 0.5)

            # four elements of the E2aa
            dbe.add_element('cckk_me_aa',
                            (bas_aa[(p, q)] + aa_dim, bas_aa[(r, s)]), 0.25)
            dbe.add_element('cckk_me_aa',
                            (bas_aa[(r, s)] + aa_dim, bas_aa[(p, q)]), 0.25)
            dbe.add_element('cckk_me_aa',
                            (bas_aa[(p, q)], bas_aa[(r, s)] + aa_dim), 0.25)
            dbe.add_element('cckk_me_aa',
                            (bas_aa[(r, s)], bas_aa[(p, q)] + aa_dim), 0.25)

            dbe.dual_scalar = measured_tpdm_aa[bas_aa[(p, q)],
                                               bas_aa[(r, s)]].real
            dbe.simplify()

            # construct the dbe for constraining the [0, 0] orthant to the idenity matrix
            dbe_identity_aa = DualBasisElement()
            if bas_aa[(p, q)] == bas_aa[(r, s)]:
                dbe_identity_aa.add_element('cckk_me_aa',
                                            (bas_aa[(p, q)], bas_aa[(r, s)]),
                                            1.0)
                dbe_identity_aa.dual_scalar = 1.0
            else:
                dbe_identity_aa.add_element('cckk_me_aa',
                                            (bas_aa[(p, q)], bas_aa[(r, s)]),
                                            0.5)
                dbe_identity_aa.add_element('cckk_me_aa',
                                            (bas_aa[(r, s)], bas_aa[(p, q)]),
                                            0.5)
                dbe_identity_aa.dual_scalar = 0.0

            db += dbe
            db += dbe_identity_aa

    # map the bb matrix to the measured_tpdm_bb
    for p, q, r, s in product(range(dim), repeat=4):
        if p < q and r < s and bas_aa[(p, q)] <= bas_aa[(r, s)]:
            dbe = DualBasisElement()

            # two elements of D2bb
            dbe.add_element('cckk_bb', (p, q, r, s), 0.5)
            dbe.add_element('cckk_bb', (r, s, p, q), 0.5)

            # four elements of the E2bb
            dbe.add_element('cckk_me_bb',
                            (bas_aa[(p, q)] + aa_dim, bas_aa[(r, s)]), 0.25)
            dbe.add_element('cckk_me_bb',
                            (bas_aa[(r, s)] + aa_dim, bas_aa[(p, q)]), 0.25)
            dbe.add_element('cckk_me_bb',
                            (bas_aa[(p, q)], bas_aa[(r, s)] + aa_dim), 0.25)
            dbe.add_element('cckk_me_bb',
                            (bas_aa[(r, s)], bas_aa[(p, q)] + aa_dim), 0.25)

            dbe.dual_scalar = measured_tpdm_bb[bas_aa[(p, q)],
                                               bas_aa[(r, s)]].real
            dbe.simplify()

            # construct the dbe for constraining the [0, 0] orthant to the idenity matrix
            dbe_identity_bb = DualBasisElement()
            if bas_aa[(p, q)] == bas_aa[(r, s)]:
                dbe_identity_bb.add_element('cckk_me_bb',
                                            (bas_aa[(p, q)], bas_aa[(r, s)]),
                                            1.0)
                dbe_identity_bb.dual_scalar = 1.0
            else:
                dbe_identity_bb.add_element('cckk_me_bb',
                                            (bas_aa[(p, q)], bas_aa[(r, s)]),
                                            0.5)
                dbe_identity_bb.add_element('cckk_me_bb',
                                            (bas_aa[(r, s)], bas_aa[(p, q)]),
                                            0.5)
                dbe_identity_bb.dual_scalar = 0.0

            db += dbe
            db += dbe_identity_bb

    # map the ab matrix to the measured_tpdm_ab
    for p, q, r, s in product(range(dim), repeat=4):
        if bas_ab[(p, q)] <= bas_ab[(r, s)]:
            dbe = DualBasisElement()

            # two elements of D2ab
            dbe.add_element('cckk_ab', (p, q, r, s), 0.5)
            dbe.add_element('cckk_ab', (r, s, p, q), 0.5)

            # four elements of the E2ab
            dbe.add_element('cckk_me_ab',
                            (bas_ab[(p, q)] + ab_dim, bas_ab[(r, s)]), 0.25)
            dbe.add_element('cckk_me_ab',
                            (bas_ab[(r, s)] + ab_dim, bas_ab[(p, q)]), 0.25)
            dbe.add_element('cckk_me_ab',
                            (bas_ab[(p, q)], bas_ab[(r, s)] + ab_dim), 0.25)
            dbe.add_element('cckk_me_ab',
                            (bas_ab[(r, s)], bas_ab[(p, q)] + ab_dim), 0.25)

            dbe.dual_scalar = measured_tpdm_ab[bas_ab[(p, q)],
                                               bas_ab[(r, s)]].real
            dbe.simplify()

            # construct the dbe for constraining the [0, 0] orthant to the idenity matrix
            dbe_identity_ab = DualBasisElement()
            if bas_ab[(p, q)] == bas_ab[(r, s)]:
                dbe_identity_ab.add_element('cckk_me_ab',
                                            (bas_ab[(p, q)], bas_ab[(r, s)]),
                                            1.0)
                dbe_identity_ab.dual_scalar = 1.0
            else:
                dbe_identity_ab.add_element('cckk_me_ab',
                                            (bas_ab[(p, q)], bas_ab[(r, s)]),
                                            0.5)
                dbe_identity_ab.add_element('cckk_me_ab',
                                            (bas_ab[(r, s)], bas_ab[(p, q)]),
                                            0.5)
                dbe_identity_ab.dual_scalar = 0.0

            db += dbe
            db += dbe_identity_ab

    return db
コード例 #23
0
    def g2d2map_ab(p, q, r, s, key, factor=1.0):
        dbe = DualBasisElement()
        if key == 'ab':
            if q == s:
                dbe.add_element('ck_' + key[0], (p, r), krond[q, s] * factor)

            dbe.add_element('cckk_' + key, (p, s, r, q), -1.0 * factor)
        elif key == 'ba':
            if q == s:
                dbe.add_element('ck_' + key[0], (p, r), krond[q, s] * factor)

            dbe.add_element('cckk_ab', (s, p, q, r), -1.0 * factor)
        else:
            raise TypeError("I only accept ab or ba blocks")

        dbe.add_element('ckck_' + key, (p, q, r, s), -1.0 * factor)
        dbe.dual_scalar = 0.0
        return dbe
コード例 #24
0
    def d2q2element_ab(p, q, r, s, factor):
        dbe = DualBasisElement()
        if q == s:
            dbe.add_element('ck_a', (p, r), factor)
        if p == r:
            dbe.add_element('kc_b', (s, q), -factor)

        dbe.add_element('kkcc_ab', (r, s, p, q), factor)
        dbe.add_element('cckk_ab', (p, q, r, s), -factor)
        # dbe.dual_scalar = -krond[q, s]*krond[p, r] * factor
        dbe.dual_scalar = 0
        return dbe
コード例 #25
0
def d2bb_d1b_mapping(dim, Nb):
    """
    Map the d2_spin-adapted 2-RDM to the D1 rdm

    :param Nb: number of beta electrons
    :param dim:
    :return:
    """
    db = DualBasis()
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            for r in range(dim):
                # Not in the basis because always zero
                if i == r or j == r:
                    continue
                else:
                    sir = 1 if i < r else -1
                    sjr = 1 if j < r else -1
                    ir_pair = (i, r) if i < r else (r, i)
                    jr_pair = (j, r) if j < r else (r, j)
                    if i == j:
                        dbe.add_element(
                            'cckk_bb',
                            (ir_pair[0], ir_pair[1], jr_pair[0], jr_pair[1]),
                            sir * sjr)
                    else:
                        dbe.add_element(
                            'cckk_bb',
                            (ir_pair[0], ir_pair[1], jr_pair[0], jr_pair[1]),
                            sir * sjr * 0.5)
                        dbe.add_element(
                            'cckk_bb',
                            (jr_pair[0], jr_pair[1], ir_pair[0], ir_pair[1]),
                            sir * sjr * 0.5)

            dbe.add_element('ck_b', (i, j), -0.5 * (Nb - 1))
            dbe.add_element('ck_b', (j, i), -0.5 * (Nb - 1))
            dbe.dual_scalar = 0

            # dbe.simplify()
            db += dbe

    return db
コード例 #26
0
def s_representability_d2ab_to_d2aa(dim):
    """
    Constraint the antisymmetric part of the alpha-beta matrix to be equal
    to the aa and bb components if a singlet

    :param dim:
    :return:
    """
    sma = dim * (dim - 1) // 2
    sms = dim * (dim + 1) // 2
    uadapt, d2ab_abas, d2ab_abas_rev, d2ab_sbas, d2ab_sbas_rev = \
        gen_trans_2rdm(dim**2, dim)

    d2ab_bas = {}
    d2aa_bas = {}
    cnt_ab = 0
    cnt_aa = 0
    for p, q in product(range(dim), repeat=2):
        d2ab_bas[(p, q)] = cnt_ab
        cnt_ab += 1
        if p < q:
            d2aa_bas[(p, q)] = cnt_aa
            cnt_aa += 1
    d2ab_rev = dict(zip(d2ab_bas.values(), d2ab_bas.keys()))
    d2aa_rev = dict(zip(d2aa_bas.values(), d2aa_bas.keys()))

    assert uadapt.shape == (int(dim)**2, int(dim)**2)
    dbe_list = []
    for r, s in product(range(dim * (dim - 1) // 2), repeat=2):
        if r < s:
            dbe = DualBasisElement()
            # lower triangle
            i, j = d2aa_rev[r]
            k, l = d2aa_rev[s]
            # aa element should equal the triplet block aa
            dbe.add_element('cckk_aa', (i, j, k, l), -0.5)
            coeff_mat = uadapt[:, [r]] @ uadapt[:, [s]].T
            for p, q in product(range(coeff_mat.shape[0]), repeat=2):
                if not np.isclose(coeff_mat[p, q], 0):
                    ii, jj = d2ab_rev[p]
                    kk, ll = d2ab_rev[q]
                    dbe.add_element('cckk_ab', (ii, jj, kk, ll),
                                    0.5 * coeff_mat[p, q])

            # upper triangle .  Hermitian conjugate
            dbe.add_element('cckk_aa', (k, l, i, j), -0.5)
            coeff_mat = uadapt[:, [s]] @ uadapt[:, [r]].T
            for p, q in product(range(coeff_mat.shape[0]), repeat=2):
                if not np.isclose(coeff_mat[p, q], 0):
                    ii, jj = d2ab_rev[p]
                    kk, ll = d2ab_rev[q]
                    dbe.add_element('cckk_ab', (ii, jj, kk, ll),
                                    0.5 * coeff_mat[p, q])
            dbe.simplify()
            dbe_list.append(dbe)

        elif r == s:
            i, j = d2aa_rev[r]
            k, l = d2aa_rev[s]
            dbe = DualBasisElement()
            # aa element should equal the triplet block aa
            dbe.add_element('cckk_aa', (i, j, k, l), -1.0)
            coeff_mat = uadapt[:, [r]] @ uadapt[:, [s]].T
            for p, q in product(range(coeff_mat.shape[0]), repeat=2):
                if not np.isclose(coeff_mat[p, q], 0):
                    ii, jj = d2ab_rev[p]
                    kk, ll = d2ab_rev[q]
                    dbe.add_element('cckk_ab', (ii, jj, kk, ll), coeff_mat[p,
                                                                           q])
            dbe.simplify()
            dbe_list.append(dbe)

    return DualBasis(elements=dbe_list)
コード例 #27
0
def d2_to_t1(dim):
    """
    Generate the dual basis elements for mapping d2 and d1 to the T1-matrix

    The T1 condition is the sum of three-marginals

    T1 = <p^ q^ r^ i j k>  i j k p^ q^ r^>

    in such a fashion that any triples component cancels out. T1 will be
    represented over antisymmeterized basis functions to save a significant amount
    of space

    :param dim: spin-orbital basis dimension
    :return:
    """
    db = []  # DualBasis()
    for p, q, r, i, j, k in product(range(dim), repeat=6):
        # if (p * dim**2 + q * dim + r <= i * dim**2 + j * dim + k):
        print(p, q, r, i, j, k)
        dbe = DualBasisElement()
        dbe.dual_scalar -= (
            (-1.0) * kdelta(i, p) * kdelta(j, q) * kdelta(k, r) +
            (1.0) * kdelta(i, p) * kdelta(j, r) * kdelta(k, q) +
            (1.0) * kdelta(i, q) * kdelta(j, p) * kdelta(k, r) +
            (-1.0) * kdelta(i, q) * kdelta(j, r) * kdelta(k, p) +
            (-1.0) * kdelta(i, r) * kdelta(j, p) * kdelta(k, q) +
            (1.0) * kdelta(i, r) * kdelta(j, q) * kdelta(k, p))
        dbe.add_element('ck', (r, k), (1.0) * kdelta(i, p) * kdelta(j, q))
        dbe.add_element('ck', (q, k), (-1.0) * kdelta(i, p) * kdelta(j, r))
        dbe.add_element('ck', (r, j), (-1.0) * kdelta(i, p) * kdelta(k, q))
        dbe.add_element('ck', (q, j), (1.0) * kdelta(i, p) * kdelta(k, r))
        dbe.add_element('ck', (r, k), (-1.0) * kdelta(i, q) * kdelta(j, p))
        dbe.add_element('ck', (p, k), (1.0) * kdelta(i, q) * kdelta(j, r))
        dbe.add_element('ck', (r, j), (1.0) * kdelta(i, q) * kdelta(k, p))
        dbe.add_element('ck', (p, j), (-1.0) * kdelta(i, q) * kdelta(k, r))
        dbe.add_element('ck', (q, k), (1.0) * kdelta(i, r) * kdelta(j, p))
        dbe.add_element('ck', (p, k), (-1.0) * kdelta(i, r) * kdelta(j, q))
        dbe.add_element('ck', (q, j), (-1.0) * kdelta(i, r) * kdelta(k, p))
        dbe.add_element('ck', (p, j), (1.0) * kdelta(i, r) * kdelta(k, q))
        dbe.add_element('ck', (r, i), (1.0) * kdelta(j, p) * kdelta(k, q))
        dbe.add_element('ck', (q, i), (-1.0) * kdelta(j, p) * kdelta(k, r))
        dbe.add_element('ck', (r, i), (-1.0) * kdelta(j, q) * kdelta(k, p))
        dbe.add_element('ck', (p, i), (1.0) * kdelta(j, q) * kdelta(k, r))
        dbe.add_element('ck', (q, i), (1.0) * kdelta(j, r) * kdelta(k, p))
        dbe.add_element('ck', (p, i), (-1.0) * kdelta(j, r) * kdelta(k, q))
        dbe.add_element('cckk', (q, r, j, k), (1.0) * kdelta(i, p))
        dbe.add_element('cckk', (p, r, j, k), (-1.0) * kdelta(i, q))
        dbe.add_element('cckk', (p, q, j, k), (1.0) * kdelta(i, r))
        dbe.add_element('cckk', (q, r, i, k), (-1.0) * kdelta(j, p))
        dbe.add_element('cckk', (p, r, i, k), (1.0) * kdelta(j, q))
        dbe.add_element('cckk', (p, q, i, k), (-1.0) * kdelta(j, r))
        dbe.add_element('cckk', (q, r, i, j), (1.0) * kdelta(k, p))
        dbe.add_element('cckk', (p, r, i, j), (-1.0) * kdelta(k, q))
        dbe.add_element('cckk', (p, q, i, j), (1.0) * kdelta(k, r))
        dbe.add_element('t1', (p, q, r, i, j, k), -1.0)
        dbe.simplify()
        db.append(dbe)
    return DualBasis(elements=db)
コード例 #28
0
def trace_d2_ab(dim, Na, Nb):
    dbe = DualBasisElement()
    for i, j in product(range(dim), repeat=2):
        dbe.add_element('cckk_ab', (i, j, i, j), 1.0)
    dbe.dual_scalar = Na * Nb
    return dbe
コード例 #29
0
    def d2q2element(p, q, r, s, factor, tname_d1_1, tname_d2,
                    tname_q2):  # , spin_string):
        """
        # (   1.00000) cre(r) cre(s) des(q) des(p)

        # (   1.00000) kdelta(p,s) cre(r) des(q)

        # (  -1.00000) kdelta(p,r) cre(s) des(q)

        # (  -1.00000) kdelta(q,s) cre(r) des(p)

        # (   1.00000) kdelta(q,r) cre(s) des(p)

        # (  -1.00000) kdelta(p,s) kdelta(q,r)
        # (   1.00000) kdelta(p,r) kdelta(q,s)
        """
        dbe = DualBasisElement()
        dbe.add_element(tname_q2, (p, q, r, s), -factor)
        dbe.add_element(tname_d2, (r, s, p, q), factor)

        if p == s:
            dbe.add_element(tname_d1_1, (r, q), factor)
        if p == r:
            dbe.add_element(tname_d1_1, (s, q), -factor)
        if q == s:
            dbe.add_element(tname_d1_1, (r, p), -factor)
        if q == r:
            dbe.add_element(tname_d1_1, (s, p), factor)

        # remember the negative sign because AX = b
        dbe.dual_scalar = -factor * (krond[p, r] * krond[q, s] -
                                     krond[p, s] * krond[q, r])

        # dbe.add_element('kkcc_' + spin_string + spin_string, (r, s, p, q), factor)
        # if q == s:
        #     dbe.add_element('ck_' + spin_string, (p, r), factor)
        # if p == s:
        #     dbe.add_element('ck_' + spin_string, (q, r), -factor)
        # if q == r:
        #     dbe.add_element('kc_' + spin_string, (s, p), factor)
        # if p == r:
        #     dbe.add_element('kc_' + spin_string, (s, q), -factor)

        # dbe.add_element('cckk_' + spin_string + spin_string, (p, q, r, s), -factor)
        # dbe.dual_scalar = 0
        return dbe
コード例 #30
0
def d2_to_t1_matrix(dim):
    """
    Generate the dual basis elements for mapping d2 and d1 to the T1-matrix

    The T1 condition is the sum of three-marginals

    T1 = <p^ q^ r^ i j k>  i j k p^ q^ r^>

    in such a fashion that any triples component cancels out. T1 will be
    represented over antisymmeterized basis functions to save a significant amount
    of space

    :param dim: spin-orbital basis dimension
    :return:
    """
    db = []  # DualBasis()
    for p, q, r, i, j, k in product(range(dim), repeat=6):
        if (p * dim**2 + q * dim + r <= i * dim**2 + j * dim + k and p != q
                and q != r and p != r and i != j and j != k and i != k):
            print(p, q, r, i, j, k)
            dbe = DualBasisElement()
            if np.isclose(p * dim**2 + q * dim + r, i * dim**2 + j * dim + k):
                # diagonal term should be treated once
                dbe.dual_scalar -= t1_dual_scalar(p, q, r, i, j, k)
                for element in t1_opdm_component(p, q, r, i, j, k):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0])
                for element in t1_tpdm_component(p, q, r, i, j, k):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0])
                dbe.add_element('t1', (p, q, r, i, j, k), -1.0)
            else:
                dbe.dual_scalar -= t1_dual_scalar(p, q, r, i, j, k) * 0.5
                for element in t1_opdm_component(p, q, r, i, j, k):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0] * 0.5)
                for element in t1_tpdm_component(p, q, r, i, j, k):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0] * 0.5)

                dbe.dual_scalar -= t1_dual_scalar(i, j, k, p, q, r) * 0.5
                for element in t1_opdm_component(i, j, k, p, q, r):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0] * 0.5)
                for element in t1_tpdm_component(i, j, k, p, q, r):
                    # dbe.join_elements(element)
                    dbe.add_element(element.primal_tensors_names[0],
                                    element.primal_elements[0],
                                    element.primal_coeffs[0] * 0.5)

                # This is the weirdest part right here!
                # we reference everything else in tensor ordering but then this is
                # put into a weird matrix order.  The way it works is that it
                # just groups them
                dbe.add_element('t1', (p, q, r, i, j, k), -0.5)
                dbe.add_element('t1', (i, j, k, p, q, r), -0.5)

            dbe.simplify()
            db.append(dbe)
    return DualBasis(elements=db)