Source code for mimiqcircuits.operations.noisechannel.standards.projectivenoise

#
# Copyright © 2022-2024 University of Strasbourg. All Rights Reserved.
# Copyright © 2032-2024 QPerfect. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import symengine as se
from mimiqcircuits.operations.krauschannel import krauschannel
import mimiqcircuits as mc


def checknormalizlength(normaliz, length):
    if len(normaliz) != length:
        raise ValueError(f"normaliz must be a list or tuple of length {length}.")


[docs] class ProjectiveNoiseX(krauschannel): r""" ProjectiveNoiseX() Single qubit projection noise onto an X Pauli basis. This channel is defined by the Kraus operators: .. math:: E_1 = |-\rangle \langle-|, \quad E_2 = |+\rangle \langle+|, where :math:`\ket{+}` and :math:`\ket{-}` are the eigenstates of Pauli `X`. See also: - :class:`ProjectiveNoise` - :class:`ProjectiveNoiseY` - :class:`ProjectiveNoiseZ` """ _name = "ProjectiveNoiseX" _num_qubits = 1 _num_bits = 0 _num_zvars = 0 _qregsizes = [1]
[docs] def opname(self): return "ProjectiveNoiseX"
[docs] def krausoperators(self): return [mc.ProjectorX0(), mc.ProjectorX1()]
def __str__(self): return f"{self._name}"
[docs] class ProjectiveNoiseY(krauschannel): r""" ProjectiveNoiseY() Single qubit projection noise onto a Y Pauli basis. This channel is defined by the Kraus operators: .. math:: E_1 = |Y0\rangle \langle Y0|, \quad E_2 = |Y1\rangle \langle Y1|, where :math:`\ket{Y0}` and :math:`\ket{Y1}` are the eigenstates of Pauli `Y`. See also: - :class:`ProjectiveNoise` - :class:`ProjectiveNoiseX` - :class:`ProjectiveNoiseZ` """ _name = "ProjectiveNoiseY" _num_qubits = 1 _num_bits = 0 _num_zvars = 0 _qregsizes = [1]
[docs] def opname(self): return "ProjectiveNoiseY"
[docs] def krausoperators(self): return [mc.ProjectorY0(), mc.ProjectorY1()]
def __str__(self): return f"{self._name}"
[docs] class ProjectiveNoiseZ(krauschannel): r""" ProjectiveNoiseZ() Single qubit projection noise onto a Z Pauli basis. This channel is defined by the Kraus operators: .. math:: E_1 = |0\rangle \langle Z0|, \quad E_2 = |1\rangle \langle Z1|, where :math:`\ket{0}` and :math:`\ket{1}` are the eigenstates of Pauli `Z`. See also: - :class:`ProjectiveNoise` - :class:`ProjectiveNoiseX` - :class:`ProjectiveNoiseY` """ _name = "ProjectiveNoiseZ" _num_qubits = 1 _num_bits = 0 _num_zvars = 0 _qregsizes = [1]
[docs] def opname(self): return "ProjectiveNoiseZ"
def __str__(self): return f"{self._name}"
[docs] def krausoperators(self): return [mc.Projector0(), mc.Projector1()]
[docs] class ProjectiveNoise(krauschannel): r""" ProjectiveNoise(basis) Single qubit projection noise onto a Pauli basis. This channel is defined by the Kraus operators: .. math:: E_1 = |\alpha\rangle \langle\alpha|, \quad E_2 = |\beta\rangle \langle\beta|, where the states :math:`|\alpha\rangle` and :math:`|\beta\rangle` are the +1 and -1 eigenstates of a Pauli operator. Specifically, they correspond to :math:`\{ |0\rangle, |1\rangle \}` (Z basis), :math:`\{ |+\rangle, |-\rangle \}` (X basis), or :math:`\{ |y+\rangle, |y-\rangle \}` (Y basis). This operation is similar to measuring in the corresponding basis (X, Y, or Z), except that the outcome of the measurement is not stored, i.e., there is a loss of information. Parameters: basis (str): String or character that selects the Pauli basis, `"X"`, `"Y"`, or `"Z"`. Examples: >>> from mimiqcircuits import * >>> c = Circuit() >>> c.push(ProjectiveNoise("Z"), 1) 2-qubit circuit with 1 instructions: └── ProjectiveNoiseZ @ q[1] <BLANKLINE> The Kraus matrices are given by: >>> ProjectiveNoise("X").krausmatrices() [[0.5, 0.5] [0.5, 0.5] , [0.5, -0.5] [-0.5, 0.5] ] >>> ProjectiveNoise("Y").krausmatrices() [[0.5, -0.0 - 0.5*I] [0.0 + 0.5*I, 0.5] , [0.5, 0.0 + 0.5*I] [-0.0 - 0.5*I, 0.5] ] >>> ProjectiveNoise("Z").krausmatrices() [[1.0, 0] [0, 0] , [0, 0] [0, 1.0] ] """ _name = "ProjectiveNoise" _num_qubits = 1 _qregsizes = [1] _cregsizes = () def __new__(self, basis="Z"): if basis == "X": return ProjectiveNoiseX() elif basis == "Y": return ProjectiveNoiseY() elif basis == "Z": return ProjectiveNoiseZ() else: raise ValueError( "Invalid basis for Projective noise. Must be 'X', 'Y', or 'Z'." )
[docs] def krausmatrices(self): return [se.Matrix(kraus.matrix().tolist()) for kraus in self.krausoperators()]
def __str__(self): return f"{self._name}"
__all__ = [ "ProjectiveNoise", "ProjectiveNoiseX", "ProjectiveNoiseY", "ProjectiveNoiseZ", ]