Esempio n. 1
0
    def _two_body_mapping(h2_ijkm_a_ijkm, threshold):
        """
        Subroutine for two body mapping. We use the chemists notation
        for the two-body term, h2(i,j,k,m) adag_i adag_k a_m a_j.

        Args:
            h2_ijkm_aijkm (tuple): value of h2 at index (i,j,k,m),
                                   pauli at index i, pauli at index j,
                                   pauli at index k, pauli at index m
            threshold: (float): threshold to remove a pauli

        Returns:
            WeightedPauliOperator: Operator for those paulis
        """
        h2_ijkm, a_i, a_j, a_k, a_m = h2_ijkm_a_ijkm
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                for gamma in range(2):
                    for delta in range(2):
                        pauli_prod_1 = Pauli.sgn_prod(a_i[alpha], a_k[beta])
                        pauli_prod_2 = Pauli.sgn_prod(pauli_prod_1[0], a_m[gamma])
                        pauli_prod_3 = Pauli.sgn_prod(pauli_prod_2[0], a_j[delta])

                        phase1 = pauli_prod_1[1] * pauli_prod_2[1] * pauli_prod_3[1]
                        phase2 = np.power(-1j, alpha + beta) * np.power(1j, gamma + delta)
                        pauli_term = [h2_ijkm / 16 * phase1 * phase2, pauli_prod_3[0]]
                        if np.absolute(pauli_term[0]) > threshold:
                            pauli_list.append(pauli_term)
        return WeightedPauliOperator(paulis=pauli_list)
Esempio n. 2
0
    def test_sgn_prod(self):
        """Test sgn prod."""
        p1 = Pauli(np.array([False]), np.array([True]))
        p2 = Pauli(np.array([True]), np.array([True]))

        self.log.info("sign product:")
        p3, sgn = Pauli.sgn_prod(p1, p2)
        self.log.info("p1: %s", p1.to_label())
        self.log.info("p2: %s", p2.to_label())
        self.log.info("p3: %s", p3.to_label())
        self.log.info("sgn_prod(p1, p2): %s", str(sgn))
        self.assertEqual(p1.to_label(), 'X')
        self.assertEqual(p2.to_label(), 'Y')
        self.assertEqual(p3.to_label(), 'Z')
        self.assertEqual(sgn, 1j)

        self.log.info("sign product reverse:")
        p3, sgn = Pauli.sgn_prod(p2, p1)
        self.log.info("p2: %s", p2.to_label())
        self.log.info("p1: %s", p1.to_label())
        self.log.info("p3: %s", p3.to_label())
        self.log.info("sgn_prod(p2, p1): %s", str(sgn))
        self.assertEqual(p1.to_label(), 'X')
        self.assertEqual(p2.to_label(), 'Y')
        self.assertEqual(p3.to_label(), 'Z')
        self.assertEqual(sgn, -1j)
Esempio n. 3
0
    def compose(self,
                other: OperatorBase,
                permutation: Optional[List[int]] = None,
                front: bool = False) -> OperatorBase:

        new_self, other = self._expand_shorter_operator_and_permute(
            other, permutation)
        new_self = cast(PauliOp, new_self)

        if front:
            return other.compose(new_self)
        # If self is identity, just return other.
        if not any(new_self.primitive.x +
                   new_self.primitive.z):  # type: ignore
            return other * new_self.coeff  # type: ignore

        # Both Paulis
        if isinstance(other, PauliOp):
            product, phase = Pauli.sgn_prod(new_self.primitive,
                                            other.primitive)
            return PrimitiveOp(product,
                               coeff=new_self.coeff * other.coeff * phase)

        # pylint: disable=cyclic-import,import-outside-toplevel
        from .circuit_op import CircuitOp
        from ..state_fns.circuit_state_fn import CircuitStateFn
        if isinstance(other, (CircuitOp, CircuitStateFn)):
            return new_self.to_circuit_op().compose(other)

        return super(PauliOp, new_self).compose(other)
