Exemple #1
0
    def __init__(self, p) -> None:
        r"""The phase flip channel.

        Construct a channel to flip the phase with probability p.

        This channel evolves a density matrix via:

            $$
            \rho \rightarrow M_0 \rho M_0^\dagger + M_1 \rho M_1^\dagger
            $$

        With:

            $$
            \begin{aligned}
            M_0 =& \sqrt{1 - p} \begin{bmatrix}
                                1 & 0  \\
                                0 & 1
                            \end{bmatrix}
            \\
            M_1 =& \sqrt{p} \begin{bmatrix}
                                1 & 0 \\
                                0 & -1
                            \end{bmatrix}
            \end{aligned}
            $$

        Args:
            p: the probability of a phase flip.

        Raises:
            ValueError: if p is not a valid probability.
        """
        self._p = value.validate_probability(p, 'p')
        self._delegate = AsymmetricDepolarizingChannel(0., 0., p)
Exemple #2
0
    def __init__(self, gamma) -> None:
        r"""The phase damping channel.

        Construct a channel that enacts a phase damping constant gamma.

        This channel evolves a density matrix via:

            $$
            \rho \rightarrow M_0 \rho M_0^\dagger + M_1 \rho M_1^\dagger
            $$

        With:

            $$
            \begin{aligned}
            M_0 =& \begin{bmatrix}
                    1 & 0 \\
                    0 & \sqrt{1 - \gamma}
                  \end{bmatrix}
            \\
            M_1 =& \begin{bmatrix}
                    0 & 0 \\
                    0 & \sqrt{\gamma}
                  \end{bmatrix}
            \end{aligned}
            $$

        Args:
            gamma: The damping constant.

        Raises:
            ValueError: if gamma is not a valid probability.
        """
        self._gamma = value.validate_probability(gamma, 'gamma')
Exemple #3
0
 def __init__(self, depol_prob: float, bitflip_prob: float,
              decay_prob: float):
     """A depolarizing noise model with damped readout error.
     Args:
         depol_prob: Depolarizing probability.
         bitflip_prob: Probability of a bit-flip during measurement.
         decay_prob: Probability of T1 decay during measurement.
             Bitflip noise is applied first, then amplitude decay.
     """
     value.validate_probability(depol_prob, 'depol prob')
     value.validate_probability(bitflip_prob, 'bitflip prob')
     value.validate_probability(decay_prob, 'decay_prob')
     self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob)
     self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
     self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob)
Exemple #4
0
    def __init__(self, gamma: float) -> None:
        r"""The amplitude damping channel.

        Construct a channel that dissipates energy. The probability of
        energy exchange occurring is given by gamma.

        This channel evolves a density matrix as follows:

            $$
            \rho \rightarrow M_0 \rho M_0^\dagger + M_1 \rho M_1^\dagger
            $$

        With:

            $$
            \begin{aligned}
            M_0 =& \begin{bmatrix}
                    1 & 0  \\
                    0 & \sqrt{1 - \gamma}
                  \end{bmatrix}
            \\
            M_1 =& \begin{bmatrix}
                    0 & \sqrt{\gamma} \\
                    0 & 0
                  \end{bmatrix}
            \end{aligned}
            $$

        Args:
            gamma: the probability of the interaction being dissipative.

        Raises:
            ValueError: is gamma is not a valid probability.
        """
        self._gamma = value.validate_probability(gamma, 'gamma')
        self._delegate = GeneralizedAmplitudeDampingChannel(1.0, self._gamma)
