Esempio n. 1
0
    def test_expval(self):
        """Test expectation_value method"""

        psi = Statevector([1, 0, 0, 1]) / np.sqrt(2)
        rho = DensityMatrix(psi)
        for label, target in [('II', 1), ('XX', 1), ('YY', -1), ('ZZ', 1),
                              ('IX', 0), ('YZ', 0), ('ZX', 0), ('YI', 0)]:
            with self.subTest(msg="<{}>".format(label)):
                op = Pauli(label)
                expval = rho.expectation_value(op)
                self.assertAlmostEqual(expval, target)

        psi = Statevector([np.sqrt(2), 0, 0, 0, 0, 0, 0, 1 + 1j]) / 2
        rho = DensityMatrix(psi)
        for label, target in [('XXX', np.sqrt(2) / 2),
                              ('YYY', -np.sqrt(2) / 2), ('ZZZ', 0), ('XYZ', 0),
                              ('YIY', 0)]:
            with self.subTest(msg="<{}>".format(label)):
                op = Pauli(label)
                expval = rho.expectation_value(op)
                self.assertAlmostEqual(expval, target)

        labels = ['XXX', 'IXI', 'YYY', 'III']
        coeffs = [3.0, 5.5, -1j, 23]
        spp_op = SparsePauliOp.from_list(list(zip(labels, coeffs)))
        expval = rho.expectation_value(spp_op)
        target = 25.121320343559642 + 0.7071067811865476j
        self.assertAlmostEqual(expval, target)
 def test_expval_pauli(self, pauli):
     """Test expectation_value method for Pauli op"""
     seed = 1020
     op = Pauli(pauli)
     state = random_statevector(2**op.num_qubits, seed=seed)
     target = state.expectation_value(op.to_matrix())
     expval = state.expectation_value(op)
     self.assertAlmostEqual(expval, target)
Esempio n. 3
0
 def test_expval_pauli_c_contiguous(self, pauli):
     """Test expectation_value method for Pauli op"""
     seed = 1020
     op = Pauli(pauli)
     rho = random_density_matrix(2**op.num_qubits, seed=seed)
     rho._data = np.reshape(rho.data.flatten(order="C"), rho.data.shape, order="C")
     target = rho.expectation_value(op.to_matrix())
     expval = rho.expectation_value(op)
     self.assertAlmostEqual(expval, target)
Esempio n. 4
0
 def test_hf_bitstring_mapped(self):
     """Mapped bitstring test for water"""
     # Original driver config when creating operator that resulted in symmetries coded
     # below. The sector [1, -1] is the correct ground sector.
     # PySCFDriver(
     #    atom="O 0.0000 0.0000 0.1173; H 0.0000 0.07572 -0.4692;H 0.0000 -0.07572 -0.4692",
     #    unit=UnitsType.ANGSTROM,
     #    charge=0,
     #    spin=0,
     #    basis='sto-3g',
     #    hf_method=HFMethodType.RHF)
     num_spin_orbitals = 14
     num_particles = (5, 5)
     converter = QubitConverter(ParityMapper(), two_qubit_reduction=True)
     z2symmetries = Z2Symmetries(
         symmetries=[Pauli("IZZIIIIZZIII"),
                     Pauli("ZZIZIIZZIZII")],
         sq_paulis=[Pauli("IIIIIIIIXIII"),
                    Pauli("IIIIIIIIIXII")],
         sq_list=[3, 2],
         tapering_values=[1, -1],
     )
     with self.subTest("Matched bitsring creation"):
         converter.force_match(num_particles=num_particles,
                               z2symmetries=z2symmetries)
         bitstr = hartree_fock_bitstring_mapped(
             num_spin_orbitals=num_spin_orbitals,
             num_particles=num_particles,
             qubit_converter=converter,
         )
         ref_matched = [
             True, False, True, True, False, True, False, True, False, False
         ]
         self.assertListEqual(bitstr, ref_matched)
     with self.subTest("Bitsring creation with no tapering"):
         bitstr = hartree_fock_bitstring_mapped(
             num_spin_orbitals=num_spin_orbitals,
             num_particles=num_particles,
             qubit_converter=converter,
             match_convert=False,
         )
         ref_notaper = [
             True,
             False,
             True,
             False,
             True,
             True,
             False,
             True,
             False,
             True,
             False,
             False,
         ]
         self.assertListEqual(bitstr, ref_notaper)