Esempio n. 4
0
    def _three_body_mapping(h3_ijkmpq_a_ijkmpq, threshold):
        """
        Subroutine for three body mapping. We use the chemists notation
        for the two-body term, h2(i,j,k,m,p,q) adag_i adag_k adag_p a_q a_m a_j .

        Args:
            h2_ijkmpq_a_ijkmpq (tuple): value of h3 at index (i,j,k,m,p,q),
                                    pauli at index i, pauli at index j, 
                                    pauli at index k, pauli at index m,
                                    pauli at index p, pauli at index q
            threshold (float): threshold to remove a pauli

        Returns:
            WeightedPauliOperator: Operator for those paulis
        """
        h3_ijkmpq, a_i, a_j, a_k, a_m, a_p, a_q = h3_ijkmpq_a_ijkmpq
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                for gamma in range(2):
                    for delta in range(2):
                        for theta in range(2):
                            for phi in range(2):
                                pauli_prod_1 = Pauli.sgn_prod(
                                    a_i[alpha], a_k[beta])
                                pauli_prod_2 = Pauli.sgn_prod(
                                    pauli_prod_1[0], a_p[gamma])
                                pauli_prod_3 = Pauli.sgn_prod(
                                    pauli_prod_2[0], a_q[delta])
                                pauli_prod_4 = Pauli.sgn_prod(
                                    pauli_prod_3[0], a_m[theta])
                                pauli_prod_5 = Pauli.sgn_prod(
                                    pauli_prod_4[0], a_j[phi])

                                phase1 = pauli_prod_1[1] * pauli_prod_2[1] * pauli_prod_3[1] * \
                                    pauli_prod_4[1] * pauli_prod_5[1]
                                phase2 = np.power(-1j, alpha + beta + gamma) * \
                                    np.power(1j, delta + theta + phi)
                                pauli_term = [
                                    h3_ijkmpq / 64 * phase1 * phase2,
                                    pauli_prod_5[0]
                                ]
                                if np.absolute(pauli_term[0]) > threshold:
                                    pauli_list.append(pauli_term)
        return WeightedPauliOperator(paulis=pauli_list)
    def _two_body_mapping(h2_ijkm, a_i, a_j, a_k, a_m, threshold):
        """
        Subroutine for two body mapping.

        Args:
            h1_ijkm (complex): value of h2 at index (i,j,k,m)
            a_i (Pauli): pauli at index i
            a_j (Pauli): pauli at index j
            a_k (Pauli): pauli at index k
            a_m (Pauli): pauli at index m
            threshold: (float): threshold to remove a pauli

        Returns:
            Operator: Operator for those paulis
        """
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                for gamma in range(2):
                    for delta in range(2):
                        pauli_prod_1 = Pauli.sgn_prod(a_i[alpha], a_k[beta])
                        pauli_prod_2 = Pauli.sgn_prod(pauli_prod_1[0],
                                                      a_m[gamma])
                        pauli_prod_3 = Pauli.sgn_prod(pauli_prod_2[0],
                                                      a_j[delta])

                        phase1 = pauli_prod_1[1] * pauli_prod_2[
                            1] * pauli_prod_3[1]
                        phase2 = np.power(-1j, alpha + beta) * np.power(
                            1j, gamma + delta)
                        pauli_term = [
                            h2_ijkm / 16 * phase1 * phase2, pauli_prod_3[0]
                        ]
                        if np.absolute(pauli_term[0]) > threshold:
                            pauli_list.append(pauli_term)
        return Operator(paulis=pauli_list)
    def multiply(self, other):
        """
        Perform self * other, and the phases are tracked.

        Args:
            other (WeightedPauliOperator): an operator

        Returns:
            WeightedPauliOperator: the multiplied operator
        """
        ret_op = WeightedPauliOperator(paulis=[])
        for existed_weight, existed_pauli in self.paulis:
            for weight, pauli in other.paulis:
                new_pauli, sign = Pauli.sgn_prod(existed_pauli, pauli)
                new_weight = existed_weight * weight * sign
                pauli_term = [new_weight, new_pauli]
                ret_op += WeightedPauliOperator(paulis=[pauli_term])
        return ret_op
Esempio n. 7
0
    def compose(self, other: OperatorBase) -> OperatorBase:
        other = self._check_zero_for_composition_and_expand(other)

        # If self is identity, just return other.
        if not any(self.primitive.x + self.primitive.z):  # type: ignore
            return other * self.coeff  # type: ignore

        # Both Paulis
        if isinstance(other, PauliOp):
            product, phase = Pauli.sgn_prod(self.primitive, other.primitive)
            return PrimitiveOp(product, coeff=self.coeff * other.coeff * phase)

        # pylint: disable=cyclic-import,import-outside-toplevel
        from .circuit_op import CircuitOp
        from ..state_fns.circuit_state_fn import CircuitStateFn
        if isinstance(other, (CircuitOp, CircuitStateFn)):
            return self.to_circuit_op().compose(other)

        return ComposedOp([self, other])
Esempio n. 8
0
def _one_body_mapping(a_i, a_j, threshold=0.000001):
        """
        Subroutine for one body mapping.
        Args:
            a_i (Pauli): pauli at index i
            a_j (Pauli): pauli at index j
            threshold: (float): threshold to remove a pauli
        Returns:
            Operator: Operator for those paulis
        """
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                pauli_prod = Pauli.sgn_prod(a_i[alpha], a_j[beta])
                coeff = 1.0/4 * pauli_prod[1] * np.power(-1j, alpha) * np.power(1j, beta)
                pauli_term = [coeff, pauli_prod[0]]
                if np.absolute(pauli_term[0]) > threshold:
                    pauli_list.append(pauli_term)
        return Operator(paulis=pauli_list)
Esempio n. 9
0
    def _one_body_mapping(h1_ij_aij, threshold):
        """
        Subroutine for one body mapping.

        Args:
            h1_ij_aij (tuple): value of h1 at index (i,j), pauli at index i, pauli at index j
            threshold: (float): threshold to remove a pauli

        Returns:
            WeightedPauliOperator: Operator for those paulis
        """
        h1_ij, a_i, a_j = h1_ij_aij
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                pauli_prod = Pauli.sgn_prod(a_i[alpha], a_j[beta])
                coeff = h1_ij / 4 * pauli_prod[1] * np.power(-1j, alpha) * np.power(1j, beta)
                pauli_term = [coeff, pauli_prod[0]]
                if np.absolute(pauli_term[0]) > threshold:
                    pauli_list.append(pauli_term)
        return WeightedPauliOperator(paulis=pauli_list)
Esempio n. 10
0
    def _one_body_mapping(self, h1_ij_aij: Tuple[float, Pauli,
                                                 Pauli]) -> PauliSumOp:
        """ Subroutine for one body mapping.

        Args:
            h1_ij_aij: value of h1 at index (i,j), pauli at index i, pauli at index j

        Returns:
            Operator for those paulis
        """
        h1_ij, a_i, a_j = h1_ij_aij
        pauli_list = []
        for alpha in range(2):
            for beta in range(2):
                pauli_prod = Pauli.sgn_prod(a_i[alpha], a_j[beta])
                coeff = h1_ij / 4 * pauli_prod[1] * np.power(
                    -1j, alpha) * np.power(1j, beta)
                pauli_term = [coeff, pauli_prod[0]]
                pauli_list.append(pauli_term)

        op = PauliSumOp.from_list([(pauli[1].to_label(), pauli[0])
                                   for pauli in pauli_list])

        return op