Пример #1
0
def d2aa_d1a_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, 2 * r, 2 * j, 2 * r), 0.5)
                dbe.add_element('cckk', (2 * j, 2 * r, 2 * i, 2 * r), 0.5)

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

    # return DualBasis(elements=dbe_list)  # db_basis
    return db_basis
Пример #2
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)
Пример #3
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)
Пример #4
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
Пример #5
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
Пример #6
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
Пример #7
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
Пример #8
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
Пример #9
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)
Пример #10
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)
Пример #11
0
def d2_to_t1_matrix_antisym(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 < r
                and i < j < 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):
                for pp, qq, rr, cparity in _three_parity(p, q, r):
                    for ii, jj, kk, rparity in _three_parity(i, j, k):
                        # diagonal term should be treated once
                        dbe.dual_scalar -= t1_dual_scalar(
                            pp, qq, rr, ii, jj, kk) * cparity * rparity / 6
                        for element in t1_opdm_component(
                                pp, qq, rr, ii, jj, kk):
                            # dbe.join_elements(element)
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] / 6)
                        for element in t1_tpdm_component(
                                pp, qq, rr, ii, jj, kk):
                            # dbe.join_elements(element)
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] / 6)
                dbe.add_element('t1', (p, q, r, i, j, k), -1.0)
            else:
                for pp, qq, rr, cparity in _three_parity(p, q, r):
                    for ii, jj, kk, rparity in _three_parity(i, j, k):
                        dbe.dual_scalar -= t1_dual_scalar(
                            pp, qq, rr, ii, jj, kk) * 0.5 / 6
                        for element in t1_opdm_component(
                                pp, qq, rr, ii, jj, kk):
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] * 0.5 / 6)
                        for element in t1_tpdm_component(
                                pp, qq, rr, ii, jj, kk):
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] * 0.5 / 6)
                dbe.add_element('t1', (p, q, r, i, j, k), -0.5)

                for pp, qq, rr, cparity in _three_parity(i, j, k):
                    for ii, jj, kk, rparity in _three_parity(p, q, r):
                        dbe.dual_scalar -= t1_dual_scalar(
                            pp, qq, rr, ii, jj, kk) * 0.5 / 6
                        for element in t1_opdm_component(
                                pp, qq, rr, ii, jj, kk):
                            # dbe.join_elements(element)
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] * 0.5 / 6)
                        for element in t1_tpdm_component(
                                pp, qq, rr, ii, jj, kk):
                            # dbe.join_elements(element)
                            dbe.add_element(
                                element.primal_tensors_names[0],
                                element.primal_elements[0], cparity * rparity *
                                element.primal_coeffs[0] * 0.5 / 6)
                dbe.add_element('t1', (i, j, k, p, q, r), -0.5)

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