Esempio n. 5
0
 def test_qubits_6_py_lih(self):
     """qubits 6 py lih test"""
     num_particles = (1, 1)
     converter = QubitConverter(ParityMapper(), two_qubit_reduction=True)
     z2symmetries = Z2Symmetries(
         symmetries=[Pauli("ZIZIZIZI"),
                     Pauli("ZZIIZZII")],
         sq_paulis=[Pauli("IIIIIIXI"), Pauli("IIIIIXII")],
         sq_list=[2, 3],
         tapering_values=[1, 1],
     )
     converter.force_match(num_particles=num_particles,
                           z2symmetries=z2symmetries)
     state = HartreeFock(10, num_particles, converter)
     ref = QuantumCircuit(6)
     ref.x([0, 1])
     self.assertEqual(state, ref)
Esempio n. 6
0
    def _rowsum_deterministic(table, aux_pauli, row):
        """Updating an auxilary Pauli aux_pauli in the
        deterministic rowsum calculation.
        The StabilizerState itself is not updated."""

        row_phase = table.phase[row]
        accum_phase = aux_pauli.phase

        accum_pauli = aux_pauli
        row_pauli = table.pauli[row]
        row_pauli = Pauli(row_pauli.to_labels()[0])

        accum_pauli, accum_phase = StabilizerState._rowsum(
            accum_pauli, accum_phase, row_pauli, row_phase)

        aux_pauli = accum_pauli
        aux_pauli.phase = accum_phase
        return aux_pauli
Esempio n. 7
0
    def test_expval(self):
        """Test expectation_value method"""

        psi = Statevector([1, 0, 0, 1]) / np.sqrt(2)
        rho = DensityMatrix(psi)
        for label, target in [
            ("II", 1),
            ("XX", 1),
            ("YY", -1),
            ("ZZ", 1),
            ("IX", 0),
            ("YZ", 0),
            ("ZX", 0),
            ("YI", 0),
        ]:
            with self.subTest(msg=f"<{label}>"):
                op = Pauli(label)
                expval = rho.expectation_value(op)
                self.assertAlmostEqual(expval, target)

        psi = Statevector([np.sqrt(2), 0, 0, 0, 0, 0, 0, 1 + 1j]) / 2
        rho = DensityMatrix(psi)
        for label, target in [
            ("XXX", np.sqrt(2) / 2),
            ("YYY", -np.sqrt(2) / 2),
            ("ZZZ", 0),
            ("XYZ", 0),
            ("YIY", 0),
        ]:
            with self.subTest(msg=f"<{label}>"):
                op = Pauli(label)
                expval = rho.expectation_value(op)
                self.assertAlmostEqual(expval, target)

        labels = ["XXX", "IXI", "YYY", "III"]
        coeffs = [3.0, 5.5, -1j, 23]
        spp_op = SparsePauliOp.from_list(list(zip(labels, coeffs)))
        expval = rho.expectation_value(spp_op)
        target = 25.121320343559642 + 0.7071067811865476j
        self.assertAlmostEqual(expval, target)
