def tpdm_to_opdm_mapping(dim: int, normalization: Union[float, int]) -> DualBasis: """ Construct the DualBasis for mapping of the tpdm to the opdm Args: dim: dimension of the spin-orbital basis. normalization: Scalar for mapping tpdm to opdm. Generally, this is 1 / (N - 1) where N is the number of electrons. Returns: DualBasis for all dim^2 """ db_basis = DualBasis() for i in range(dim): for j in range(i, dim): dbe = DualBasisElement() # contract over tpdm terms for r in range(dim): # duplicate entries get summed in DualBasisElement dbe.add_element('cckk', (i, r, j, r), 0.5) dbe.add_element('cckk', (j, r, i, r), 0.5) # opdm terms dbe.add_element('ck', (i, j), -0.5 * normalization) dbe.add_element('ck', (j, i), -0.5 * normalization) dbe.simplify() db_basis += dbe return db_basis
def test_simplify(): i, j, k, l = 0, 1, 2, 3 names = ['opdm'] * 3 + ['oqdm'] elements = [(i, j), (i, j), (i, l), (l, k)] coeffs = [1, 1, 0.25, 0.3] dbe = DualBasisElement(tensor_names=names, tensor_elements=elements, tensor_coeffs=coeffs) dbe.simplify() assert len(dbe.primal_tensors_names) == 3 assert set(dbe.primal_coeffs) == {2, 0.25, 0.3} assert set(dbe.primal_tensors_names) == {'opdm', 'oqdm'} assert set(dbe.primal_elements) == {(0, 1), (0, 3), (3, 2)}