def opdm_to_ohdm_mapping(dim: int) -> DualBasis: """ Map the ck to kc D1 + Q1 = I Args: dim: dimension of the spin-orbital basis Returns: DualBasis for the 1-RDM representability constraint """ 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
def d2q2element(p: int, q: int, r: int, s: int, factor: Union[float, int])\ -> DualBasisElement: """ 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) if q == s: dbe.add_element('ck', (p, r), factor) if p == r: dbe.add_element('ck', (q, s), factor) if q == r: dbe.add_element('ck', (p, s), -1. * factor) if p == s: dbe.add_element('ck', (q, r), -1. * factor) dbe.dual_scalar = ( kronecker_delta(q, s) * kronecker_delta(p, r) - kronecker_delta(q, r) * kronecker_delta(p, s)) * factor return dbe
def nb_constraint(dim, nb): """ Constraint the trace of the alpha block of the opdm to equal the number of spin-down electrons Args: dim: Dimension of the spin-orbital basis. na: Number of spin down electrons Returns: DualBasis representing the cosntraint that is length 1 """ 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])
def sz_constraint(dim: int, sz: Union[float, int]) -> DualBasis: """ Constraint on the 1-RDM Args: dim: dimension of the spin-orbital basis. sz: expectation value of the magnetic quantum number. Returns: DualBasis """ 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])
def na_constraint(dim: int, na: Union[float, int]) -> DualBasis: """ Constraint the trace of the alpha block of the opdm to equal the number of spin-up electrons Args: dim: Dimension of the spin-orbital basis. na: Number of spin up electrons Returns: DualBasis representing the cosntraint that is length 1 """ dbe = DualBasisElement() for i in range(dim // 2): dbe.add_element('ck', (2 * i, 2 * i), 1.0) dbe.dual_scalar = na return DualBasis(elements=[dbe])
def g2d2map(p: int, q: int, r: int, s: int, factor: Optional[Union[float, int]] = 1) -> DualBasisElement: """ 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() if q == s: dbe.add_element('ck', (p, r), -1. * 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