Exemple #5
0
    def __init__(self,
                 p_x: Optional[float] = None,
                 p_y: Optional[float] = None,
                 p_z: Optional[float] = None,
                 error_probabilities: Optional[Dict[str, float]] = None,
                 tol: float = 1e-8) -> None:
        r"""The asymmetric depolarizing channel.

        This channel applies one of 4**n disjoint possibilities: nothing (the
        identity channel) or one of the 4**n - 1 pauli gates.

        This channel evolves a density matrix via

            $$
            \sum_i p_i Pi \rho Pi
            $$

        where i varies from 0 to 4**n-1 and Pi represents n-qubit Pauli operator
        (including identity). The input $\rho$ is the density matrix before the
        depolarization.

        Args:
            p_x: The probability that a Pauli X and no other gate occurs.
            p_y: The probability that a Pauli Y and no other gate occurs.
            p_z: The probability that a Pauli Z and no other gate occurs.
            error_probabilities: Dictionary of string (Pauli operator) to its
                probability. If the identity is missing from the list, it will
                be added so that the total probability mass is 1.
            tol: The tolerance used making sure the total probability mass is
                equal to 1.

        Examples of calls:
            * Single qubit: AsymmetricDepolarizingChannel(0.2, 0.1, 0.3)
            * Single qubit: AsymmetricDepolarizingChannel(p_z=0.3)
            * Two qubits: AsymmetricDepolarizingChannel(
                                error_probabilities={'XX': 0.2})

        Raises:
            ValueError: if the args or the sum of args are not probabilities.
        """
        if error_probabilities:
            num_qubits = len(list(error_probabilities)[0])
            for k in error_probabilities.keys():
                if not set(k).issubset({'I', 'X', 'Y', 'Z'}):
                    raise ValueError(f"{k} is not made solely of I, X, Y, Z.")
                if len(k) != num_qubits:
                    raise ValueError(
                        f"{k} must have {num_qubits} Pauli gates.")
            for k, v in error_probabilities.items():
                value.validate_probability(v, f"p({k})")
            sum_probs = sum(error_probabilities.values())
            identity = 'I' * num_qubits
            if sum_probs < 1.0 - tol and identity not in error_probabilities:
                error_probabilities[identity] = 1.0 - sum_probs
            elif abs(sum_probs - 1.0) > tol:
                raise ValueError(
                    f"Probabilities do not add up to 1 but to {sum_probs}")
            self._num_qubits = num_qubits
            self._error_probabilities = error_probabilities
        else:
            p_x = 0.0 if p_x is None else p_x
            p_y = 0.0 if p_y is None else p_y
            p_z = 0.0 if p_z is None else p_z

            p_x = value.validate_probability(p_x, 'p_x')
            p_y = value.validate_probability(p_y, 'p_y')
            p_z = value.validate_probability(p_z, 'p_z')
            p_i = 1 - value.validate_probability(p_x + p_y + p_z,
                                                 'p_x + p_y + p_z')

            self._num_qubits = 1
            self._error_probabilities = {
                'I': p_i,
                'X': p_x,
                'Y': p_y,
                'Z': p_z
            }