Esempio n. 8
0
    def _measure_and_update(self, qubit, randbit):
        """Measure a single qubit and return outcome and post-measure state.

        Note that this function uses the QuantumStates internal random
        number generator for sampling the measurement outcome. The RNG
        seed can be set using the :meth:`seed` method.

        Note that stabilizer state measurements only have three probabilities:
        (p0, p1) = (0.5, 0.5), (1, 0), or (0, 1)
        The random case happens if there is a row anti-commuting with Z[qubit]
        """

        num_qubits = self.clifford.num_qubits
        table = self.clifford.table
        stab_x = self.clifford.stabilizer.X

        # Check if there exists stabilizer anticommuting with Z[qubit]
        # in this case the measurement outcome is random
        z_anticommuting = np.any(stab_x[:, qubit])

        if z_anticommuting == 0:
            # Deterministic outcome - measuring it will not change the StabilizerState
            aux_pauli = Pauli(num_qubits * "I")
            for i in range(num_qubits):
                if table.X[i][qubit]:
                    aux_pauli = self._rowsum_deterministic(
                        table, aux_pauli, i + num_qubits)
            outcome = aux_pauli.phase
            return outcome

        else:
            # Non-deterministic outcome
            outcome = randbit
            p_qubit = np.min(np.nonzero(stab_x[:, qubit]))
            p_qubit += num_qubits

            # Updating the StabilizerState
            for i in range(2 * num_qubits):
                # the last condition is not in the AG paper but we seem to need it
                if (table.X[i][qubit]) and (i != p_qubit) and (
                        i != (p_qubit - num_qubits)):
                    self._rowsum_nondeterministic(table, i, p_qubit)

            table[p_qubit - num_qubits] = table[p_qubit].copy()
            table.X[p_qubit] = np.zeros(num_qubits)
            table.Z[p_qubit] = np.zeros(num_qubits)
            table.Z[p_qubit][qubit] = True
            table.phase[p_qubit] = outcome
            return outcome
Esempio n. 9
0
    def expectation_value(self, oper, qargs=None):
        """Compute the expectation value of an operator.

        Args:
            oper (Operator): an operator to evaluate expval.
            qargs (None or list): subsystems to apply the operator on.

        Returns:
            complex: the expectation value.
        """
        if isinstance(oper, Pauli):
            return self._expectation_value_pauli(oper)

        if isinstance(oper, SparsePauliOp):
            return sum([coeff * self._expectation_value_pauli(Pauli((z, x)))
                        for z, x, coeff in zip(oper.table.Z, oper.table.X, oper.coeffs)])

        if not isinstance(oper, Operator):
            oper = Operator(oper)
        return np.trace(Operator(self).dot(oper, qargs=qargs).data)
Esempio n. 10
0
    def expectation_value(self, oper, qargs=None):
        """Compute the expectation value of an operator.

        Args:
            oper (Operator): an operator to evaluate expval of.
            qargs (None or list): subsystems to apply operator on.

        Returns:
            complex: the expectation value.
        """
        if isinstance(oper, Pauli):
            return self._expectation_value_pauli(oper)

        if isinstance(oper, SparsePauliOp):
            return sum([coeff * self._expectation_value_pauli(Pauli((z, x)))
                        for z, x, coeff in zip(oper.table.Z, oper.table.X, oper.coeffs)])

        val = self.evolve(oper, qargs=qargs)
        conj = self.conjugate()
        return np.dot(conj.data, val.data)
Esempio n. 11
0
    def _rowsum_nondeterministic(table, accum, row):
        """Updating StabilizerState Clifford table in the
        non-deterministic rowsum calculation.
        row and accum are rows in the StabilizerState Clifford table."""

        row_phase = table.phase[row]
        accum_phase = table.phase[accum]

        row_pauli = table.pauli[row]
        accum_pauli = table.pauli[accum]
        row_pauli = Pauli(row_pauli.to_labels()[0])
        accum_pauli = Pauli(accum_pauli.to_labels()[0])

        accum_pauli, accum_phase = StabilizerState._rowsum(
            accum_pauli, accum_phase, row_pauli, row_phase)

        table.phase[accum] = accum_phase
        table.X[accum] = accum_pauli.x
        table.Z[accum] = accum_pauli.z
