#
# 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.
#
from mimiqcircuits.operations.operation import Operation
import mimiqcircuits as mc
[docs]
class AbstractMeasurement(Operation):
_name = "AbstractMeasurement"
[docs]
def iswrapper(self):
return False
def __str__(self):
return self._name
[docs]
class Measure(AbstractMeasurement):
"""Measure operation.
This operation performs a measurement in the computational basis (Z-basis) and stores the result in a classical register.
The measurement projects the quantum state onto either the :math:`|0⟩` or :math:`|1⟩` state, corresponding to the classical bit values of 0 and 1, respectively.
.. warning::
`Measure` is non-reversible.
Examples:
Adding Measure operation to the Circuit (The qubits (first arg) and the bits (second arg) can be: range, list, tuple, set or int)
>>> from mimiqcircuits import *
>>> c= Circuit()
>>> c.push(Measure(),0,0)
1-qubit circuit with 1 instructions:
└── M @ q[0], c[0]
<BLANKLINE>
>>> from mimiqcircuits import *
>>> c= Circuit()
>>> c.push(Measure(), range(0,3), range(0,3))
3-qubit circuit with 3 instructions:
├── M @ q[0], c[0]
├── M @ q[1], c[1]
└── M @ q[2], c[2]
<BLANKLINE>
"""
_name = "M"
_num_bits = 1
_num_qubits = 1
_num_cregs = 1
_qregsizes = [1]
_cregsizes = [1]
_num_zvars = 0
[docs]
def inverse(self):
raise TypeError("Measure is not inversible")
[docs]
def power(self, p):
raise TypeError("Measure^p is not defined.")
[docs]
def control(self, num_qubits):
raise TypeError("Controlled Measure is not defined.")
[docs]
def iswrapper(self):
return False
[docs]
def get_operation(self):
return self
[docs]
class MeasureX(AbstractMeasurement):
r"""Single qubit measurement operation in the X-basis.
This operation projects the quantum state onto the X-basis and stores the result of such
measurement in a classical register. The measurement is performed by first applying a Hadamard
gate to rotate the qubit's state into the computational basis, performing a standard Z-basis
measurement, and then applying another Hadamard gate to return the qubit to its original basis.
.. warning::
`MeasureX` is non-reversible.
See Also:
:class:`Measure`, :class:`MeasureY`, :class:`MeasureZ`, :class:`Operation`, :class:`Reset`
Examples:
>>> from mimiqcircuits import *
>>> MeasureX()
MX
>>> c = Circuit()
>>> c.push(MeasureX(), 2, 1)
3-qubit circuit with 1 instructions:
└── MX @ q[2], c[1]
<BLANKLINE>
>>> c.push(MeasureX(), 3, 4)
4-qubit circuit with 2 instructions:
├── MX @ q[2], c[1]
└── MX @ q[3], c[4]
<BLANKLINE>
"""
_name = "MX"
_num_bits = 1
_num_qubits = 1
_num_cregs = 1
_qregsizes = [1]
_cregsizes = [1]
_num_zvars = 0
[docs]
def inverse(self):
raise TypeError("MeasureX is not inversible")
[docs]
def power(self, p):
raise TypeError("MeasureX^p is not defined.")
[docs]
def control(self, num_qubits):
raise TypeError("Controlled MeasureX is not defined.")
[docs]
def iswrapper(self):
return False
[docs]
def get_operation(self):
return self
def _decompose(self, circ, qubits, bits, zvars):
q = qubits[0]
b = bits[0]
circ.push(mc.GateH(), q)
circ.push(Measure(), q, b)
circ.push(mc.GateH(), q)
return circ
[docs]
class MeasureY(AbstractMeasurement):
r"""Single qubit measurement operation in the Y-basis.
This operation projects the quantum state onto the Y-basis and stores the result of such
measurement in a classical register. The measurement is performed by first applying a :math:`R_y(\pi/2)`
rotation gate to rotate the qubit's state into the computational basis, performing a standard Z-basis
measurement, and then applying another :math:`R_y(-\pi/2)` rotation to return the qubit to its original basis.
.. warning::
`MeasureY` is non-reversible.
See Also:
:class:`Measure`, :class:`MeasureX`, :class:`MeasureZ`, :class:`Operation`, :class:`Reset`
Examples:
>>> from mimiqcircuits import *
>>> MeasureY()
MY
>>> c = Circuit()
>>> c.push(MeasureY(), 2, 1)
3-qubit circuit with 1 instructions:
└── MY @ q[2], c[1]
<BLANKLINE>
>>> c.push(MeasureY(), 3, 4)
4-qubit circuit with 2 instructions:
├── MY @ q[2], c[1]
└── MY @ q[3], c[4]
<BLANKLINE>
"""
_name = "MY"
_num_bits = 1
_num_qubits = 1
_num_cregs = 1
_qregsizes = [1]
_cregsizes = [1]
_num_zvars = 0
[docs]
def inverse(self):
raise TypeError("MeasureY is not inversible")
[docs]
def power(self, p):
raise TypeError("MeasureY^p is not defined.")
[docs]
def control(self, num_qubits):
raise TypeError("Controlled MeasureY is not defined.")
[docs]
def iswrapper(self):
return False
[docs]
def get_operation(self):
return self
def _decompose(self, circ, qubits, bits, zvars):
q = qubits[0]
b = bits[0]
circ.push(mc.GateHYZ(), q)
circ.push(Measure(), q, b)
circ.push(mc.GateHYZ(), q)
return circ
[docs]
class MeasureZ(AbstractMeasurement):
r"""Single qubit measurement operation in the Z-basis.
This class returns an instance of the :class:`Measure` operation, effectively acting as an alias for Z-basis measurement.
.. warning::
`MeasureZ` is non-reversible.
See Also:
:class:`Measure`, :class:`MeasureX`, :class:`MeasureY`, :class:`Operation`, :class:`Reset`
Examples:
>>> from mimiqcircuits import *
>>> MeasureZ()
M
>>> c = Circuit()
>>> c.push(MeasureZ(), 0, 0)
1-qubit circuit with 1 instructions:
└── M @ q[0], c[0]
<BLANKLINE>
>>> c.push(MeasureZ(), 1, 2)
2-qubit circuit with 2 instructions:
├── M @ q[0], c[0]
└── M @ q[1], c[2]
<BLANKLINE>
"""
def __new__(self):
return Measure()
# export operations
__all__ = ["Measure", "MeasureX", "MeasureY", "MeasureZ"]