Exemple #6
0
    def __init__(
            self,
            p_x: Optional[float] = None,
            p_y: Optional[float] = None,
            p_z: Optional[float] = None,
            error_probabilities: Optional[Dict[str, float]] = None) -> None:
        r"""The asymmetric depolarizing channel.

        This channel applies one of 4**n disjoint possibilities: nothing (the
        identity channel) or one of the 4**n - 1 pauli gates.

        This channel evolves a density matrix via

            $$
            \sum_i p_i Pi \rho Pi
            $$

        where i varies from 0 to 4**n-1 and Pi represents n-qubit Pauli operator
        (including identity). The input \rho is the density matrix before the
        depolarization.

        Args:
            p_x: The probability that a Pauli X and no other gate occurs.
            p_y: The probability that a Pauli Y and no other gate occurs.
            p_z: The probability that a Pauli Z and no other gate occurs.
            error_probabilities: Dictionary of string (Pauli operator) to its
                probability

        Examples of calls:
            * Single qubit: AsymmetricDepolarizingChannel(0.2, 0.1, 0.3)
            * Single qubit: AsymmetricDepolarizingChannel(p_z=0.3)
            * Two qubits: AsymmetricDepolarizingChannel(
                                error_probabilities={'XX': 0.2})

        Raises:
            ValueError: if the args or the sum of args are not probabilities.
        """
        if error_probabilities:
            num_qubits = len(list(error_probabilities)[0])
            for k in error_probabilities.keys():
                if not set(k).issubset({'I', 'X', 'Y', 'Z'}):
                    raise ValueError(f"{k} is not made solely of I, X, Y, Z.")
                if len(k) != num_qubits:
                    raise ValueError(
                        f"{k} must have {num_qubits} Pauli gates.")
            for k, v in error_probabilities.items():
                value.validate_probability(v, f"p({k})")
            value.validate_probability(sum(error_probabilities.values()),
                                       'sum(error_probabilities)')
            self._num_qubits = num_qubits
            self._error_probabilities = error_probabilities
        else:
            p_x = 0.0 if p_x is None else p_x
            p_y = 0.0 if p_y is None else p_y
            p_z = 0.0 if p_z is None else p_z

            p_x = value.validate_probability(p_x, 'p_x')
            p_y = value.validate_probability(p_y, 'p_y')
            p_z = value.validate_probability(p_z, 'p_z')
            p_i = 1 - value.validate_probability(p_x + p_y + p_z,
                                                 'p_x + p_y + p_z')

            self._num_qubits = 1
            self._error_probabilities = {
                'I': p_i,
                'X': p_x,
                'Y': p_y,
                'Z': p_z
            }
    def __init__(self, p_xi: float, p_yi: float, p_zi: float, p_xx: float,
                 p_yx: float, p_zx: float, p_xy: float, p_yy: float,
                 p_zy: float, p_xz: float, p_yz: float, p_zz: float,
                 p_ix: float, p_iy: float, p_iz: float) -> None:
        r"""The asymmetric depolarizing channel.

            This channel applies one of 16 disjoint possibilities: nothing (the
            identity channel) or a combination of the three pauli gates and the identity on each  of two qubits.
            The disjoint probabilities of the 15 gates are p_xi, p_xx, and p_xy, p_xz, and so on.
            The identity is done with probability 1 - sum(p_jk), where j is the operation on the first qubit and k is the operation on the second.
            The supplied probabilities must be valid probabilities and the sum p_jk
            must be a valid probability or else this constructor will raise a
            ValueError.

            This channel evolves a density matrix via

                $$
                \rho \rightarrow (1 - \Sum_{jk} p_jk) \rho
                        + \Sum_{jk} p_jk j \otimes k
                $$

            Args:
                p_xi: The probability that a Pauli X on qubit 1 and no other gate occurs.
                p_yi: The probability that a Pauli Y on qubit 1 and no other gate occurs.
                p_zi: The probability that a Pauli Z on qubit 1 and no other gate occurs.
                p_xx: The probability that a Pauli X on qubit 1 and a Pauli X on qubit 2 occurs.
                p_yx: The probability that a Pauli Y on qubit 1 and a Pauli Y on qubit 2 occurs.
                p_zx: The probability that a Pauli Z on qubit 1 and a Pauli Z on qubit 2 occurs.
                p_xy: The probability that a Pauli X on qubit 1 and a Pauli X on qubit 2 occurs.
                p_yy: The probability that a Pauli Y on qubit 1 and a Pauli Y on qubit 2 occurs.
                p_zy: The probability that a Pauli Z on qubit 1 and a Pauli Z on qubit 2 occurs.
                p_xz: The probability that a Pauli X on qubit 1 and a Pauli X on qubit 2 occurs.
                p_yz: The probability that a Pauli Y on qubit 1 and a Pauli Y on qubit 2 occurs.
                p_zz: The probability that a Pauli Z on qubit 1 and a Pauli Z on qubit 2 occurs.

            Raises:
                ValueError: if the args or the sum of args are not probabilities.
        """
        self._p_xi = value.validate_probability(p_xi, 'p_xi')
        self._p_yi = value.validate_probability(p_yi, 'p_yi')
        self._p_zi = value.validate_probability(p_zi, 'p_zi')
        self._p_xx = value.validate_probability(p_xx, 'p_xx')
        self._p_yx = value.validate_probability(p_yx, 'p_yx')
        self._p_zx = value.validate_probability(p_zx, 'p_zx')
        self._p_xy = value.validate_probability(p_xy, 'p_xy')
        self._p_yy = value.validate_probability(p_yy, 'p_yy')
        self._p_zy = value.validate_probability(p_zy, 'p_zy')
        self._p_xz = value.validate_probability(p_xz, 'p_xz')
        self._p_yz = value.validate_probability(p_yz, 'p_yz')
        self._p_zz = value.validate_probability(p_zz, 'p_zz')
        self._p_ix = value.validate_probability(p_ix, 'p_ix')
        self._p_iy = value.validate_probability(p_iy, 'p_iy')
        self._p_iz = value.validate_probability(p_iz, 'p_iz')
        self._p_ii = 1 - value.validate_probability(
            p_xi + p_yi + p_zi + p_xx + p_yx + p_zx + p_xy + p_yy + p_zy +
            p_xz + p_yz + p_zz + p_ix + p_iy + p_iz, 'p_ii')