Esempio n. 12
0
    def expectation_value(self, oper, qargs=None):
        """Compute the expectation value of a Pauli operator.

        Args:
            oper (Pauli): a Pauli operator to evaluate expval.
            qargs (None or list): subsystems to apply the operator on.

        Returns:
            complex: the expectation value (only 0 or 1 or -1 or i or -i).

        Raises:
            QiskitError: if oper is not a Pauli operator.
        """
        if not isinstance(oper, Pauli):
            raise QiskitError(
                "Operator for expectation value is not a Pauli operator.")

        num_qubits = self.clifford.num_qubits
        if qargs is None:
            qubits = range(num_qubits)
        else:
            qubits = qargs

        # Construct Pauli on num_qubits
        pauli = Pauli(num_qubits * "I")
        phase = 0
        pauli_phase = (-1j)**oper.phase if oper.phase else 1

        for pos, qubit in enumerate(qubits):
            pauli.x[qubit] = oper.x[pos]
            pauli.z[qubit] = oper.z[pos]
            phase += pauli.x[qubit] & pauli.z[qubit]

        # Check if there is a stabilizer that anti-commutes with an odd number of qubits
        # If so the expectation value is 0
        for p in range(num_qubits):
            stab = self.clifford.stabilizer
            num_anti = 0
            num_anti += np.count_nonzero(pauli.z & stab.X[p])
            num_anti += np.count_nonzero(pauli.x & stab.Z[p])
            if num_anti % 2 == 1:
                return 0

        # Otherwise pauli is (-1)^a prod_j S_j^b_j for Clifford stabilizers
        # If pauli anti-commutes with D_j then b_j = 1.
        # Multiply pauli by stabilizers with anti-commuting destabilizers
        pauli_z = (pauli.z).copy()  # Make a copy of pauli.z
        for p in range(num_qubits):
            # Check if destabilizer anti-commutes
            destab = self.clifford.destabilizer
            num_anti = 0
            num_anti += np.count_nonzero(pauli.z & destab.X[p])
            num_anti += np.count_nonzero(pauli.x & destab.Z[p])
            if num_anti % 2 == 0:
                continue

            # If anti-commutes multiply Pauli by stabilizer
            stab = self.clifford.stabilizer
            phase += 2 * self.clifford.table.phase[p + num_qubits]
            phase += np.count_nonzero(stab.Z[p] & stab.X[p])
            phase += 2 * np.count_nonzero(pauli_z & stab.X[p])
            pauli_z = pauli_z ^ stab.Z[p]

        # For valid stabilizers, `phase` can only be 0 (= 1) or 2 (= -1) at this point.
        if phase % 4 != 0:
            return -pauli_phase

        return pauli_phase
    def expectation_value(self, oper, qargs=None):
        """Compute the expectation value of an operator.

        Args:
            oper (BaseOperator): an operator to evaluate expval.
            qargs (None or list): subsystems to apply the operator on.

        Returns:
            complex: the expectation value (only 0 or 1 or -1).
        """
        num_qubits = self.clifford.num_qubits
        if qargs is None:
            qubits = range(num_qubits)
        else:
            qubits = qargs

        # Construct Pauli on num_qubits
        pauli = Pauli(num_qubits * "I")
        phase = 0

        for pos, qubit in enumerate(qubits):
            pauli_pos = (oper.to_label())[len(oper) - 1 - pos]
            if pauli_pos == "X":
                pauli.x[qubit] = 1
            elif pauli_pos == "Y":
                pauli.x[qubit] = 1
                pauli.z[qubit] = 1
                phase += 1
            elif pauli_pos == "Z":
                pauli.z[qubit] = 1
            else:
                pass

        # Check if there is a stabilizer that anti-commutes with an odd number of qubits
        # If so the expectation value is 0
        for p in range(num_qubits):
            stab = self.clifford.stabilizer
            num_anti = 0
            num_anti += np.count_nonzero(pauli.z & stab.X[p])
            num_anti += np.count_nonzero(pauli.x & stab.Z[p])
            if num_anti % 2 == 1:
                return 0

        # Otherwise pauli is (-1)^a prod_j S_j^b_j for Clifford stabilizers
        # If pauli anti-commutes with D_j then b_j = 1.
        # Multiply pauli by stabilizers with anti-commuting destabilizers
        pauli_z = (pauli.z).copy()  # Make a copy of pauli.z
        for p in range(num_qubits):
            # Check if destabilizer anti-commutes
            destab = self.clifford.destabilizer
            num_anti = 0
            num_anti += np.count_nonzero(pauli.z & destab.X[p])
            num_anti += np.count_nonzero(pauli.x & destab.Z[p])
            if num_anti % 2 == 0:
                continue

            # If anti-commutes multiply Pauli by stabilizer
            stab = self.clifford.stabilizer
            phase += 2 * self.clifford.table.phase[p + num_qubits]
            phase += np.count_nonzero(stab.Z[p] & stab.X[p])
            phase += 2 * np.count_nonzero(pauli_z & stab.X[p])
            pauli_z = pauli_z ^ stab.Z[p]

        if phase % 4 != 0:
            return -1

        return 1