示例#1
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
示例#2
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
示例#3
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
示例#4
0
def d2_e2_mapping(dim, measured_tpdm):
    """
    Generate the constraints between the error matrix, d2, and a measured d2.

    :param dim: dimension of the spin-orbital basis
    :param measured_tpdm:  a 4-tensor of the measured 2-p
    :return:
    """
    db_elements = []
    for p, q, r, s in product(range(dim), repeat=4):
        if p * dim + q >= r * dim + s:
            dbe = DualBasisElement()
            # two elements of d2
            dbe.add_element('cckk', (p, q, r, s), 0.5)
            dbe.add_element('cckk', (r, s, p, q), 0.5)

            # add four elements of the error matrix
            dbe.add_element('cckk_me', (p * dim + q + dim**2, r * dim + s),
                            -0.25)
            dbe.add_element('cckk_me', (r * dim + s + dim**2, p * dim + q),
                            -0.25)
            dbe.add_element('cckk_me', (p * dim + q, r * dim + s + dim**2),
                            -0.25)
            dbe.add_element('cckk_me', (r * dim + s, p * dim + q + dim**2),
                            -0.25)

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

            # construct the dual basis element for constraining the [0, 0] orthant to be identity matrix
            dbe_idenity = DualBasisElement()
            if p * dim + q == r * dim + s:
                dbe_idenity.add_element('cckk_me', (p * dim + q, r * dim + s),
                                        1.0)
                dbe_idenity.dual_scalar = 1.0
            else:
                # will a symmetric constraint provide variational freedom?
                dbe_idenity.add_element('cckk_me', (p * dim + q, r * dim + s),
                                        0.5)
                dbe_idenity.add_element('cckk_me', (r * dim + s, p * dim + q),
                                        0.5)
                dbe_idenity.dual_scalar = 0.0

            db_elements.append(dbe)
            db_elements.append(dbe_idenity)

    return DualBasis(elements=db_elements)
示例#5
0
def d1a_d1b_mapping(tname_d1a, tname_d1b, dim):
    db = DualBasis()
    for i in range(dim):
        for j in range(i, dim):
            dbe = DualBasisElement()
            if i != j:
                dbe.add_element(tname_d1a, (i, j), 0.5)
                dbe.add_element(tname_d1a, (j, i), 0.5)
                dbe.add_element(tname_d1b, (i, j), -0.5)
                dbe.add_element(tname_d1b, (j, i), -0.5)
                dbe.dual_scalar = 0.0
            else:
                dbe.add_element(tname_d1a, (i, j), 1.0)
                dbe.add_element(tname_d1b, (i, j), -1.0)
                dbe.dual_scalar = 0.0

            db += dbe  # .simplify()

    return db
示例#6
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
示例#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 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
示例#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 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])
示例#11
0
    def g2d2map_ab(p, q, r, s, key, factor=1.0):
        dbe = DualBasisElement()
        if key == 'ab':
            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':
            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
示例#12
0
    def d2q2element(p, q, r, s, factor, tname_d1_1, tname_d1_2, tname_d2,
                    tname_q2):
        dbe = DualBasisElement()
        dbe.add_element(tname_d1_1, (p, r), 2.0 * krond[q, s] * factor)
        dbe.add_element(tname_d1_2, (q, s), 2.0 * krond[p, r] * factor)
        dbe.add_element(tname_d1_1, (p, s), -2.0 * krond[r, q] * factor)
        dbe.add_element(tname_d1_2, (q, r), -2.0 * krond[p, s] * 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)

        # remember the negative sign because AX = b
        dbe.dual_scalar = -2.0 * krond[s, p] * krond[
            r, q] * factor + 2.0 * krond[q, s] * krond[r, p] * factor
        return dbe
示例#13
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
示例#14
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
示例#15
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
示例#16
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 * 0.5)
                    else:
                        # TODO: Remember why I derived a factor of 0.25 (0.5 above) for this equation.
                        dbe.add_element(
                            'cckk_bb',
                            (ir_pair[0], ir_pair[1], jr_pair[0], jr_pair[1]),
                            sir * sjr * 0.25)
                        dbe.add_element(
                            'cckk_bb',
                            (jr_pair[0], jr_pair[1], ir_pair[0], ir_pair[1]),
                            sir * sjr * 0.25)

            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
示例#17
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
示例#18
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
示例#19
0
def d2aa_d1a_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):
                # 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_aa',
                            (ir_pair[0], ir_pair[1], jr_pair[0], jr_pair[1]),
                            sir * sjr)
                    else:
                        dbe.add_element(
                            'cckk_aa',
                            (ir_pair[0], ir_pair[1], jr_pair[0], jr_pair[1]),
                            sir * sjr * 0.5)
                        dbe.add_element(
                            'cckk_aa',
                            (jr_pair[0], jr_pair[1], ir_pair[0], ir_pair[1]),
                            sir * sjr * 0.5)

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

            # dbe.simplify()
            db += dbe

    return db
示例#20
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
示例#21
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
示例#22
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
示例#23
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
示例#24
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
示例#25
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
示例#26
0
def s_rep(dim, Na, Nb, S, sz):
    dbe = DualBasisElement()
    for i, j in product(range(dim // 2), repeat=2):
        dbe.add_element('cckk', (2 * i, 2 * j + 1, 2 * i + 1, 2 * j), 1.0)
    dbe.dual_scalar = 0.5 * (Na + Nb) + sz**2 - S * (S + 1)
    return DualBasis(elements=[dbe])