From c5600092354b90ac635c4b09715e8c4c87c19b00 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Mon, 23 Mar 2020 00:06:15 -0400 Subject: [PATCH 01/38] docs for x.py --- qiskit/extensions/standard/x.py | 235 +++++++++++++++++++------------- tox.ini | 2 +- 2 files changed, 145 insertions(+), 92 deletions(-) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index c5cd3dc57b1a..94f7f0352cf1 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Pauli X (bit-flip) gate. +X, CX and CCX gates. """ import numpy from qiskit.circuit import ControlledGate @@ -28,17 +28,48 @@ class XGate(Gate): - """Pauli X (bit-flip) gate.""" + r"""The single-qubit Pauli-X gate (:math:`\sigma_x`). + + .. math:: + + X = \begin{pmatrix} + 0 & 1 \\ + 1 & 0 + \end{pmatrix} + + Equivalent to a :math:`\pi` radian rotation about the X axis (note a global + phase difference in the definitions of :math:`RX(\pi)` and :math:`X`). + + .. math:: + + RX(\pi) = \begin{pmatrix} + 0 & -i \\ + -i & 0 + \end{pmatrix} + = -i.X + + Circuit symbol: + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ X ├ + └───┘ + + The gate is equivalent to a classical bit flip. + + .. math:: + + |0\rangle \rightarrow |1\rangle \\ + |1\rangle \rightarrow |0\rangle + """ def __init__(self, label=None): - """Create new X gate.""" super().__init__('x', 1, [], label=label) def _define(self): """ - gate x a { - u3(pi,0,pi) a; - } + gate x a { u3(pi,0,pi) a; } """ from qiskit.extensions.standard.u3 import U3Gate definition = [] @@ -51,7 +82,9 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-X gate. + + One control returns a CX gate. Two controls returns a CCX gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -71,7 +104,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + r"""Return inverted X gate (:math:`X{\dagger} = X`)""" return XGate() # self-inverse def to_matrix(self): @@ -82,31 +115,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def x(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply X gate to a specified qubit (qubit). - - An X gate implements a :math:`\\pi` rotation of the qubit state vector about - the x axis of the Bloch sphere. This gate is canonically used to implement - a bit flip on the qubit state from :math:`|0\\rangle` to :math:`|1\\rangle`, - or vice versa. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.x(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.x import XGate - XGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.XGate`. """ return self.append(XGate(), [qubit], []) @@ -125,15 +134,60 @@ def __instancecheck__(mcs, inst): class CXGate(ControlledGate, metaclass=CXMeta): - """The controlled-X gate.""" + r"""CX gate, also known as controlled-NOT or CNOT gate. + + Circuit symbol: + + .. parsed-literal:: + + q_0: ──■── + ┌─┴─┐ + q_1: ┤ X ├ + └───┘ + + Matrix representation: + + .. math:: + + CX 0, 1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 1 \\ + 0 & 0 & 1 & 0 \\ + 0 & 1 & 0 & 0 + \end{pmatrix} + + .. note:: + + In Qiskit's convention, lower qubit indices are less significant + (little endian). Textbook representations of CX matrix implicitly + assume the more significant qubit to be the control. So in order to + get such a matrix in Qiskit, the higher-index qubit must be the control. + + .. math:: + + CX 1, 0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 1 \\ + 0 & 0 & 1 & 0 + \end{pmatrix} + + In the computational basis, this gate flips the target qubit + if the control qubit is in the :math:`|1\rangle` state. + In this sense it is similar to a classical XOR gate. + + .. math:: + `|a, b\rangle \rightarrow |a, a \oplus b\rangle` + """ def __init__(self): - """Create new cx gate.""" super().__init__('cx', 2, [], num_ctrl_qubits=1) self.base_gate = XGate() def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a controlled-X gate with more control lines. Args: num_ctrl_qubits (int): number of control qubits. @@ -151,7 +205,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + """Return inverted CX gate (:math:`CX^{\dagger} = CX`)""" return CXGate() # self-inverse def to_matrix(self): @@ -178,33 +232,7 @@ def __init__(self): 'tgt': 'target_qubit'}) def cx(self, control_qubit, target_qubit, # pylint: disable=invalid-name *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply CX gate - - From a specified control ``control_qubit`` to target ``target_qubit`` qubit. - A CX gate implements a :math:`\\pi` rotation of the qubit state vector about - the x axis of the Bloch sphere when the control qubit is in state :math:`|1\\rangle` - This gate is canonically used to implement a bit flip on the qubit state from - :math:`|0\\rangle` to :math:`|1\\rangle`, or vice versa when the control qubit is in - :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.cx(0,1) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.x import CXGate - CXGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.CXGate`. """ return self.append(CXGate(), [control_qubit, target_qubit], []) @@ -225,10 +253,58 @@ def __instancecheck__(mcs, inst): class CCXGate(ControlledGate, metaclass=CCXMeta): - """The double-controlled-not gate, also called Toffoli gate.""" + r"""CCX gate, also known as Toffoli gate. + + Circuit symbol: + + .. parsed-literal:: + + q_0: ──■── + │ + q_1: ──■── + ┌─┴─┐ + q_2: ┤ X ├ + └───┘ + + Matrix representation: + + .. math:: + + CX 0, 1, 2 = + \begin{pmatrix} + 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ + 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ + 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ + 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 + \end{pmatrix} + + .. note:: + + In Qiskit's convention, lower qubit indices are less significant + (little endian). Textbook representations of CCX matrix implicitly + assume the more significant qubits to be the controls. So in order to + get such a matrix in Qiskit, the higher-index qubits must be the controls. + + .. math:: + + CCX 2, 1, 0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ + 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ + 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\ + 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 + \end{pmatrix} + """ def __init__(self): - """Create new CCX gate.""" super().__init__('ccx', 3, [], num_ctrl_qubits=2) self.base_gate = XGate() @@ -265,7 +341,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return an inverted CCX gate (also a CCX).""" return CCXGate() # self-inverse def to_matrix(self): @@ -297,30 +373,7 @@ def __init__(self): 'tgt': 'target_qubit'}) def ccx(self, control_qubit1, control_qubit2, target_qubit, *, ctl1=None, ctl2=None, tgt=None): # pylint: disable=unused-argument - """Apply Toffoli (ccX) gate - - From two specified controls ``(control_qubit1 and control_qubit2)`` to target ``target_qubit`` - qubit. This gate is canonically used to rotate the qubit state from :math:`|0\\rangle` to - :math:`|1\\rangle`, or vice versa when both the control qubits are in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(3) - circuit.ccx(0,1,2) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.x import CCXGate - CCXGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.CCXGate` (Toffoli). """ return self.append(CCXGate(), diff --git a/tox.ini b/tox.ini index 7e4a6bde2cd7..dfc0d272c919 100644 --- a/tox.ini +++ b/tox.ini @@ -43,4 +43,4 @@ deps = qiskit-aer qiskit-ibmq-provider commands = - sphinx-build -W -b html docs/ docs/_build/html {posargs} + sphinx-build -b html docs/ docs/_build/html {posargs} From 907fdd9fe88b32815fa8ecc42fef553eb1672d5b Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Mon, 23 Mar 2020 09:33:39 -0400 Subject: [PATCH 02/38] update rzz docstring --- qiskit/extensions/standard/iswap.py | 30 +++--------- qiskit/extensions/standard/rzz.py | 74 +++++++++++++++++++++++++++-- qiskit/extensions/standard/x.py | 47 ++++++++++-------- 3 files changed, 103 insertions(+), 48 deletions(-) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index 7e1c3daf29ae..e645d616e037 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -30,13 +30,13 @@ class iSwapGate(Gate): states and phase the :math:`|01\rangle` and :math:`|10\rangle` amplitudes by i. - .. parsed-literal:: + Circuit Symbol: - ┌───┐┌───┐ ┌───┐ - q_0: ┤ S ├┤ H ├──■──┤ X ├───── - ├───┤└───┘┌─┴─┐└─┬─┘┌───┐ - q_1: ┤ S ├─────┤ X ├──■──┤ H ├ - └───┘ └───┘ └───┘ + .. parsed-literal:: + + q_0: ─⨂─ + │ + q_1: ─⨂─ .. math:: @@ -98,24 +98,6 @@ def to_matrix(self): def iswap(self, qubit1, qubit2): """Apply iSWAP gate to a pair specified qubits (qubit1, qubit2). - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.iswap(0,1) - circuit.draw() - - .. jupyter-execute:: - - from qiskit.extensions.standard.iswap import iSwapGate - from qiskit.quantum_info import Operator - Operator(iSwapGate()).data """ return self.append(iSwapGate(), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index 00f7e322754a..0df8dac78e51 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -15,16 +15,74 @@ """ Two-qubit ZZ-rotation gate. """ +import numpy as np from qiskit.circuit import Gate from qiskit.circuit import QuantumCircuit from qiskit.circuit import QuantumRegister class RZZGate(Gate): - """The two-qubit ZZ-rotation gate.""" + r"""A parameteric 2-qubit :math:`Z \otimes Z` interaction (rotation about ZZ). + + This gate is symmetric, and is maximally entangling at :math:`\theta = \pi/2`. + + **Matrix Representation:** + + .. math:: + + RZZ(\theta) = exp(-i\frac{\theta}{2}Z{\otimes}Z) = + \begin{pmatrix} + e^{-i\frac{\theta}{2}} & 0 & 0 & 0 \\ + 0 & e^{i\frac{\theta}{2}} & 0 & 0 \\ + 0 & 0 & e^{i\frac{\theta}{2}} & 0 \\ + 0 & 0 & 0 & e^{-i\frac{\theta}{2}} + \end{pmatrix} + + This is a direct sum of RZ rotations, so this gate is equivalent to a + uniformly controlled (multiplexed) RZ gate: + + .. math:: + + RZZ(\theta) = + \begin{pmatrix} + RZ(\theta) & 0 \\ + 0 & RZ(-\theta) + \end{pmatrix} + + **Circuit Symbol:** + + .. parsed-literal:: + + q_0: ───■──── + │zz(θ) + q_1: ───■──── + + **Examples:** + + .. math:: + + RZZ(\theta = 0) = I + + .. math:: + + RZZ(\theta = 2\pi) = -I + + .. math:: + + RZZ(\theta = \pi) = - Z \otimes Z + + .. math:: + + RZZ(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1-i & 0 & 0 & 0 \\ + 0 & 1+i & 0 & 0 \\ + 0 & 0 & 1+i & 0 \\ + 0 & 0 & 0 & 1-i + \end{pmatrix} + """ def __init__(self, theta): - """Create new rzz gate.""" super().__init__('rzz', 2, [theta]) def _define(self): @@ -45,9 +103,19 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RZZ gate (i.e. with the negative rotation angle).""" return RZZGate(-self.params[0]) + # TODO: this is the correct definition but has a global phase with respect + # to the decomposition above. Restore after allowing phase on circuits. + # def to_matrix(self): + # """Return a numpy.array for the RZZ gate.""" + # theta = self.params[0] + # return np.array([[np.exp(-1j*theta/2), 0, 0, 0], + # [0, np.exp(1j*theta/2), 0, 0], + # [0, 0, np.exp(1j*theta/2), 0], + # [0, 0, 0, np.exp(-1j*theta/2)]], dtype=complex) + def rzz(self, theta, qubit1, qubit2): """Apply RZZ to circuit.""" diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 94f7f0352cf1..a81917e5474d 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -30,6 +30,8 @@ class XGate(Gate): r"""The single-qubit Pauli-X gate (:math:`\sigma_x`). + **Matrix Representation:** + .. math:: X = \begin{pmatrix} @@ -37,18 +39,7 @@ class XGate(Gate): 1 & 0 \end{pmatrix} - Equivalent to a :math:`\pi` radian rotation about the X axis (note a global - phase difference in the definitions of :math:`RX(\pi)` and :math:`X`). - - .. math:: - - RX(\pi) = \begin{pmatrix} - 0 & -i \\ - -i & 0 - \end{pmatrix} - = -i.X - - Circuit symbol: + **Circuit symbol:** .. parsed-literal:: @@ -56,10 +47,24 @@ class XGate(Gate): q_0: ┤ X ├ └───┘ + Equivalent to a :math:`\pi` radian rotation about the X axis. + + .. note:: + A global phase difference exists between the definitions of + :math:`RX(\pi)` and :math:`X`. + + .. math:: + + RX(\pi) = \begin{pmatrix} + 0 & -i \\ + -i & 0 + \end{pmatrix} + = -i.X + The gate is equivalent to a classical bit flip. .. math:: - + |0\rangle \rightarrow |1\rangle \\ |1\rangle \rightarrow |0\rangle """ @@ -136,16 +141,16 @@ def __instancecheck__(mcs, inst): class CXGate(ControlledGate, metaclass=CXMeta): r"""CX gate, also known as controlled-NOT or CNOT gate. - Circuit symbol: + **Circuit symbol:** .. parsed-literal:: - + q_0: ──■── ┌─┴─┐ q_1: ┤ X ├ └───┘ - Matrix representation: + **Matrix representation:** .. math:: @@ -179,7 +184,7 @@ class CXGate(ControlledGate, metaclass=CXMeta): In this sense it is similar to a classical XOR gate. .. math:: - `|a, b\rangle \rightarrow |a, a \oplus b\rangle` + `|a, b\rangle \rightarrow |a, a \oplus b\rangle` """ def __init__(self): @@ -255,18 +260,18 @@ def __instancecheck__(mcs, inst): class CCXGate(ControlledGate, metaclass=CCXMeta): r"""CCX gate, also known as Toffoli gate. - Circuit symbol: + **Circuit symbol:** .. parsed-literal:: - + q_0: ──■── - │ + │ q_1: ──■── ┌─┴─┐ q_2: ┤ X ├ └───┘ - Matrix representation: + **Matrix representation:** .. math:: From ce540232ddbe9356d152376e32ab2e60aa1421d0 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Tue, 24 Mar 2020 14:41:30 -0400 Subject: [PATCH 03/38] dcx docs --- qiskit/extensions/standard/dcx.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/qiskit/extensions/standard/dcx.py b/qiskit/extensions/standard/dcx.py index 3e8e6664c81c..a28aa4704ea8 100644 --- a/qiskit/extensions/standard/dcx.py +++ b/qiskit/extensions/standard/dcx.py @@ -40,7 +40,7 @@ class DCXGate(Gate): .. math:: - DCX = + DCX 0, 1 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ @@ -73,26 +73,6 @@ def to_matrix(self): def dcx(self, qubit1, qubit2): """Apply DCX gate to a pair specified qubits (qubit1, qubit2). - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.dcx(0, 1) - print(circuit) - print(circuit.decompose()) - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.dcx import DCXGate - DCXGate().to_matrix() """ return self.append(DCXGate(), [qubit1, qubit2], []) From 9eba3d1ea678076cbb8575c8a44620d888a26d39 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Tue, 24 Mar 2020 21:54:35 -0400 Subject: [PATCH 04/38] add RZXGate --- qiskit/extensions/__init__.py | 1 + qiskit/extensions/standard/__init__.py | 1 + qiskit/extensions/standard/rzx.py | 141 +++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 qiskit/extensions/standard/rzx.py diff --git a/qiskit/extensions/__init__.py b/qiskit/extensions/__init__.py index d13fd4d39e06..392fbbcb12e9 100644 --- a/qiskit/extensions/__init__.py +++ b/qiskit/extensions/__init__.py @@ -45,6 +45,7 @@ RYGate RZGate RZZGate + RZXGate SGate SdgGate SwapGate diff --git a/qiskit/extensions/standard/__init__.py b/qiskit/extensions/standard/__init__.py index 4408bc4d12d7..b8292ee57535 100644 --- a/qiskit/extensions/standard/__init__.py +++ b/qiskit/extensions/standard/__init__.py @@ -27,6 +27,7 @@ from .ryy import RYYGate from .rz import RZGate, CRZGate from .rzz import RZZGate +from .rzx import RZXGate from .s import SGate, SdgGate from .swap import SwapGate, CSwapGate from .iswap import iSwapGate diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py new file mode 100644 index 000000000000..0a23bf72f8d1 --- /dev/null +++ b/qiskit/extensions/standard/rzx.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Two-qubit ZX-rotation gate. +""" +import numpy as np +from qiskit.circuit import Gate +from qiskit.circuit import QuantumCircuit +from qiskit.circuit import QuantumRegister + + +class RZXGate(Gate): + r"""A parameteric 2-qubit :math:`Z \otimes X` interaction (rotation about ZX). + + This gate is maximally entangling at :math:`\theta = \pi/2`. + + The cross-resonance gate (CR) for superconducting qubits implements + a ZX interaction (however other terms are also present in an experiment). + + **Matrix Representation:** + + .. math:: + + \newcommand{\ctheta}{\cos(\frac{\theta}{2})} + \newcommand{\stheta}{\sin(\frac{\theta}{2})} + + R_{ZX}(\theta)\ q_0, q_1 = exp(-i.\frac{\theta}{2}.X{\otimes}Z) = + \begin{pmatrix} + \ctheta & 0 & -i\stheta & 0 \\ + 0 & \ctheta & 0 & i\stheta \\ + -i\stheta & 0 & \ctheta & 0 \\ + 0 & i\stheta & 0 & \ctheta + \end{pmatrix} + + R_{ZX}(\theta)\quad q_1, q_0 = exp(-i.\frac{\theta}{2}.Z{\otimes}X) = + \begin{pmatrix} + \ctheta & -i\stheta & 0 & 0 \\ + -i\stheta & \ctheta & 0 & 0 \\ + 0 & 0 & \ctheta & i\stheta \\ + 0 & 0 & i\stheta & \ctheta + \end{pmatrix} + + This is a direct sum of RX rotations, so this gate is equivalent to a + uniformly controlled (multiplexed) RX gate: + + .. math:: + + R_{ZX}(\theta) = + \begin{pmatrix} + RX(\theta) & 0 \\ + 0 & RX(-\theta) + \end{pmatrix} + + **Circuit Symbol:** + + .. parsed-literal:: + + ┌─────────┐ + q_0: ┤0 ├ + │ Rzx(θ) │ + q_1: ┤1 ├ + └─────────┘ + + **Examples:** + + .. math:: + + R_{ZX}(\theta = 0) = I + + .. math:: + + R_{ZX}(\theta = 2\pi) = -I + + .. math:: + + R_{ZX}(\theta = \pi) = -i Z \otimes X + + .. math:: + + RZX(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & -i & 0 & 0 \\ + -i & 1 & 0 & 0 \\ + 0 & 0 & 1 & i \\ + 0 & 0 & i & 1 + \end{pmatrix} + """ + + def __init__(self, theta): + super().__init__('rzx', 2, [theta]) + + def _define(self): + """ + gate rzx(theta) a, b { h b; cx a, b; u1(theta) b; cx a, b; h b;} + """ + from qiskit.extensions.standard.u1 import U1Gate + from qiskit.extensions.standard.h import HGate + from qiskit.extensions.standard.x import CXGate + q = QuantumRegister(2, 'q') + self.definition = [ + (HGate(), [q[1]], []), + (CXGate(), [q[0], q[1]], []), + (U1Gate(self.params[0]), [q[1]], []), + (CXGate(), [q[0], q[1]], []), + (HGate(), [q[1]], []) + ] + + def inverse(self): + """Return inverse RZX gate (i.e. with the negative rotation angle).""" + return RZXGate(-self.params[0]) + + # TODO: this is the correct definition but has a global phase with respect + # to the decomposition above. Restore after allowing phase on circuits. + # def to_matrix(self): + # """Return a numpy.array for the RZX gate.""" + # theta = self.params[0] + # return np.array([[np.exp(-1j*theta/2), 0, 0, 0], + # [0, np.exp(1j*theta/2), 0, 0], + # [0, 0, np.exp(1j*theta/2), 0], + # [0, 0, 0, np.exp(-1j*theta/2)]], dtype=complex) + + +def rzx(self, theta, qubit1, qubit2): + """Apply RZX to circuit.""" + return self.append(RZXGate(theta), [qubit1, qubit2], []) + + +# Add to QuantumCircuit class +QuantumCircuit.rzx = rzx From 74901fe9a955d5931f5d3d7365e0b2bc77427af9 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 00:25:56 -0400 Subject: [PATCH 05/38] polish doc for x,y,z,rzz,rzx,iswap,dcx --- qiskit/extensions/standard/dcx.py | 2 +- qiskit/extensions/standard/iswap.py | 6 +- qiskit/extensions/standard/rzx.py | 58 ++++++----- qiskit/extensions/standard/rzz.py | 20 ++-- qiskit/extensions/standard/x.py | 37 +++---- qiskit/extensions/standard/y.py | 143 ++++++++++++++++++---------- qiskit/extensions/standard/z.py | 136 ++++++++++++++------------ 7 files changed, 235 insertions(+), 167 deletions(-) diff --git a/qiskit/extensions/standard/dcx.py b/qiskit/extensions/standard/dcx.py index a28aa4704ea8..a10bf12159c3 100644 --- a/qiskit/extensions/standard/dcx.py +++ b/qiskit/extensions/standard/dcx.py @@ -72,7 +72,7 @@ def to_matrix(self): def dcx(self, qubit1, qubit2): - """Apply DCX gate to a pair specified qubits (qubit1, qubit2). + """Apply :class:`~qiskit.extensions.standard.DCXGate`. """ return self.append(DCXGate(), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index e645d616e037..f5037d775990 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -33,9 +33,9 @@ class iSwapGate(Gate): Circuit Symbol: .. parsed-literal:: - + q_0: ─⨂─ - │ + │ q_1: ─⨂─ .. math:: @@ -97,7 +97,7 @@ def to_matrix(self): def iswap(self, qubit1, qubit2): - """Apply iSWAP gate to a pair specified qubits (qubit1, qubit2). + """Apply :class:`~qiskit.extensions.standard.iSwapGate`. """ return self.append(iSwapGate(), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index 0a23bf72f8d1..4c5a16cf5724 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -29,27 +29,28 @@ class RZXGate(Gate): The cross-resonance gate (CR) for superconducting qubits implements a ZX interaction (however other terms are also present in an experiment). + **Circuit Symbol:** + + .. parsed-literal:: + + ┌─────────┐ + q_0: ┤1 ├ + │ Rzx(θ) │ + q_1: ┤0 ├ + └─────────┘ + **Matrix Representation:** .. math:: - \newcommand{\ctheta}{\cos(\frac{\theta}{2})} - \newcommand{\stheta}{\sin(\frac{\theta}{2})} + \newcommand{\th}{\frac{\theta}{2}} - R_{ZX}(\theta)\ q_0, q_1 = exp(-i.\frac{\theta}{2}.X{\otimes}Z) = + R_{ZX}(\theta)\ q_1, q_0 = exp(-i.\frac{\theta}{2}.Z{\otimes}X) = \begin{pmatrix} - \ctheta & 0 & -i\stheta & 0 \\ - 0 & \ctheta & 0 & i\stheta \\ - -i\stheta & 0 & \ctheta & 0 \\ - 0 & i\stheta & 0 & \ctheta - \end{pmatrix} - - R_{ZX}(\theta)\quad q_1, q_0 = exp(-i.\frac{\theta}{2}.Z{\otimes}X) = - \begin{pmatrix} - \ctheta & -i\stheta & 0 & 0 \\ - -i\stheta & \ctheta & 0 & 0 \\ - 0 & 0 & \ctheta & i\stheta \\ - 0 & 0 & i\stheta & \ctheta + \cos(\th) & -i\sin(\th) & 0 & 0 \\ + -i\sin(\th) & \cos(\th) & 0 & 0 \\ + 0 & 0 & \cos(\th) & i\sin(\th) \\ + 0 & 0 & i\sin(\th) & \cos(\th) \end{pmatrix} This is a direct sum of RX rotations, so this gate is equivalent to a @@ -57,21 +58,30 @@ class RZXGate(Gate): .. math:: - R_{ZX}(\theta) = + R_{ZX}(\theta)\ q_1, q_0 = \begin{pmatrix} RX(\theta) & 0 \\ 0 & RX(-\theta) \end{pmatrix} - **Circuit Symbol:** + .. note:: - .. parsed-literal:: + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In the above example we apply the gate + on (q_1, q_0) which results in the ZX tensor order. Instead, if we + apply it on (q_0, q_1), the matrix will be: - ┌─────────┐ - q_0: ┤0 ├ - │ Rzx(θ) │ - q_1: ┤1 ├ - └─────────┘ + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + R_{ZX}(\theta)\ q_0, q_1 = exp(-i.\frac{\theta}{2}.X{\otimes}Z) = + \begin{pmatrix} + \cos(\th) & 0 & -i\sin(\th) & 0 \\ + 0 & \cos(\th) & 0 & i\sin(\th) \\ + -i\sin(\th) & 0 & \cos(\th) & 0 \\ + 0 & i\sin(\th) & 0 & \cos(\th) + \end{pmatrix} **Examples:** @@ -133,7 +143,7 @@ def inverse(self): def rzx(self, theta, qubit1, qubit2): - """Apply RZX to circuit.""" + """Apply :class:`~qiskit.extensions.standard.RZXGate`.""" return self.append(RZXGate(theta), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index 0df8dac78e51..b2471c73008b 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -26,11 +26,19 @@ class RZZGate(Gate): This gate is symmetric, and is maximally entangling at :math:`\theta = \pi/2`. + **Circuit Symbol:** + + .. parsed-literal:: + + q_0: ───■──── + │zz(θ) + q_1: ───■──── + **Matrix Representation:** .. math:: - RZZ(\theta) = exp(-i\frac{\theta}{2}Z{\otimes}Z) = + RZZ(\theta) = exp(-i.\frac{\theta}{2}.Z{\otimes}Z) = \begin{pmatrix} e^{-i\frac{\theta}{2}} & 0 & 0 & 0 \\ 0 & e^{i\frac{\theta}{2}} & 0 & 0 \\ @@ -49,14 +57,6 @@ class RZZGate(Gate): 0 & RZ(-\theta) \end{pmatrix} - **Circuit Symbol:** - - .. parsed-literal:: - - q_0: ───■──── - │zz(θ) - q_1: ───■──── - **Examples:** .. math:: @@ -118,7 +118,7 @@ def inverse(self): def rzz(self, theta, qubit1, qubit2): - """Apply RZZ to circuit.""" + """Apply :class:`~qiskit.extensions.standard.RZZGate`.""" return self.append(RZZGate(theta), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index a81917e5474d..5f076346f3cf 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -50,8 +50,9 @@ class XGate(Gate): Equivalent to a :math:`\pi` radian rotation about the X axis. .. note:: - A global phase difference exists between the definitions of - :math:`RX(\pi)` and :math:`X`. + + A global phase difference exists between the definitions of + :math:`RX(\pi)` and :math:`X`. .. math:: @@ -139,44 +140,46 @@ def __instancecheck__(mcs, inst): class CXGate(ControlledGate, metaclass=CXMeta): - r"""CX gate, also known as controlled-NOT or CNOT gate. + r"""Controlled-X gate. **Circuit symbol:** .. parsed-literal:: - q_0: ──■── - ┌─┴─┐ - q_1: ┤ X ├ - └───┘ + ┌───┐ + q_0: |0>┤ X ├ + └─┬─┘ + q_1: |0>──■── + **Matrix representation:** .. math:: - CX 0, 1 = + CX\ q_1, q_0 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ - 0 & 0 & 1 & 0 \\ - 0 & 1 & 0 & 0 + 0 & 0 & 1 & 0 \end{pmatrix} .. note:: - In Qiskit's convention, lower qubit indices are less significant - (little endian). Textbook representations of CX matrix implicitly - assume the more significant qubit to be the control. So in order to - get such a matrix in Qiskit, the higher-index qubit must be the control. + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: .. math:: - CX 1, 0 = + CX\ q_0, q_1 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ - 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ - 0 & 0 & 1 & 0 + 0 & 0 & 1 & 0 \\ + 0 & 1 & 0 & 0 \end{pmatrix} In the computational basis, this gate flips the target qubit diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index 30eeb7473d0c..e69a13f2d65f 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Pauli Y (bit-phase-flip) gate. +Y and CY gates. """ import numpy from qiskit.circuit import Gate @@ -25,7 +25,47 @@ class YGate(Gate): - """Pauli Y (bit-phase-flip) gate.""" + r"""The single-qubit Pauli-Y gate (:math:`\sigma_y`). + + **Matrix Representation:** + + .. math:: + + Y = \begin{pmatrix} + 0 & -i \\ + i & 0 + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ Y ├ + └───┘ + + Equivalent to a :math:`\pi` radian rotation about the Y axis. + + .. note:: + + A global phase difference exists between the definitions of + :math:`RY(\pi)` and :math:`Y`. + + .. math:: + + RY(\pi) = \begin{pmatrix} + 0 & -1 \\ + 1 & 0 + \end{pmatrix} + = -i.Y + + The gate is equivalent to a bit and phase flip. + + .. math:: + + |0\rangle \rightarrow i|1\rangle \\ + |1\rangle \rightarrow -i|0\rangle + """ def __init__(self, label=None): """Create new Y gate.""" @@ -43,7 +83,9 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-Y gate. + + One control returns a CY gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -61,7 +103,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + r"""Return inverted Y gate (:math:`Y{\dagger} = Y`)""" return YGate() # self-inverse def to_matrix(self): @@ -72,31 +114,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def y(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply Y gate to a specified qubit (qubit). - - A Y gate implements a :math:`\\pi` rotation of the qubit state vector about - the y axis of the Bloch sphere. This gate is canonically used to implement - a bit flip and phase flip on the qubit state from :math:`|0\\rangle` to - :math:`i|1\\rangle`, or from :math:`|1\\rangle` to :math:`-i|0\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.y(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.y import YGate - YGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.YGate`.. """ return self.append(YGate(), [qubit], []) @@ -115,8 +133,49 @@ def __instancecheck__(mcs, inst): class CYGate(ControlledGate, metaclass=CYMeta): - """The controlled-Y gate.""" + r"""Controlled-Y gate. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: |0>┤ Y ├ + └─┬─┘ + q_1: |0>──■── + + + **Matrix representation:** + + .. math:: + + CY\ q_1, q_0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & -i \\ + 0 & 0 & i & 0 + \end{pmatrix} + + .. note:: + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + CY\ q_0, q_1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 0 & 0 & -i \\ + 0 & 0 & 1 & 0 \\ + 0 & i & 0 & 0 + \end{pmatrix} + + """ def __init__(self): """Create a new CY gate.""" super().__init__('cy', 2, [], num_ctrl_qubits=1) @@ -141,7 +200,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverted CY gate (:math:`CY^{\dagger} = CY`)""" return CYGate() # self-inverse def to_matrix(self): @@ -168,27 +227,7 @@ def __init__(self): 'tgt': 'target_qubit'}) def cy(self, control_qubit, target_qubit, # pylint: disable=invalid-name *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cY gate - - Applied from a specified control ``control_qubit`` to target ``target_qubit`` qubit. - A cY gate implements a pi rotation of the qubit state vector about the y axis - of the Bloch sphere when the control qubit is in state :math:`|1\\rangle`. - This gate is canonically used to implement a bit flip and phase flip on the qubit state - from :math:`|0\\rangle` to :math:`i|1\\rangle`, or from :math:`|1\\rangle` to - :math:`-i|0\\rangle` when the control qubit is in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.cy(0,1) - circuit.draw() - """ + """Apply :class:`~qiskit.extensions.standard.CYGate`.""" return self.append(CYGate(), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index a5b4c329d9d1..ad161d5b4dd4 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Pauli Z (phase-flip) gate. +Z and CZ gates. """ import numpy from qiskit.circuit import Gate @@ -25,7 +25,47 @@ class ZGate(Gate): - """Pauli Z (phase-flip) gate.""" + r"""The single-qubit Pauli-Z gate (:math:`\sigma_z`). + + **Matrix Representation:** + + .. math:: + + Z = \begin{pmatrix} + 1 & 0 \\ + 0 & -1 + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ Z ├ + └───┘ + + Equivalent to a :math:`\pi` radian rotation about the Z axis. + + .. note:: + + A global phase difference exists between the definitions of + :math:`RZ(\pi)` and :math:`Z`. + + .. math:: + + RZ(\pi) = \begin{pmatrix} + -1 & 0 \\ + 0 & 1 + \end{pmatrix} + = -Z + + The gate is equivalent to a phase flip. + + .. math:: + + |0\rangle \rightarrow |0\rangle \\ + |1\rangle \rightarrow -|1\rangle + """ def __init__(self, label=None): """Create new Z gate.""" @@ -43,7 +83,9 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-Z gate. + + One control returns a CZ gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -61,7 +103,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + r"""Return inverted Z gate (:math:`Z{\dagger} = Z`)""" return ZGate() # self-inverse def to_matrix(self): @@ -72,31 +114,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def z(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply Z gate to a specified qubit (qubit). - - A Z gate implements a :math:`\\pi` rotation of the qubit state vector about - the z axis of the Bloch sphere. This gate is canonically used to implement - a phase flip on the qubit state from :math:`|+\\rangle` to :math:`|-\\rangle`, - or vice versa. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.z(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.z import ZGate - ZGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.ZGate`. """ return self.append(ZGate(), [qubit], []) @@ -115,7 +133,33 @@ def __instancecheck__(mcs, inst): class CZGate(ControlledGate, metaclass=CZMeta): - """The controlled-Z gate.""" + r"""Controlled-Z gate. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: |0>┤ Z ├ + └─┬─┘ + q_1: |0>──■── + + + **Matrix representation:** + + .. math:: + + CZ\ q_1, q_0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & -1 + \end{pmatrix} + + In the computational basis, this gate flips the phase of + the target qubit if the control qubit is in the :math:`|1\rangle` state. + """ def __init__(self, label=None): """Create new CZ gate.""" @@ -140,7 +184,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverted CZ gate (:math:`CZ^{\dagger} = CZ`)""" return CZGate() # self-inverse def to_matrix(self): @@ -167,35 +211,7 @@ def __init__(self): 'tgt': 'target_qubit'}) def cz(self, control_qubit, target_qubit, # pylint: disable=invalid-name *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cZ gate - - From a specified control ``control_qubit`` to target ``target_qubit`` qubit. - A cZ gate implements a :math:`\\pi` rotation of the qubit state vector about - the z axis of the Bloch sphere when the control qubit is in state :math:`|1\\rangle`. - This gate is canonically used to implement a phase flip on the qubit state from - :math:`|+\\rangle` to :math:`|-\\rangle`, or vice versa when the control qubit is in - state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - import numpy - - circuit = QuantumCircuit(2) - circuit.cz(0,1) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.z import CZGate - CZGate().to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.CZGate`.""" return self.append(CZGate(), [control_qubit, target_qubit], []) From 200ac0ea23f04411450fd322dc19bfd4e9c70d1f Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 00:30:57 -0400 Subject: [PATCH 06/38] i gate --- qiskit/extensions/standard/i.py | 43 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/qiskit/extensions/standard/i.py b/qiskit/extensions/standard/i.py index d4e93fdca3dc..9c6af2581674 100644 --- a/qiskit/extensions/standard/i.py +++ b/qiskit/extensions/standard/i.py @@ -37,6 +37,22 @@ class IGate(Gate, metaclass=IMeta): Identity gate corresponds to a single-qubit gate wait cycle, and should not be optimized or unrolled (it is an opaque gate). + + **Matrix Representation:** + + .. math:: + + I = \begin{pmatrix} + 1 & 0 \\ + 0 & 1 + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + ┌───┐ + q_0: ┤ I ├ + └───┘ """ def __init__(self, label=None): @@ -66,32 +82,7 @@ def __init__(self): @deprecate_arguments({'q': 'qubit'}) def i(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply Identity to to a specified qubit ``qubit``. - - The Identity gate ensures that nothing is applied to a qubit for one unit - of gate time. It leaves the quantum states :math:`|0\\rangle` and - :math:`|1\\rangle` unchanged. The Identity gate should not be optimized or - unrolled (it is an opaque gate). - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.id(0) # or circuit.i(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.i import IGate - IGate().to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.IGate`.""" return self.append(IGate(), [qubit], []) From 8d3c1509d7e91163fa65301a6b107e1d5b2bb7db Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 02:12:28 -0400 Subject: [PATCH 07/38] u1 and rz docs --- qiskit/extensions/standard/rz.py | 116 ++++++++++++++++++++------- qiskit/extensions/standard/u1.py | 130 ++++++++++++++++++------------- qiskit/extensions/standard/y.py | 5 +- qiskit/extensions/standard/z.py | 1 - 4 files changed, 164 insertions(+), 88 deletions(-) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index 0b595605c541..ea9b15e25c1f 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -23,10 +23,42 @@ class RZGate(Gate): - """The rotation around the z-axis.""" + r"""Single-qubit rotation about the Z axis. + This is a diagonal gate. It can be implemented virtually in hardware + via framechanges (i.e. at zero error and duration). + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ Rz(λ) ├ + └───────┘ + + **Matrix Representation:** + + .. math:: + + RZ(\lambda) = + \begin{pmatrix} + e^{-i\frac{\lambda}{2}} & 0 \\ + 0 & e^{i\frac{\lambda}{2}} + \end{pmatrix} + + .. seealso:: + + :class:`~qiskit.extensions.standard.U1Gate` + This gate is equivalent to U1 up to a phase factor. + + .. math:: + + U1(\lambda) = e^{i.{\lambda}/2}.RZ(\lambda) + + Reference for virtual Z gate implementation: + `1612.00858 `_ + """ def __init__(self, phi): - """Create new RZ single qubit gate.""" super().__init__('rz', 1, [phi]) def _define(self): @@ -44,7 +76,7 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-RZ gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -62,34 +94,13 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate. - - rz(phi)^dagger = rz(-phi) - """ + r"""Return inverted RZ gate (:math:`RZ(\lambda){\dagger} = RZ(-\lambda)`)""" return RZGate(-self.params[0]) @deprecate_arguments({'q': 'qubit'}) def rz(self, phi, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply Rz gate with angle :math:`\\phi` - - The gate is applied to a specified qubit `qubit`. - An Rz gate implemements a phi radian rotation of the qubit state vector - about the z axis of the Bloch sphere. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - phi = Parameter('φ') - circuit = QuantumCircuit(1) - circuit.rz(phi,0) - circuit.draw() - """ + """Apply :class:`~qiskit.extensions.standard.RZGate`.""" return self.append(RZGate(phi), [qubit], []) @@ -107,10 +118,59 @@ def __instancecheck__(mcs, inst): class CRZGate(ControlledGate, metaclass=CRZMeta): - """The controlled-rz gate.""" + r"""Controlled-RZ gate. + + This is a diagonal but non-symmetric gate that induces a + phase on the state of the target qubit, depending on the control state. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: |0>┤ Rz(λ) ├ + └───┬───┘ + q_1: |0>────■──── + + **Matrix representation:** + + .. math:: + + CRZ(\lambda)\ q_1, q_0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & e^{-i\frac{\lambda}{2}} & 0 \\ + 0 & 0 & 0 & e^{i\frac{\lambda}{2}} + \end{pmatrix} + + .. note:: + + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + CRZ(\lambda)\ q_0, q_1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & e^{-i\frac{\lambda}{2}} & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & e^{i\frac{\lambda}{2}} + \end{pmatrix} + + .. seealso:: + + :class:`~qiskit.extensions.standard.CU1Gate`: + Due to the global phase difference in the matrix definitions + of U1 and RZ, CU1 and CRZ are different gates with a relative + phase difference. + """ def __init__(self, theta): - """Create new crz gate.""" super().__init__('crz', 2, [theta], num_ctrl_qubits=1) self.base_gate = RZGate(theta) diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 1ade6b1ca905..1ef15094dd44 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Diagonal single qubit gate. +U1 Gate. """ import numpy from qiskit.circuit import ControlledGate @@ -25,10 +25,43 @@ # pylint: disable=cyclic-import class U1Gate(Gate): - """Diagonal single-qubit gate.""" + r"""Single-qubit rotation about the Z axis. + + This is a diagonal gate. It can be implemented virtually in hardware + via framechanges (i.e. at zero error and duration). + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ U1(λ) ├ + └───────┘ + + **Matrix Representation:** + + .. math:: + + U1(\lambda) = + \begin{pmatrix} + 1 & 0 \\ + 0 & e^{i.\lambda} + \end{pmatrix} + + .. seealso:: + + :class:`~qiskit.extensions.standard.RZGate` + This gate is equivalent to RZ up to a phase factor. + + .. math:: + + U1(\lambda) = e^{i.{\lambda}/2}.RZ(\lambda) + + Reference for virtual Z gate implementation: + `1612.00858 `_ + """ def __init__(self, theta, label=None): - """Create new diagonal single-qubit gate.""" super().__init__('u1', 1, [theta], label=label) def _define(self): @@ -43,7 +76,7 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-U1 gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -61,7 +94,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + r"""Return inverted U1 gate (:math:`U1(\lambda){\dagger} = U1(-\lambda)`)""" return U1Gate(-self.params[0]) def to_matrix(self): @@ -73,33 +106,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def u1(self, theta, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply U1 gate with angle theta - - Applied to a specified qubit ``qubit``. - :math:`u1(\\lambda) := diag(1, ei\\lambda) ∼ U(0, 0, \\lambda) = Rz(\\lambda)` - where :math:`~` is equivalence up to a global phase. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - circuit = QuantumCircuit(1) - circuit.u1(theta,0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - import numpy - from qiskit.extensions.standard.u1 import U1Gate - U1Gate(numpy.pi/2).to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.U1Gate`.""" return self.append(U1Gate(theta), [qubit], []) @@ -117,10 +124,42 @@ def __instancecheck__(mcs, inst): class CU1Gate(ControlledGate, metaclass=CU1Meta): - """The controlled-u1 gate.""" + r"""Controlled-U1 gate. + + This is a diagonal and symmetric gate that induces a + phase on the state of the target qubit, depending on the control state. + + **Circuit symbol:** + + .. parsed-literal:: + + + q_0: |0>─■── + │λ + q_1: |0>─■── + + + **Matrix representation:** + + .. math:: + + CU1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & e^{i\lambda} + \end{pmatrix} + + .. seealso:: + + :class:`~qiskit.extensions.standard.CRZGate`: + Due to the global phase difference in the matrix definitions + of U1 and RZ, CU1 and CRZ are different gates with a relative + phase difference. + """ def __init__(self, theta): - """Create new cu1 gate.""" super().__init__('cu1', 2, [theta], num_ctrl_qubits=1) self.base_gate = U1Gate(theta) @@ -147,7 +186,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + r"""Return inverted CU1 gate (:math:`CU1(\lambda){\dagger} = CU1(-\lambda)`)""" return CU1Gate(-self.params[0]) @@ -167,26 +206,7 @@ def __init__(self, theta): 'tgt': 'target_qubit'}) def cu1(self, theta, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument - r"""Apply cU1 gate - - Applied from a specified control ``control_qubit`` to target - ``target_qubit`` qubit with angle theta. A cU1 gate implements a - :math:`\theta` radian rotation of the qubit state vector about the z axis - of the Bloch sphere when the control qubit is in state :math:`|1\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - circuit = QuantumCircuit(2) - circuit.cu1(theta,0,1) - circuit.draw() - """ + """Apply :class:`~qiskit.extensions.standard.CU1Gate`.""" return self.append(CU1Gate(theta), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index e69a13f2d65f..9051974123a2 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -68,7 +68,6 @@ class YGate(Gate): """ def __init__(self, label=None): - """Create new Y gate.""" super().__init__('y', 1, [], label=label) def _define(self): @@ -114,8 +113,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def y(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply :class:`~qiskit.extensions.standard.YGate`.. - """ + """Apply :class:`~qiskit.extensions.standard.YGate`.""" return self.append(YGate(), [qubit], []) @@ -177,7 +175,6 @@ class CYGate(ControlledGate, metaclass=CYMeta): """ def __init__(self): - """Create a new CY gate.""" super().__init__('cy', 2, [], num_ctrl_qubits=1) self.base_gate = YGate() diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index ad161d5b4dd4..6d96139bb55a 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -68,7 +68,6 @@ class ZGate(Gate): """ def __init__(self, label=None): - """Create new Z gate.""" super().__init__('z', 1, [], label=label) def _define(self): From 7f4418f39b83ddd0dedf763787f75947a3624e06 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 02:49:41 -0400 Subject: [PATCH 08/38] u2 and u3 --- qiskit/extensions/standard/rz.py | 18 ---- qiskit/extensions/standard/u1.py | 11 ++- qiskit/extensions/standard/u2.py | 65 +++++++------- qiskit/extensions/standard/u3.py | 145 ++++++++++++++++++------------- 4 files changed, 129 insertions(+), 110 deletions(-) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index ea9b15e25c1f..15272cf80e18 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -216,24 +216,6 @@ def __init__(self, theta): def crz(self, theta, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument """Apply cRz gate - - Applied from a specified control ``control_qubit`` to target ``target_qubit`` qubit - with angle :math:`\\theta`. A cRz gate implements a :math:`\\theta` radian rotation - of the qubit state vector about the z axis of the Bloch sphere when the control - qubit is in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - circuit = QuantumCircuit(2) - circuit.crz(theta,0,1) - circuit.draw() """ return self.append(CRZGate(theta), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 1ef15094dd44..ae60f8f1eedb 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -45,17 +45,21 @@ class U1Gate(Gate): U1(\lambda) = \begin{pmatrix} 1 & 0 \\ - 0 & e^{i.\lambda} + 0 & e^{i\lambda} \end{pmatrix} .. seealso:: - :class:`~qiskit.extensions.standard.RZGate` + :class:`~qiskit.extensions.standard.RZGate`: This gate is equivalent to RZ up to a phase factor. .. math:: - U1(\lambda) = e^{i.{\lambda}/2}.RZ(\lambda) + U1(\lambda) = e^{i{\lambda}/2}.RZ(\lambda) + + :class:`~qiskit.extensions.standard.U3Gate`: + U3 is a generalization of U2 that covers all single-qubit rotations, + using two X90 pulses. Reference for virtual Z gate implementation: `1612.00858 `_ @@ -158,7 +162,6 @@ class CU1Gate(ControlledGate, metaclass=CU1Meta): of U1 and RZ, CU1 and CRZ are different gates with a relative phase difference. """ - def __init__(self, theta): super().__init__('cu1', 2, [theta], num_ctrl_qubits=1) self.base_gate = U1Gate(theta) diff --git a/qiskit/extensions/standard/u2.py b/qiskit/extensions/standard/u2.py index f73c0bae41c8..cc22a3d21499 100644 --- a/qiskit/extensions/standard/u2.py +++ b/qiskit/extensions/standard/u2.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -One-pulse single-qubit gate. +U2 Gate. """ import numpy from qiskit.circuit import Gate @@ -24,10 +24,39 @@ class U2Gate(Gate): - """One-pulse single-qubit gate.""" + r"""Single-qubit rotation about the X+Z axis. + + Implemented using one X90 pulse on IBM Quantum systems: + + .. math:: + U2(\phi, \lambda) = RZ(\phi+\pi/2).RX(\frac{\pi}{2}).RZ(\lambda-\pi/2) + + **Circuit symbol:** + + .. parsed-literal:: + + ┌─────────┐ + q_0: ┤ U2(φ,λ) ├ + └─────────┘ + + **Matrix Representation:** + + .. math:: + + U2(\phi, \lambda) = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & e^{-i\lambda} \\ + e^{i\phi} & e^{i(\phi+\lambda)} + \end{pmatrix} + + .. seealso:: + + :class:`~qiskit.extensions.standard.U3Gate`: + U3 is a generalization of U2 that covers all single-qubit rotations, + using two X90 pulses. + """ def __init__(self, phi, lam, label=None): - """Create new one-pulse single-qubit gate.""" super().__init__('u2', 1, [phi, lam], label=label) def _define(self): @@ -40,9 +69,9 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate. + r"""Return inverted U2 gate. - u2(phi,lamb)^dagger = u2(-lamb-pi,-phi+pi) + :math:`U2(\phi, \lambda)^{\dagger} =U2(-\lambda-\pi, -\phi+\pi)`) """ return U2Gate(-self.params[1] - pi, -self.params[0] + pi) @@ -65,31 +94,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def u2(self, phi, lam, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply U2 gate with angle phi and lam to a specified qubit (qubit). - u2(φ,λ) := U(π/2,φ,λ) = Rz(φ + π/2)Rx(π/2)Rz(λ − π/2) - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - phi = Parameter('φ') - lam = Parameter('λ') - circuit = QuantumCircuit(1) - circuit.u2(phi,lam,0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - import numpy - from qiskit.extensions.standard.u2 import U2Gate - U2Gate(numpy.pi/2,numpy.pi/2).to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.U2Gate`.""" return self.append(U2Gate(phi, lam), [qubit], []) diff --git a/qiskit/extensions/standard/u3.py b/qiskit/extensions/standard/u3.py index c1c32798064c..444c2e86a16b 100644 --- a/qiskit/extensions/standard/u3.py +++ b/qiskit/extensions/standard/u3.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Two-pulse single-qubit gate. +U3 Gate. """ import numpy @@ -26,21 +26,46 @@ # pylint: disable=cyclic-import class U3Gate(Gate): - """Two-pulse single-qubit gate.""" + r"""Generic single-qubit rotation gate with 3 Euler angles. + + Implemented using two X90 pulses on IBM Quantum systems: + + .. math:: + U2(\phi, \lambda) = RZ(\phi+\pi/2).RX(\frac{\pi}{2}).RZ(\lambda-\pi/2) + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────────┐ + q_0: ┤ U3(ϴ,φ,λ) ├ + └───────────┘ + + **Matrix Representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + U3(\theta, \phi, \lambda) = + \begin{pmatrix} + \cos(\th) & e^{-i\lambda}\sin(\th) \\ + e^{i\phi}\sin(\th) & e^{i(\phi+\lambda)\cos(\th)} + \end{pmatrix} + """ def __init__(self, theta, phi, lam, label=None): - """Create new two-pulse single qubit gate.""" super().__init__('u3', 1, [theta, phi, lam], label=label) def inverse(self): - """Invert this gate. + r"""Return inverted U3 gate. - u3(theta, phi, lamb)^dagger = u3(-theta, -lam, -phi) - """ + :math:`U3(\theta,\phi,\lambda)^{\dagger} =U3(-\theta,-\phi,-\lambda)`) + """ return U3Gate(-self.params[0], -self.params[2], -self.params[1]) def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-U3 gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -75,32 +100,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def u3(self, theta, phi, lam, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply U3 gate with angle theta, phi, and lam to a specified qubit (qubit). - u3(θ, φ, λ) := U(θ, φ, λ) = Rz(φ + 3π)Rx(π/2)Rz(θ + π)Rx(π/2)Rz(λ) - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('theta') - phi = Parameter('φ') - lam = Parameter('λ') - circuit = QuantumCircuit(1) - circuit.u3(theta,phi,lam,0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - import numpy - from qiskit.extensions.standard.u3 import U3Gate - U3Gate(numpy.pi/2,numpy.pi/2,numpy.pi/2).to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.U3Gate`.""" return self.append(U3Gate(theta, phi, lam), [qubit], []) @@ -118,10 +118,57 @@ def __instancecheck__(mcs, inst): class CU3Gate(ControlledGate, metaclass=CU3Meta): - """The controlled-u3 gate.""" + r"""Controlled-U3 gate (3-parameter two-qubit gate). + + This is a controlled version of the U3 gate (generic single qubit rotation). + It is restricted to 3 parameters, and so cannot cover generic two-qubit + controlled gates). + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────────┐ + q_0: ┤ U3(ϴ,φ,λ) ├ + └─────┬─────┘ + q_1: ──────■────── + + + **Matrix representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + CU3(\theta, \phi, \lambda)\ q_1, q_0= + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & \cos(\th) & e^{-i\lambda}\sin(\th) \\ + 0 & 0 & e^{i\phi}\sin(\th) & e^{i(\phi+\lambda)\cos(\th)} + \end{pmatrix} + + + .. note:: + + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + CU3(\theta, \phi, \lambda)\ q_0, q_1= + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos(\th) & 0 & e^{-i\lambda}\sin(\th) \\ + 0 & 0 & 1 & 0 \\ + 0 & e^{i\phi}\sin(\th) & 0 & e^{i(\phi+\lambda)\cos(\th)} + \end{pmatrix} + """ def __init__(self, theta, phi, lam): - """Create new cu3 gate.""" super().__init__('cu3', 2, [theta, phi, lam], num_ctrl_qubits=1) self.base_gate = U3Gate(theta, phi, lam) @@ -153,7 +200,10 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + r"""Return inverted CU3 gate. + + :math:`CU3(\theta,\phi,\lambda)^{\dagger} =CU3(-\theta,-\phi,-\lambda)`) + """ return CU3Gate(-self.params[0], -self.params[2], -self.params[1]) @@ -173,28 +223,7 @@ def __init__(self, theta, phi, lam): 'tgt': 'target_qubit'}) def cu3(self, theta, phi, lam, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cU3 gate - - Applied from a specified control ``control_qubit`` to target - ``target_qubit`` qubit with angle ``theta``, ``phi``, and ``lam``. - A cU3 gate implements a ``U3(theta,phi,lam)`` on the target qubit when the - control qubit is in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - phi = Parameter('φ') - lam = Parameter('λ') - circuit = QuantumCircuit(2) - circuit.cu3(theta,phi,lam,0,1) - circuit.draw() - """ + """Apply :class:`~qiskit.extensions.standard.U3Gate`.""" return self.append(CU3Gate(theta, phi, lam), [control_qubit, target_qubit], []) From cab79232cd3f64381ed69c4b1b7d17ce7d6ad3f0 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 03:35:03 -0400 Subject: [PATCH 09/38] rx,ry,rz --- qiskit/extensions/standard/dcx.py | 1 + qiskit/extensions/standard/iswap.py | 3 +- qiskit/extensions/standard/rx.py | 111 ++++++++++++++++++--------- qiskit/extensions/standard/ry.py | 112 +++++++++++++++++++--------- qiskit/extensions/standard/rz.py | 26 ++++--- qiskit/extensions/standard/rzx.py | 1 + qiskit/extensions/standard/u1.py | 17 +++++ qiskit/extensions/standard/u2.py | 11 ++- qiskit/extensions/standard/u3.py | 22 ++++-- qiskit/extensions/standard/x.py | 39 +++++----- qiskit/extensions/standard/y.py | 2 + qiskit/extensions/standard/z.py | 1 + 12 files changed, 240 insertions(+), 106 deletions(-) diff --git a/qiskit/extensions/standard/dcx.py b/qiskit/extensions/standard/dcx.py index a10bf12159c3..c3a8bffd4e66 100644 --- a/qiskit/extensions/standard/dcx.py +++ b/qiskit/extensions/standard/dcx.py @@ -50,6 +50,7 @@ class DCXGate(Gate): """ def __init__(self): + """Create new DCX gate.""" super().__init__('dcx', 2, []) def _define(self): diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index f5037d775990..ec6549aff97a 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -25,7 +25,7 @@ class iSwapGate(Gate): r"""iSWAP gate. - A 2-qubit XY interaction that is equivalent to a SWAP up to a diagonal. + A 2-qubit XX+YY interaction that is equivalent to a SWAP up to a diagonal. This is a Clifford and symmetric gate. Its action is to swap two qubit states and phase the :math:`|01\rangle` and :math:`|10\rangle` amplitudes by i. @@ -62,6 +62,7 @@ class iSwapGate(Gate): """ def __init__(self): + """Create new iSwap gate.""" super().__init__('iswap', 2, []) def _define(self): diff --git a/qiskit/extensions/standard/rx.py b/qiskit/extensions/standard/rx.py index 801bc27eef75..e0ba93498817 100644 --- a/qiskit/extensions/standard/rx.py +++ b/qiskit/extensions/standard/rx.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Rotation around the x-axis. +Rotation around the X axis. """ import math import numpy @@ -26,10 +26,31 @@ class RXGate(Gate): - """The rotation around the x-axis.""" + r"""Single-qubit rotation about the X axis. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ Rx(ϴ) ├ + └───────┘ + + **Matrix Representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + RX(\theta) = exp(-i\frac{\theta}{2}X) = + \begin{pmatrix} + \cos{\th} & -i\sin{\th} \\ + -i\sin{\th} & \cos{\th}} + \end{pmatrix} + """ def __init__(self, theta): - """Create new rx single qubit gate.""" + """Create new RX gate.""" super().__init__('rx', 1, [theta]) def _define(self): @@ -47,7 +68,7 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-RX gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -65,9 +86,9 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate. + r"""Return inverted RX gate. - rx(theta)^dagger = rx(-theta) + :math:`RX(\lambda)^{\dagger} = RX(-\lambda)` """ return RXGate(-self.params[0]) @@ -81,31 +102,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def rx(self, theta, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply Rx gate with angle theta to a specified qubit (qubit). - An Rx gate implements a theta radian rotation of the qubit state vector about the - x axis of the Bloch sphere. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - circuit = QuantumCircuit(1) - circuit.rx(theta,0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - import numpy - from qiskit.extensions.standard.rx import RXGate - RXGate(numpy.pi/2).to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.RXGate`.""" return self.append(RXGate(theta), [qubit], []) @@ -123,10 +120,54 @@ def __instancecheck__(mcs, inst): class CRXGate(ControlledGate, metaclass=CRXMeta): - """The controlled-rx gate.""" + r"""Controlled-RX gate. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ Rx(λ) ├ + └───┬───┘ + q_1: ────■──── + + **Matrix representation:** + + .. math:: + \newcommand{\th}{\frac{\theta}{2}} + + CRX(\theta)\ q_1, q_0 = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes RX = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & \cos{\th} & -i\sin{\th} \\ + 0 & 0 & -i\sin{\th} & \cos{\th}} + \end{pmatrix} + + .. note:: + + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + CRX(\lambda)\ q_0, q_1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos{\th} & 0 & -i\sin{\th} \\ + 0 & 0 & 1 & 0 \\ + 0 & -i\sin{\th} & 0 & \cos{\th}} + \end{pmatrix} + """ def __init__(self, theta): - """Create new crx gate.""" + """Create new CRX gate.""" super().__init__('crx', 2, [theta], num_ctrl_qubits=1) self.base_gate = RXGate(theta) @@ -157,7 +198,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RX gate (i.e. with the negative rotation angle).""" return CRXGate(-self.params[0]) @@ -177,7 +218,7 @@ def __init__(self, theta): 'tgt': 'target_qubit'}) def crx(self, theta, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply crx from ctl to tgt with angle theta.""" + """Apply :class:`~qiskit.extensions.standard.CRXGate`.""" return self.append(CRXGate(theta), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/ry.py b/qiskit/extensions/standard/ry.py index a76668f132f1..b47f32c33fe0 100644 --- a/qiskit/extensions/standard/ry.py +++ b/qiskit/extensions/standard/ry.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Rotation around the y-axis. +Rotation around the Y axis. """ import math import numpy @@ -26,10 +26,31 @@ class RYGate(Gate): - """The rotation around the y-axis.""" + r"""Single-qubit rotation about the Y axis. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ Ry(ϴ) ├ + └───────┘ + + **Matrix Representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + RX(\theta) = exp(-i\frac{\theta}{2}Y) = + \begin{pmatrix} + \cos{\th} & -\sin{\th} \\ + \sin{\th} & \cos{\th}} + \end{pmatrix} + """ def __init__(self, theta): - """Create new RY single qubit gate.""" + """Create new RY gate.""" super().__init__('ry', 1, [theta]) def _define(self): @@ -47,7 +68,7 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (mutli-)controlled-RY gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -65,9 +86,9 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate. + r"""Return inverted RY gate. - ry(theta)^dagger = ry(-theta) + :math:`RY(\lambda){\dagger} = RY(-\lambda)` """ return RYGate(-self.params[0]) @@ -81,31 +102,7 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def ry(self, theta, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply Ry gate with angle theta to a specified qubit (qubit). - An Ry gate implements a theta radian rotation of the qubit state vector about the - y axis of the Bloch sphere. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit.circuit import QuantumCircuit, Parameter - - theta = Parameter('θ') - circuit = QuantumCircuit(1) - circuit.ry(theta,0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - import numpy - from qiskit.extensions.standard.ry import RYGate - RYGate(numpy.pi/2).to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.RYGate`.""" return self.append(RYGate(theta), [qubit], []) @@ -123,10 +120,55 @@ def __instancecheck__(mcs, inst): class CRYGate(ControlledGate, metaclass=CRYMeta): - """The controlled-ry gate.""" + r"""Controlled-RY gate. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───────┐ + q_0: ┤ Ry(λ) ├ + └───┬───┘ + q_1: ────■──── + + + **Matrix representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + CRX(\theta)\ q_1, q_0 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & \cos{\th} & -\sin{\th} \\ + 0 & 0 & \sin{\th} & \cos{\th}} + \end{pmatrix} + + .. note:: + + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + CRX(\lambda)\ q_0, q_1 = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos{\th} & 0 & -\sin{\th} \\ + 0 & 0 & 1 & 0 \\ + 0 & \sin{\th} & 0 & \cos{\th}} + \end{pmatrix} + """ def __init__(self, theta): - """Create new cry gate.""" + """Create new CRY gate.""" super().__init__('cry', 2, [theta], num_ctrl_qubits=1) self.base_gate = RYGate(theta) @@ -153,7 +195,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RY gate (i.e. with the negative rotation angle).""" return CRYGate(-self.params[0]) @@ -173,7 +215,7 @@ def __init__(self, theta): 'tgt': 'target_qubit'}) def cry(self, theta, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cry from ctl to tgt with angle theta.""" + """Apply :class:`~qiskit.extensions.standard.CRYGate`.""" return self.append(CRYGate(theta), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index 15272cf80e18..8c1d85edec6e 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Rotation around the z-axis. +Rotation around the Z axis. """ from qiskit.circuit import Gate from qiskit.circuit import ControlledGate @@ -40,7 +40,7 @@ class RZGate(Gate): .. math:: - RZ(\lambda) = + RZ(\lambda) = exp(-i\frac{\theta}{2}Z) = \begin{pmatrix} e^{-i\frac{\lambda}{2}} & 0 \\ 0 & e^{i\frac{\lambda}{2}} @@ -59,6 +59,7 @@ class RZGate(Gate): `1612.00858 `_ """ def __init__(self, phi): + """Create new RZ gate.""" super().__init__('rz', 1, [phi]) def _define(self): @@ -94,7 +95,10 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - r"""Return inverted RZ gate (:math:`RZ(\lambda){\dagger} = RZ(-\lambda)`)""" + r"""Return inverted RZ gate + + :math:`RZ(\lambda){\dagger} = RZ(-\lambda)` + """ return RZGate(-self.params[0]) @@ -127,11 +131,11 @@ class CRZGate(ControlledGate, metaclass=CRZMeta): .. parsed-literal:: - ┌───────┐ - q_0: |0>┤ Rz(λ) ├ - └───┬───┘ - q_1: |0>────■──── - + ┌───────┐ + q_0: ┤ Rz(λ) ├ + └───┬───┘ + q_1: ────■──── + **Matrix representation:** @@ -171,6 +175,7 @@ class CRZGate(ControlledGate, metaclass=CRZMeta): phase difference. """ def __init__(self, theta): + """Create new CRZ gate.""" super().__init__('crz', 2, [theta], num_ctrl_qubits=1) self.base_gate = RZGate(theta) @@ -196,7 +201,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RZ gate (i.e. with the negative rotation angle).""" return CRZGate(-self.params[0]) @@ -215,8 +220,7 @@ def __init__(self, theta): @deprecate_arguments({'ctl': 'control_qubit', 'tgt': 'target_qubit'}) def crz(self, theta, control_qubit, target_qubit, *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cRz gate - """ + """Apply :class:`~qiskit.extensions.standard.CRZGate`.""" return self.append(CRZGate(theta), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index 4c5a16cf5724..2ecc429995ed 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -109,6 +109,7 @@ class RZXGate(Gate): """ def __init__(self, theta): + """Create new RZX gate.""" super().__init__('rzx', 2, [theta]) def _define(self): diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index ae60f8f1eedb..4dc67a932cc6 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -48,6 +48,20 @@ class U1Gate(Gate): 0 & e^{i\lambda} \end{pmatrix} + **Examples:** + + .. math:: + + U1(\lambda = \pi) = Z + + .. math:: + + U1(\lambda = \pi/2) = S + + .. math:: + + U1(\lambda = \pi/4) = T + .. seealso:: :class:`~qiskit.extensions.standard.RZGate`: @@ -66,6 +80,7 @@ class U1Gate(Gate): """ def __init__(self, theta, label=None): + """Create new U1 gate.""" super().__init__('u1', 1, [theta], label=label) def _define(self): @@ -162,7 +177,9 @@ class CU1Gate(ControlledGate, metaclass=CU1Meta): of U1 and RZ, CU1 and CRZ are different gates with a relative phase difference. """ + def __init__(self, theta): + """Create new CU1 gate.""" super().__init__('cu1', 2, [theta], num_ctrl_qubits=1) self.base_gate = U1Gate(theta) diff --git a/qiskit/extensions/standard/u2.py b/qiskit/extensions/standard/u2.py index cc22a3d21499..f6d19715ba09 100644 --- a/qiskit/extensions/standard/u2.py +++ b/qiskit/extensions/standard/u2.py @@ -27,10 +27,10 @@ class U2Gate(Gate): r"""Single-qubit rotation about the X+Z axis. Implemented using one X90 pulse on IBM Quantum systems: - + .. math:: U2(\phi, \lambda) = RZ(\phi+\pi/2).RX(\frac{\pi}{2}).RZ(\lambda-\pi/2) - + **Circuit symbol:** .. parsed-literal:: @@ -49,6 +49,12 @@ class U2Gate(Gate): e^{i\phi} & e^{i(\phi+\lambda)} \end{pmatrix} + **Examples:** + + .. math:: + + U2(\pi, 0) = H + .. seealso:: :class:`~qiskit.extensions.standard.U3Gate`: @@ -57,6 +63,7 @@ class U2Gate(Gate): """ def __init__(self, phi, lam, label=None): + """Create new U2 gate.""" super().__init__('u2', 1, [phi, lam], label=label) def _define(self): diff --git a/qiskit/extensions/standard/u3.py b/qiskit/extensions/standard/u3.py index 444c2e86a16b..491c25f899de 100644 --- a/qiskit/extensions/standard/u3.py +++ b/qiskit/extensions/standard/u3.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -U3 Gate. +U3 Gate, three-parameter single-qubit gate. """ import numpy @@ -29,10 +29,10 @@ class U3Gate(Gate): r"""Generic single-qubit rotation gate with 3 Euler angles. Implemented using two X90 pulses on IBM Quantum systems: - + .. math:: U2(\phi, \lambda) = RZ(\phi+\pi/2).RX(\frac{\pi}{2}).RZ(\lambda-\pi/2) - + **Circuit symbol:** .. parsed-literal:: @@ -46,22 +46,33 @@ class U3Gate(Gate): .. math:: \newcommand{\th}{\frac{\theta}{2}} - + U3(\theta, \phi, \lambda) = \begin{pmatrix} \cos(\th) & e^{-i\lambda}\sin(\th) \\ e^{i\phi}\sin(\th) & e^{i(\phi+\lambda)\cos(\th)} \end{pmatrix} + + **Examples:** + + .. math:: + + U3(\theta, -\frac{\pi}{2}, \frac{pi}{2}) = RX(\theta) + + .. math:: + + U3(\theta, 0, 0) = RY(\theta) """ def __init__(self, theta, phi, lam, label=None): + """Create new U3 gate.""" super().__init__('u3', 1, [theta, phi, lam], label=label) def inverse(self): r"""Return inverted U3 gate. :math:`U3(\theta,\phi,\lambda)^{\dagger} =U3(-\theta,-\phi,-\lambda)`) - """ + """ return U3Gate(-self.params[0], -self.params[2], -self.params[1]) def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -169,6 +180,7 @@ class CU3Gate(ControlledGate, metaclass=CU3Meta): """ def __init__(self, theta, phi, lam): + """Create new CU3 gate.""" super().__init__('cu3', 2, [theta, phi, lam], num_ctrl_qubits=1) self.base_gate = U3Gate(theta, phi, lam) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 5f076346f3cf..2a02f85b6c5a 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -71,6 +71,7 @@ class XGate(Gate): """ def __init__(self, label=None): + """Create new X gate.""" super().__init__('x', 1, [], label=label) def _define(self): @@ -191,6 +192,7 @@ class CXGate(ControlledGate, metaclass=CXMeta): """ def __init__(self): + """Create new CX gate.""" super().__init__('cx', 2, [], num_ctrl_qubits=1) self.base_gate = XGate() @@ -267,52 +269,55 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. parsed-literal:: - q_0: ──■── - │ + ┌───┐ + q_0: ┤ X ├ + └─┬─┘ q_1: ──■── - ┌─┴─┐ - q_2: ┤ X ├ - └───┘ + │ + q_2: ──■── + **Matrix representation:** .. math:: - CX 0, 1, 2 = + CCX\ q_0, q_1, q_2 = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ - 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ - 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\ - 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \end{pmatrix} .. note:: - In Qiskit's convention, lower qubit indices are less significant - (little endian). Textbook representations of CCX matrix implicitly - assume the more significant qubits to be the controls. So in order to - get such a matrix in Qiskit, the higher-index qubits must be the controls. + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 and q_1 as control, the matrix will be: .. math:: - CCX 2, 1, 0 = + CCX q_2, q_1, q_0 = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ - 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\ + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ - 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ - 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \end{pmatrix} """ def __init__(self): + """Create new CCX gate.""" super().__init__('ccx', 3, [], num_ctrl_qubits=2) self.base_gate = XGate() diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index 9051974123a2..da7025478458 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -68,6 +68,7 @@ class YGate(Gate): """ def __init__(self, label=None): + """Create new Y gate.""" super().__init__('y', 1, [], label=label) def _define(self): @@ -175,6 +176,7 @@ class CYGate(ControlledGate, metaclass=CYMeta): """ def __init__(self): + """Create new CY gate.""" super().__init__('cy', 2, [], num_ctrl_qubits=1) self.base_gate = YGate() diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index 6d96139bb55a..ad161d5b4dd4 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -68,6 +68,7 @@ class ZGate(Gate): """ def __init__(self, label=None): + """Create new Z gate.""" super().__init__('z', 1, [], label=label) def _define(self): From f2219c4c44e533a3e3f8318f6207b979b150ce40 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 04:20:59 -0400 Subject: [PATCH 10/38] fix typos --- qiskit/extensions/standard/h.py | 125 ++++++++++++++++++------------- qiskit/extensions/standard/i.py | 2 +- qiskit/extensions/standard/rx.py | 13 ++-- qiskit/extensions/standard/ry.py | 18 +++-- qiskit/extensions/standard/rz.py | 2 + qiskit/extensions/standard/u1.py | 1 + qiskit/extensions/standard/u3.py | 5 +- qiskit/extensions/standard/x.py | 4 + qiskit/extensions/standard/y.py | 2 + qiskit/extensions/standard/z.py | 1 + 10 files changed, 104 insertions(+), 69 deletions(-) diff --git a/qiskit/extensions/standard/h.py b/qiskit/extensions/standard/h.py index 3f9f883cdece..79039b5d22ce 100644 --- a/qiskit/extensions/standard/h.py +++ b/qiskit/extensions/standard/h.py @@ -28,10 +28,33 @@ # pylint: disable=cyclic-import class HGate(Gate): - """Hadamard gate.""" + r"""Single-qubit Hadamard gate. + + This gate is a \pi rotation about the X+Z axis, and has the effect of + changing computation basis from :math:`|0\rangle,|1\rangle` to + :math:`|+\rangle,|-\rangle` and vice-versa. + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ H ├ + └───┘ + + **Matrix Representation:** + + .. math:: + + H = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & 1 \\ + 1 & -2 + \end{pmatrix} + """ def __init__(self, label=None): - """Create new Hadamard gate.""" + """Create new H gate.""" super().__init__('h', 1, [], label=label) def _define(self): @@ -49,7 +72,9 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (multi-)controlled-H gate. + + One control qubit returns a CH gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -67,7 +92,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + r"""Return inverted H gate (itself).""" return HGate() # self-inverse def to_matrix(self): @@ -78,43 +103,62 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def h(self, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - r"""Apply Hadamard (H) gate. + """Apply :class:`~qiskit.extensions.standard.HGate`.""" + return self.append(HGate(), [qubit], []) - Applied to a specified qubit ``qubit``. - An H gate implements a rotation of :math:`\pi` about the axis - :math:`\frac{(x + z)}{\sqrt{2}}` on the Bloch sphere. This gate is - canonically used to rotate the qubit state from :math:`|0\rangle` to - :math:`|+\rangle` or :math:`|1\rangle` to :math:`|-\rangle`. +QuantumCircuit.h = h - Examples: - Circuit Representation: +class CHGate(ControlledGate): + r"""Controlled-Hadamard gate. - .. jupyter-execute:: + Applies a Hadamard on the target qubit if the control is + in the :math:`|1\rangle` state. - from qiskit import QuantumCircuit + **Circuit symbol:** - circuit = QuantumCircuit(1) - circuit.h(0) - circuit.draw() + .. parsed-literal:: - Matrix Representation: + ┌───┐ + q_0: ┤ H ├ + └─┬─┘ + q_1: ──■── - .. jupyter-execute:: + **Matrix Representation:** - from qiskit.extensions.standard.h import HGate - HGate().to_matrix() + .. math:: - """ - return self.append(HGate(), [qubit], []) + CH\ q_1, q_0 = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes H = + \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 1 \\ + 0 & 0 & 1 & -1 + \end{pmatrix} + .. note:: -QuantumCircuit.h = h + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + .. math:: -class CHGate(ControlledGate): - """The controlled-H gate.""" + CH\ q_0, q_1 = + I \otimes |0\rangle\langle 0| + H \otimes |1\rangle\langle 1| = + \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 1 \\ + 0 & 0 & 1 & 0 \\ + 0 & 1 & 0 & -1 + \end{pmatrix} + """ def __init__(self): """Create new CH gate.""" @@ -150,7 +194,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverted CH gate (itself).""" return CHGate() # self-inverse def to_matrix(self): @@ -165,32 +209,7 @@ def to_matrix(self): @deprecate_arguments({'ctl': 'control_qubit', 'tgt': 'target_qubit'}) def ch(self, control_qubit, target_qubit, # pylint: disable=invalid-name *, ctl=None, tgt=None): # pylint: disable=unused-argument - """Apply cH gate - - From a specified control ``control_qubit`` to target ``target_qubit`` qubit. - This gate is canonically used to rotate the qubit state from :math:`|0\\rangle` to - :math:`|+\\rangle` and :math:`|1\\rangle to :math:`|−\\rangle` when the control qubit is - in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.ch(0,1) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.h import CHGate - CHGate().to_matrix() - """ + """Apply :class:`~qiskit.extensions.standard.CHGate`.""" return self.append(CHGate(), [control_qubit, target_qubit], []) diff --git a/qiskit/extensions/standard/i.py b/qiskit/extensions/standard/i.py index 9c6af2581674..0188f61952da 100644 --- a/qiskit/extensions/standard/i.py +++ b/qiskit/extensions/standard/i.py @@ -33,7 +33,7 @@ def __instancecheck__(mcs, inst): class IGate(Gate, metaclass=IMeta): - """Identity gate. + r"""Identity gate. Identity gate corresponds to a single-qubit gate wait cycle, and should not be optimized or unrolled (it is an opaque gate). diff --git a/qiskit/extensions/standard/rx.py b/qiskit/extensions/standard/rx.py index e0ba93498817..78797659a5c7 100644 --- a/qiskit/extensions/standard/rx.py +++ b/qiskit/extensions/standard/rx.py @@ -42,10 +42,10 @@ class RXGate(Gate): \newcommand{\th}{\frac{\theta}{2}} - RX(\theta) = exp(-i\frac{\theta}{2}X) = + RX(\theta) = exp(-i \th X) = \begin{pmatrix} \cos{\th} & -i\sin{\th} \\ - -i\sin{\th} & \cos{\th}} + -i\sin{\th} & \cos{\th} \end{pmatrix} """ @@ -127,7 +127,7 @@ class CRXGate(ControlledGate, metaclass=CRXMeta): .. parsed-literal:: ┌───────┐ - q_0: ┤ Rx(λ) ├ + q_0: ┤ Rx(ϴ) ├ └───┬───┘ q_1: ────■──── @@ -138,12 +138,12 @@ class CRXGate(ControlledGate, metaclass=CRXMeta): \newcommand{\th}{\frac{\theta}{2}} CRX(\theta)\ q_1, q_0 = - |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes RX = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes RX(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos{\th} & -i\sin{\th} \\ - 0 & 0 & -i\sin{\th} & \cos{\th}} + 0 & 0 & -i\sin{\th} & \cos{\th} \end{pmatrix} .. note:: @@ -159,11 +159,12 @@ class CRXGate(ControlledGate, metaclass=CRXMeta): \newcommand{\th}{\frac{\theta}{2}} CRX(\lambda)\ q_0, q_1 = + I \otimes |0\rangle\langle 0| + RX(\theta) \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos{\th} & 0 & -i\sin{\th} \\ 0 & 0 & 1 & 0 \\ - 0 & -i\sin{\th} & 0 & \cos{\th}} + 0 & -i\sin{\th} & 0 & \cos{\th} \end{pmatrix} """ def __init__(self, theta): diff --git a/qiskit/extensions/standard/ry.py b/qiskit/extensions/standard/ry.py index b47f32c33fe0..3b581cde20ef 100644 --- a/qiskit/extensions/standard/ry.py +++ b/qiskit/extensions/standard/ry.py @@ -42,10 +42,10 @@ class RYGate(Gate): \newcommand{\th}{\frac{\theta}{2}} - RX(\theta) = exp(-i\frac{\theta}{2}Y) = + RX(\theta) = exp(-i \th Y) = \begin{pmatrix} - \cos{\th} & -\sin{\th} \\ - \sin{\th} & \cos{\th}} + \cos{\th} & -\sin{\th} \\ + \sin{\th} & \cos{\th} \end{pmatrix} """ @@ -127,7 +127,7 @@ class CRYGate(ControlledGate, metaclass=CRYMeta): .. parsed-literal:: ┌───────┐ - q_0: ┤ Ry(λ) ├ + q_0: ┤ Ry(ϴ) ├ └───┬───┘ q_1: ────■──── @@ -138,12 +138,13 @@ class CRYGate(ControlledGate, metaclass=CRYMeta): \newcommand{\th}{\frac{\theta}{2}} - CRX(\theta)\ q_1, q_0 = + CRY(\theta)\ q_1, q_0 = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes RY(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos{\th} & -\sin{\th} \\ - 0 & 0 & \sin{\th} & \cos{\th}} + 0 & 0 & \sin{\th} & \cos{\th} \end{pmatrix} .. note:: @@ -158,12 +159,13 @@ class CRYGate(ControlledGate, metaclass=CRYMeta): \newcommand{\th}{\frac{\theta}{2}} - CRX(\lambda)\ q_0, q_1 = + CRY(\theta)\ q_0, q_1 = + I \otimes |0\rangle\langle 0| + RY(\theta) \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos{\th} & 0 & -\sin{\th} \\ 0 & 0 & 1 & 0 \\ - 0 & \sin{\th} & 0 & \cos{\th}} + 0 & \sin{\th} & 0 & \cos{\th} \end{pmatrix} """ diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index 8c1d85edec6e..cd7f31d84aed 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -142,6 +142,7 @@ class CRZGate(ControlledGate, metaclass=CRZMeta): .. math:: CRZ(\lambda)\ q_1, q_0 = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes RZ(\lambda) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ @@ -160,6 +161,7 @@ class CRZGate(ControlledGate, metaclass=CRZMeta): .. math:: CRZ(\lambda)\ q_0, q_1 = + I \otimes |0\rangle\langle 0| + RZ(\lambda) \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & e^{-i\frac{\lambda}{2}} & 0 & 0 \\ diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 4dc67a932cc6..965905fc9d06 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -163,6 +163,7 @@ class CU1Gate(ControlledGate, metaclass=CU1Meta): .. math:: CU1 = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes U1 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ diff --git a/qiskit/extensions/standard/u3.py b/qiskit/extensions/standard/u3.py index 491c25f899de..a256395f395c 100644 --- a/qiskit/extensions/standard/u3.py +++ b/qiskit/extensions/standard/u3.py @@ -152,6 +152,7 @@ class CU3Gate(ControlledGate, metaclass=CU3Meta): \newcommand{\th}{\frac{\theta}{2}} CU3(\theta, \phi, \lambda)\ q_1, q_0= + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes U3(\theta,\phi,\lambda) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ @@ -170,7 +171,9 @@ class CU3Gate(ControlledGate, metaclass=CU3Meta): .. math:: - CU3(\theta, \phi, \lambda)\ q_0, q_1= + CU3(\theta, \phi, \lambda)\ q_0, q_1 = + I \otimes |0\rangle\langle 0| + + U3(\theta,\phi,\lambda) \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos(\th) & 0 & e^{-i\lambda}\sin(\th) \\ diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 2a02f85b6c5a..ba518722ed81 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -158,6 +158,7 @@ class CXGate(ControlledGate, metaclass=CXMeta): .. math:: CX\ q_1, q_0 = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes X = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ @@ -176,6 +177,7 @@ class CXGate(ControlledGate, metaclass=CXMeta): .. math:: CX\ q_0, q_1 = + I \otimes |0\rangle\langle0| + Y \otimes |1\rangle\langle1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ @@ -282,6 +284,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: CCX\ q_0, q_1, q_2 = + I \otimes I \otimes |0\rangle\langle 0| + CX \otimes |1\rangle\langle1| = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ @@ -304,6 +307,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: CCX q_2, q_1, q_0 = + |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle1| \otimes CX = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index da7025478458..eec579de8e9f 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -149,6 +149,7 @@ class CYGate(ControlledGate, metaclass=CYMeta): .. math:: CY\ q_1, q_0 = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes Y = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ @@ -167,6 +168,7 @@ class CYGate(ControlledGate, metaclass=CYMeta): .. math:: CY\ q_0, q_1 = + I \otimes |0\rangle\langle0| + Y \otimes |1\rangle\langle1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & -i \\ diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index ad161d5b4dd4..2a79fadc71ad 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -150,6 +150,7 @@ class CZGate(ControlledGate, metaclass=CZMeta): .. math:: CZ\ q_1, q_0 = + |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes Z = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ From 02f661568ff7c3e75ae93ddec16c676bacc8dbb9 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 04:39:08 -0400 Subject: [PATCH 11/38] cswap --- qiskit/extensions/standard/iswap.py | 3 +- qiskit/extensions/standard/swap.py | 159 +++++++++++++++++++--------- qiskit/extensions/standard/x.py | 4 +- 3 files changed, 112 insertions(+), 54 deletions(-) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index ec6549aff97a..f961ab600c80 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -30,7 +30,7 @@ class iSwapGate(Gate): states and phase the :math:`|01\rangle` and :math:`|10\rangle` amplitudes by i. - Circuit Symbol: + **Circuit Symbol:** .. parsed-literal:: @@ -38,6 +38,7 @@ class iSwapGate(Gate): │ q_1: ─⨂─ + **Matrix Representation:** .. math:: iSWAP = diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index 94d8a1a6e706..f849b0d8e12f 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -24,7 +24,45 @@ class SwapGate(Gate): - """SWAP gate.""" + r"""The SWAP gate. + + This is a symmetric and Clifford gate. + + **Matrix Representation:** + + .. math:: + + Z = \begin{pmatrix} + 0 & 0 & \\ + 0 & -1 + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + q_0: ─X─ + │ + q_1: ─X─ + + **Matrix Representation:** + + .. math:: + + SWAP = + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 1 + \end{pmatrix} + + The gate is equivalent to a state swap and is a classical logic gate. + + .. math:: + + |a, b\rangle \rightarrow |b, a\rangle + """ def __init__(self): """Create new SWAP gate.""" @@ -47,7 +85,9 @@ def _define(self): self.definition = definition def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): - """Controlled version of this gate. + """Return a (multi-)controlled-SWAP gate. + + One control returns a CSWAP (Fredkin) gate. Args: num_ctrl_qubits (int): number of control qubits. @@ -65,7 +105,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Invert this gate.""" + """Return inverse Swap gate (itself).""" return SwapGate() # self-inverse def to_matrix(self): @@ -77,27 +117,7 @@ def to_matrix(self): def swap(self, qubit1, qubit2): - """Apply SWAP gate to a pair specified qubits (qubit1, qubit2). - The SWAP gate canonically swaps the states of two qubits. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.swap(0,1) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.swap import SwapGate - SwapGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.SwapGate`. """ return self.append(SwapGate(), [qubit1, qubit2], []) @@ -116,7 +136,68 @@ def __instancecheck__(mcs, inst): class CSwapGate(ControlledGate, metaclass=CSwapMeta): - """The controlled-swap gate, also called Fredkin gate.""" + r"""Controlled-X gate. + + **Circuit symbol:** + + .. parsed-literal:: + + + q_0: |0>─X─ + │ + q_1: |0>─X─ + │ + q_2: |0>─■─ + + + **Matrix representation:** + + .. math:: + + CSWAP\ q_2, q_1, q_0 = + |0\rangle\langle0| \otimes I \otimes I + |1\rangle\langle1| \otimes SWAP = + \begin{pmatrix} + 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ + \end{pmatrix} + + .. note:: + + In Qiskit's convention, higher qubit indices are more significant + (little endian convention). In many textbooks, controlled gates are + presented with the assumption of more significant qubits as control, + which is how we present the gate above as well, resulting in textbook + matrices. Instead, if we use q_0 as control, the matrix will be: + + .. math:: + + CSWAP\ q_0, q_1, q_2 = + |0\rangle\langle0| \otimes I \otimes I + |1\rangle\langle1| \otimes SWAP = + \begin{pmatrix} + 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ + \end{pmatrix} + + In the computational basis, this gate swaps the states of + the two target qubits if the control qubit is in the + :math:`|1\rangle` state. + + .. math:: + `|0, b, c\rangle \rightarrow |0, b, c\rangle` + `|1, b, c\rangle \rightarrow |1, c, b\rangle` + """ def __init__(self): """Create new CSWAP gate.""" @@ -145,7 +226,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse CSwap gate (itself).""" return CSwapGate() # self-inverse def to_matrix(self): @@ -177,31 +258,7 @@ def __init__(self): 'tgt2': 'target_qubit2'}) def cswap(self, control_qubit, target_qubit1, target_qubit2, *, ctl=None, tgt1=None, tgt2=None): # pylint: disable=unused-argument - """Apply Fredkin (CSWAP) gate - - From a specified control ``control_qubit`` to target1 ``target_qubit1`` and - target2 ``target_qubit2`` qubits. The CSWAP gate is canonically - used to swap the qubit states of target1 and target2 when the control qubit - is in state :math:`|1\\rangle`. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(3) - circuit.cswap(0,1,2) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.swap import CSwapGate - CSwapGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.CSwapGate`. """ return self.append(CSwapGate(), [control_qubit, target_qubit1, target_qubit2], []) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index ba518722ed81..47362f19b6c3 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -283,7 +283,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: - CCX\ q_0, q_1, q_2 = + CCX\ q_2, q_1, q_0 = I \otimes I \otimes |0\rangle\langle 0| + CX \otimes |1\rangle\langle1| = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ @@ -306,7 +306,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: - CCX q_2, q_1, q_0 = + CCX q_0, q_1, q_2 = |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle1| \otimes CX = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ From cbf0fbc6b9ce6deae01507e297a9953d91046894 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 04:57:53 -0400 Subject: [PATCH 12/38] s and t --- qiskit/extensions/standard/s.py | 103 ++++++++++++++++--------------- qiskit/extensions/standard/t.py | 105 +++++++++++++++++--------------- tox.ini | 2 +- 3 files changed, 111 insertions(+), 99 deletions(-) diff --git a/qiskit/extensions/standard/s.py b/qiskit/extensions/standard/s.py index 7dc61269fe37..44cf2c088a74 100644 --- a/qiskit/extensions/standard/s.py +++ b/qiskit/extensions/standard/s.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -The S gate (Clifford phase gate) and its inverse. +S and Sdg gate. """ import numpy from qiskit.circuit import Gate @@ -24,8 +24,31 @@ class SGate(Gate): - """The S gate, also called Clifford phase gate.""" + r"""Single qubit S gate (Z**0.5). + It induces a :math:`\pi/2` phase, and is sometimes called the P gate (phase). + + This is a Clifford gate and a square-root of Pauli-Z. + + **Matrix Representation:** + + .. math:: + + S = \begin{pmatrix} + 1 & 0 \\ + 0 & i + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ S ├ + └───┘ + + Equivalent to a :math:`\pi/2` radian rotation about the Z axis. + """ def __init__(self, label=None): """Create a new S gate.""" super().__init__('s', 1, [], label=label) @@ -45,7 +68,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse of S (SdgGate).""" return SdgGate() def to_matrix(self): @@ -55,7 +78,31 @@ def to_matrix(self): class SdgGate(Gate): - """Sdg=diag(1,-i) Clifford adjoint phase gate.""" + r"""Single qubit S-adjoint gate (~Z**0.5). + + It induces a :math:`-\pi/2` phase. + + This is a Clifford gate and a square-root of Pauli-Z. + + **Matrix Representation:** + + .. math:: + + Sdg = \begin{pmatrix} + 1 & 0 \\ + 0 & -i + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌─────┐ + q_0: ┤ Sdg ├ + └─────┘ + + Equivalent to a :math:`\pi/2` radian rotation about the Z axis. + """ def __init__(self, label=None): """Create a new Sdg gate.""" @@ -76,7 +123,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse of Sdg (SGate).""" return SGate() def to_matrix(self): @@ -87,56 +134,14 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def s(self, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply S gate to a specified qubit (qubit). - An S gate implements a pi/2 rotation of the qubit state vector about the - z axis of the Bloch sphere. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.s(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.s import SGate - SGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.SGate`. """ return self.append(SGate(), [qubit], []) @deprecate_arguments({'q': 'qubit'}) def sdg(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply Sdg gate to a specified qubit (qubit). - An Sdg gate implements a -pi/2 rotation of the qubit state vector about the - z axis of the Bloch sphere. It is the inverse of S gate. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.sdg(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.s import SdgGate - SdgGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.SdgGate`. """ return self.append(SdgGate(), [qubit], []) diff --git a/qiskit/extensions/standard/t.py b/qiskit/extensions/standard/t.py index ff49cb7ddcae..29c2d2621d36 100644 --- a/qiskit/extensions/standard/t.py +++ b/qiskit/extensions/standard/t.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -T=sqrt(S) phase gate or its inverse. +T and Tdg gate. """ import numpy from qiskit.circuit import Gate @@ -24,7 +24,32 @@ class TGate(Gate): - """T Gate: pi/4 rotation around Z axis.""" + r"""Single qubit T gate (Z**0.25). + + It induces a :math:`\pi/4` phase, and is sometimes called the pi/8 gate + (because of how the RZ(\pi/4) matrix looks like). + + This is a non-Clifford gate and a fourth-root of Pauli-Z. + + **Matrix Representation:** + + .. math:: + + T = \begin{pmatrix} + 1 & 0 \\ + 0 & 1+i + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌───┐ + q_0: ┤ T ├ + └───┘ + + Equivalent to a :math:`\pi/4` radian rotation about the Z axis. + """ def __init__(self, label=None): """Create new T gate.""" @@ -45,7 +70,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse T gate (i.e. Tdg).""" return TdgGate() def to_matrix(self): @@ -55,7 +80,31 @@ def to_matrix(self): class TdgGate(Gate): - """Tdg Gate: -pi/4 rotation around Z axis.""" + r"""Single qubit T-adjoint gate (~Z**0.25). + + It induces a :math:`-\pi/4` phase. + + This is a non-Clifford gate and a fourth-root of Pauli-Z. + + **Matrix Representation:** + + .. math:: + + Tdg = \begin{pmatrix} + 1 & 0 \\ + 0 & 1-i + \end{pmatrix} + + **Circuit symbol:** + + .. parsed-literal:: + + ┌─────┐ + q_0: ┤ Tdg ├ + └─────┘ + + Equivalent to a :math:`\pi/2` radian rotation about the Z axis. + """ def __init__(self, label=None): """Create a new Tdg gate.""" @@ -76,7 +125,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse Tdg gate (i.e. T).""" return TGate() def to_matrix(self): @@ -87,56 +136,14 @@ def to_matrix(self): @deprecate_arguments({'q': 'qubit'}) def t(self, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument - """Apply T gate to a specified qubit (qubit). - A T gate implements a pi/4 rotation of a qubit state vector about the - z axis of the Bloch sphere. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.t(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.t import TGate - TGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.TGate`. """ return self.append(TGate(), [qubit], []) @deprecate_arguments({'q': 'qubit'}) def tdg(self, qubit, *, q=None): # pylint: disable=unused-argument - """Apply Tdg gate to a specified qubit (qubit). - A Tdg gate implements a -pi/4 rotation of a qubit state vector about the - z axis of the Bloch sphere. It is the inverse of T-gate. - - Examples: - - Circuit Representation: - - .. jupyter-execute:: - - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.tdg(0) - circuit.draw() - - Matrix Representation: - - .. jupyter-execute:: - - from qiskit.extensions.standard.t import TdgGate - TdgGate().to_matrix() + """Apply :class:`~qiskit.extensions.standard.TdgGate`. """ return self.append(TdgGate(), [qubit], []) diff --git a/tox.ini b/tox.ini index dfc0d272c919..7e4a6bde2cd7 100644 --- a/tox.ini +++ b/tox.ini @@ -43,4 +43,4 @@ deps = qiskit-aer qiskit-ibmq-provider commands = - sphinx-build -b html docs/ docs/_build/html {posargs} + sphinx-build -W -b html docs/ docs/_build/html {posargs} From ab2400487de212edb88cf62efe56f121e8992a95 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 05:06:19 -0400 Subject: [PATCH 13/38] tweak --- qiskit/extensions/standard/dcx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/dcx.py b/qiskit/extensions/standard/dcx.py index c3a8bffd4e66..a1cc9e97e740 100644 --- a/qiskit/extensions/standard/dcx.py +++ b/qiskit/extensions/standard/dcx.py @@ -40,7 +40,7 @@ class DCXGate(Gate): .. math:: - DCX 0, 1 = + DCX\ q_0, q_1 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ From 4ebeb61b9ac61f8bf5cbf45dc163d927fdbe0b3c Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 09:50:14 -0400 Subject: [PATCH 14/38] lint --- qiskit/extensions/standard/rzx.py | 9 +++++---- qiskit/extensions/standard/rzz.py | 1 - qiskit/extensions/standard/swap.py | 6 +++--- qiskit/extensions/standard/u1.py | 2 +- qiskit/extensions/standard/u3.py | 2 +- qiskit/extensions/standard/x.py | 6 +++--- qiskit/extensions/standard/y.py | 2 +- qiskit/extensions/standard/z.py | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index 2ecc429995ed..517d4551c72b 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -137,10 +137,11 @@ def inverse(self): # def to_matrix(self): # """Return a numpy.array for the RZX gate.""" # theta = self.params[0] - # return np.array([[np.exp(-1j*theta/2), 0, 0, 0], - # [0, np.exp(1j*theta/2), 0, 0], - # [0, 0, np.exp(1j*theta/2), 0], - # [0, 0, 0, np.exp(-1j*theta/2)]], dtype=complex) + # return np.array([[np.cos(theta/2), 0, -1j*np.sin(theta/2), 0], + # [0, np.cos(theta/2), 0, 1j*np.sin(theta/2)], + # [-1j*np.sin(theta/2), 0, np.cos(theta/2), 0], + # [0, 1j*np.sin(theta/2), 0, np.cos(theta/2)]], + # dtype=complex) def rzx(self, theta, qubit1, qubit2): diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index b2471c73008b..9cde98a276fc 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -15,7 +15,6 @@ """ Two-qubit ZZ-rotation gate. """ -import numpy as np from qiskit.circuit import Gate from qiskit.circuit import QuantumCircuit from qiskit.circuit import QuantumRegister diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index f849b0d8e12f..bc1a1c3dbbf8 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -142,11 +142,11 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. parsed-literal:: - + q_0: |0>─X─ - │ + │ q_1: |0>─X─ - │ + │ q_2: |0>─■─ diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 965905fc9d06..9614a8d21904 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -154,7 +154,7 @@ class CU1Gate(ControlledGate, metaclass=CU1Meta): q_0: |0>─■── - │λ + │λ q_1: |0>─■── diff --git a/qiskit/extensions/standard/u3.py b/qiskit/extensions/standard/u3.py index a256395f395c..7888a19bc142 100644 --- a/qiskit/extensions/standard/u3.py +++ b/qiskit/extensions/standard/u3.py @@ -150,7 +150,7 @@ class CU3Gate(ControlledGate, metaclass=CU3Meta): .. math:: \newcommand{\th}{\frac{\theta}{2}} - + CU3(\theta, \phi, \lambda)\ q_1, q_0= |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes U3(\theta,\phi,\lambda) = \begin{pmatrix} diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 47362f19b6c3..e25837752bc5 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -50,7 +50,7 @@ class XGate(Gate): Equivalent to a :math:`\pi` radian rotation about the X axis. .. note:: - + A global phase difference exists between the definitions of :math:`RX(\pi)` and :math:`X`. @@ -111,7 +111,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - r"""Return inverted X gate (:math:`X{\dagger} = X`)""" + r"""Return inverted X gate (itself)""" return XGate() # self-inverse def to_matrix(self): @@ -217,7 +217,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - """Return inverted CX gate (:math:`CX^{\dagger} = CX`)""" + """Return inverted CX gate (itself).""" return CXGate() # self-inverse def to_matrix(self): diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index eec579de8e9f..5745fc111b73 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -201,7 +201,7 @@ def _define(self): self.definition = definition def inverse(self): - """Return inverted CY gate (:math:`CY^{\dagger} = CY`)""" + """Return inverted CY gate (itself)""" return CYGate() # self-inverse def to_matrix(self): diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index 2a79fadc71ad..c36594bcdc6c 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -103,7 +103,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): ctrl_state=ctrl_state) def inverse(self): - r"""Return inverted Z gate (:math:`Z{\dagger} = Z`)""" + r"""Return inverted Z gate (itself).""" return ZGate() # self-inverse def to_matrix(self): @@ -185,7 +185,7 @@ def _define(self): self.definition = definition def inverse(self): - """Return inverted CZ gate (:math:`CZ^{\dagger} = CZ`)""" + """Return inverted CZ gate (itself).""" return CZGate() # self-inverse def to_matrix(self): From 9a7783026e6dc291c8b73c7316aaab29c3fd15c9 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 13:29:48 -0400 Subject: [PATCH 15/38] release notes --- qiskit/extensions/standard/rzx.py | 1 - .../notes/gate-documentation-5a376c8a471a13e1.yaml | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/gate-documentation-5a376c8a471a13e1.yaml diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index 517d4551c72b..f78931d90591 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -15,7 +15,6 @@ """ Two-qubit ZX-rotation gate. """ -import numpy as np from qiskit.circuit import Gate from qiskit.circuit import QuantumCircuit from qiskit.circuit import QuantumRegister diff --git a/releasenotes/notes/gate-documentation-5a376c8a471a13e1.yaml b/releasenotes/notes/gate-documentation-5a376c8a471a13e1.yaml new file mode 100644 index 000000000000..a44668617f6f --- /dev/null +++ b/releasenotes/notes/gate-documentation-5a376c8a471a13e1.yaml @@ -0,0 +1,7 @@ +--- +prelude: > + This release has vastly improved documentation across Qiskit. This + includes documentation for the circuit, pulse and quantum_info modules. + The documentation can be navigated at + `qiskit.org `_. + From d2ed88ea69557274eda84142f96a78dfeb355143 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 16:27:03 -0400 Subject: [PATCH 16/38] iswap def in terms of xx+yy --- qiskit/extensions/standard/h.py | 2 +- qiskit/extensions/standard/iswap.py | 4 +++- qiskit/extensions/standard/swap.py | 9 --------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/qiskit/extensions/standard/h.py b/qiskit/extensions/standard/h.py index 79039b5d22ce..6ed16ce6d222 100644 --- a/qiskit/extensions/standard/h.py +++ b/qiskit/extensions/standard/h.py @@ -49,7 +49,7 @@ class HGate(Gate): H = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1 \\ - 1 & -2 + 1 & -1 \end{pmatrix} """ diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index f961ab600c80..695473af8740 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -39,9 +39,11 @@ class iSwapGate(Gate): q_1: ─⨂─ **Matrix Representation:** + .. math:: - iSWAP = + iSWAP = R_{XX+YY}(-\frac{\pi}{2}) + = exp(i.\frac{\pi}{4}.(X{\otimes}X+Y{\otimes}Y)) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0 \\ diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index bc1a1c3dbbf8..f55a369275ce 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -28,15 +28,6 @@ class SwapGate(Gate): This is a symmetric and Clifford gate. - **Matrix Representation:** - - .. math:: - - Z = \begin{pmatrix} - 0 & 0 & \\ - 0 & -1 - \end{pmatrix} - **Circuit symbol:** .. parsed-literal:: From 58f674fcc2d0a6a7573e0ced581edebfe9ae857f Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 16:40:43 -0400 Subject: [PATCH 17/38] lint --- qiskit/extensions/standard/swap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index f55a369275ce..6e27ca352128 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -146,7 +146,7 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. math:: CSWAP\ q_2, q_1, q_0 = - |0\rangle\langle0| \otimes I \otimes I + |1\rangle\langle1| \otimes SWAP = + |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle 1| \otimes SWAP = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ From 668fe55c4ba78fff6b43bfdb9c8758eb1206cc48 Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 22:01:22 -0400 Subject: [PATCH 18/38] correct phase in RY definition and add reference implementation for iswap --- qiskit/extensions/standard/iswap.py | 20 +++++- qiskit/extensions/standard/ms.py | 17 ++--- qiskit/extensions/standard/rxx.py | 55 ++++++++++++-- qiskit/extensions/standard/ryy.py | 76 +++++++++++++++----- qiskit/extensions/standard/rzz.py | 14 ++-- qiskit/extensions/standard/swap.py | 2 +- test/python/circuit/test_gate_definitions.py | 21 +----- 7 files changed, 147 insertions(+), 58 deletions(-) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index 695473af8740..7337e677d53f 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -25,7 +25,7 @@ class iSwapGate(Gate): r"""iSWAP gate. - A 2-qubit XX+YY interaction that is equivalent to a SWAP up to a diagonal. + A 2-qubit XX+YY interaction. This is a Clifford and symmetric gate. Its action is to swap two qubit states and phase the :math:`|01\rangle` and :math:`|10\rangle` amplitudes by i. @@ -38,6 +38,16 @@ class iSwapGate(Gate): │ q_1: ─⨂─ + **Reference Implementation:** + + .. parsed-literal:: + + ┌───┐┌───┐ ┌───┐ + q_0: ┤ S ├┤ H ├──■──┤ X ├───── + ├───┤└───┘┌─┴─┐└─┬─┘┌───┐ + q_1: ┤ S ├─────┤ X ├──■──┤ H ├ + └───┘ └───┘ └───┘ + **Matrix Representation:** .. math:: @@ -50,7 +60,13 @@ class iSwapGate(Gate): 0 & i & 0 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} - = \begin{pmatrix} + + This gate is equivalent to a SWAP up to a diagonal. + + .. math:: + + iSWAP = + \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ diff --git a/qiskit/extensions/standard/ms.py b/qiskit/extensions/standard/ms.py index 8c626dfc75b3..850841e8e807 100644 --- a/qiskit/extensions/standard/ms.py +++ b/qiskit/extensions/standard/ms.py @@ -16,12 +16,6 @@ """ Global Mølmer–Sørensen gate. - -The Mølmer–Sørensen gate is native to ion-trap systems. The global MS can be -applied to multiple ions to entangle multiple qubits simultaneously. - -In the two-qubit case, this is equivalent to an XX(theta) interaction, -and is thus reduced to the RXXGate. """ @@ -31,7 +25,14 @@ class MSGate(Gate): - """Global Molmer-Sorensen gate.""" + """Global Mølmer–Sørensen gate. + + The Mølmer–Sørensen gate is native to ion-trap systems. The global MS can be + applied to multiple ions to entangle multiple qubits simultaneously. + + In the two-qubit case, this is equivalent to an XX(theta) interaction, + and is thus reduced to the RXXGate. + """ def __init__(self, n_qubits, theta): """Create new MS gate.""" @@ -52,7 +53,7 @@ def _define(self): def ms(self, theta, qubits): - """Apply MS to q1 and q2.""" + """Apply :class:`~qiskit.extensions.standard.MSGate`.""" return self.append(MSGate(len(qubits), theta), qubits) diff --git a/qiskit/extensions/standard/rxx.py b/qiskit/extensions/standard/rxx.py index 1a36c666e325..2e1e32aa53bb 100644 --- a/qiskit/extensions/standard/rxx.py +++ b/qiskit/extensions/standard/rxx.py @@ -21,14 +21,57 @@ class RXXGate(Gate): - """Two-qubit XX-rotation gate. + r"""A parameteric 2-qubit :math:`X \otimes X` interaction (rotation about XX). - This gate corresponds to the rotation U(θ) = exp(-1j * θ * X⊗X / 2) - up to the phase exp(-1j * θ/2). + This gate is symmetric, and is maximally entangling at :math:`\theta = \pi/2`. + + **Circuit Symbol:** + + .. parsed-literal:: + + ┌─────────┐ + q_0: ┤1 ├ + │ Rxx(ϴ) │ + q_1: ┤0 ├ + └─────────┘ + + **Matrix Representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + R_{XX}(\theta) = exp(-i.\frac{\theta}{2}.X{\otimes}X) = + \begin{pmatrix} + \cos(\th) & 0 & 0 & -i\sin(\th) \\ + 0 & \cos(\th) & -i\sin(\th) & 0 \\ + 0 & -i\sin(\th) & \cos(\th) & 0 \\ + -i\sin(\th) & 0 & 0 & \cos(\th)} + \end{pmatrix} + + **Examples:** + + .. math:: + + R_{XX}(\theta = 0) = I + + .. math:: + + R_{XX}(\theta = \pi) = i X \otimes X + + .. math:: + + R_{XX}(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & 0 & 0 & -i \\ + 0 & 1 & -i & 0 \\ + 0 & -i & 1 & 0 \\ + -i & 0 & 0 & 1 + \end{pmatrix} """ def __init__(self, theta): - """Create new rxx gate.""" + """Create new RXX gate.""" super().__init__('rxx', 2, [theta]) def _define(self): @@ -53,7 +96,7 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RXX gate (i.e. with the negative rotation angle).""" return RXXGate(-self.params[0]) # NOTE: we should use the following as the canonical matrix @@ -70,7 +113,7 @@ def inverse(self): def rxx(self, theta, qubit1, qubit2): - """Apply RXX to circuit.""" + """Apply :class:`~qiskit.extensions.standard.RXXGate`.""" return self.append(RXXGate(theta), [qubit1, qubit2], []) diff --git a/qiskit/extensions/standard/ryy.py b/qiskit/extensions/standard/ryy.py index f8acdf9e208a..10242ddfd2e7 100644 --- a/qiskit/extensions/standard/ryy.py +++ b/qiskit/extensions/standard/ryy.py @@ -22,14 +22,57 @@ class RYYGate(Gate): - r"""Two-qubit YY-rotation gate. + r"""A parameteric 2-qubit :math:`Y \otimes Y` interaction (rotation about YY). - This gate corresponds to the rotation :math:`U(\theta) = e^{-i\theta / 2 Y \otimes Y)`, - multiplied by the phase :math:`e^{i \theta / 2}`. + This gate is symmetric, and is maximally entangling at :math:`\theta = \pi/2`. + + **Circuit Symbol:** + + .. parsed-literal:: + + ┌─────────┐ + q_0: ┤1 ├ + │ Ryy(ϴ) │ + q_1: ┤0 ├ + └─────────┘ + + **Matrix Representation:** + + .. math:: + + \newcommand{\th}{\frac{\theta}{2}} + + R_{YY}(\theta) = exp(-i.\frac{\theta}{2}.Y{\otimes}Y) = + \begin{pmatrix} + \cos(\th) & 0 & 0 & i\sin(\th) \\ + 0 & \cos(\th) & -i\sin(\th) & 0 \\ + 0 & -i\sin(\th) & \cos(\th) & 0 \\ + i\sin(\th) & 0 & 0 & \cos(\th)} + \end{pmatrix} + + **Examples:** + + .. math:: + + R_{YY}(\theta = 0) = I + + .. math:: + + R_{YY}(\theta = \pi) = i Y \otimes Y + + .. math:: + + R_{YY}(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} + \begin{pmatrix} + 1 & 0 & 0 & i \\ + 0 & 1 & -i & 0 \\ + 0 & -i & 1 & 0 \\ + i & 0 & 0 & 1 + \end{pmatrix} """ def __init__(self, theta): - """Create new ryy gate.""" + """Create new RYY gate.""" super().__init__('ryy', 2, [theta]) def _define(self): @@ -55,24 +98,25 @@ def _define(self): self.definition = definition def inverse(self): - """Invert this gate.""" + """Return inverse RYY gate (i.e. with the negative rotation angle).""" return RYYGate(-self.params[0]) - def to_matrix(self): - """Return a numpy.arry for the RYY gate.""" - theta = self.params[0] - return np.exp(0.5j * theta) * np.array([ - [np.cos(theta / 2), 0, 0, 1j * np.sin(theta / 2)], - [0, np.cos(theta / 2), -1j * np.sin(theta / 2), 0], - [0, -1j * np.sin(theta / 2), np.cos(theta / 2), 0], - [1j * np.sin(theta / 2), 0, 0, np.cos(theta / 2)] - ], dtype=complex) + # TODO: this is the correct definition but has a global phase with respect + # to the decomposition above. Restore after allowing phase on circuits. + # def to_matrix(self): + # """Return a numpy.arry for the RYY gate.""" + # theta = self.params[0] + # return np.array([ + # [np.cos(theta / 2), 0, 0, 1j * np.sin(theta / 2)], + # [0, np.cos(theta / 2), -1j * np.sin(theta / 2), 0], + # [0, -1j * np.sin(theta / 2), np.cos(theta / 2), 0], + # [1j * np.sin(theta / 2), 0, 0, np.cos(theta / 2)] + # ], dtype=complex) def ryy(self, theta, qubit1, qubit2): - """Apply RYY to circuit.""" + """Apply :class:`~qiskit.extensions.standard.RYYGate`.""" return self.append(RYYGate(theta), [qubit1, qubit2], []) -# Add to QuantumCircuit class QuantumCircuit.ryy = ryy diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index 9cde98a276fc..d83157a18a32 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -37,7 +37,7 @@ class RZZGate(Gate): .. math:: - RZZ(\theta) = exp(-i.\frac{\theta}{2}.Z{\otimes}Z) = + R_{ZZ}(\theta) = exp(-i.\frac{\theta}{2}.Z{\otimes}Z) = \begin{pmatrix} e^{-i\frac{\theta}{2}} & 0 & 0 & 0 \\ 0 & e^{i\frac{\theta}{2}} & 0 & 0 \\ @@ -50,7 +50,7 @@ class RZZGate(Gate): .. math:: - RZZ(\theta) = + R_{ZZ}(\theta) = \begin{pmatrix} RZ(\theta) & 0 \\ 0 & RZ(-\theta) @@ -60,19 +60,19 @@ class RZZGate(Gate): .. math:: - RZZ(\theta = 0) = I + R_{ZZ}(\theta = 0) = I .. math:: - RZZ(\theta = 2\pi) = -I + R_{ZZ}(\theta = 2\pi) = -I .. math:: - RZZ(\theta = \pi) = - Z \otimes Z + R_{ZZ}(\theta = \pi) = - Z \otimes Z .. math:: - RZZ(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} + R_{ZZ}(\theta = \frac{\pi}{2}) = \frac{1}{\sqrt{2}} \begin{pmatrix} 1-i & 0 & 0 & 0 \\ 0 & 1+i & 0 & 0 \\ @@ -82,6 +82,7 @@ class RZZGate(Gate): """ def __init__(self, theta): + """Create new RZZ gate.""" super().__init__('rzz', 2, [theta]) def _define(self): @@ -121,5 +122,4 @@ def rzz(self, theta, qubit1, qubit2): return self.append(RZZGate(theta), [qubit1, qubit2], []) -# Add to QuantumCircuit class QuantumCircuit.rzz = rzz diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index 6e27ca352128..24f9276d5349 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -169,7 +169,7 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. math:: CSWAP\ q_0, q_1, q_2 = - |0\rangle\langle0| \otimes I \otimes I + |1\rangle\langle1| \otimes SWAP = + |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle 1| \otimes SWAP = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ diff --git a/test/python/circuit/test_gate_definitions.py b/test/python/circuit/test_gate_definitions.py index 5b6da673b39d..728d67ac8cfd 100644 --- a/test/python/circuit/test_gate_definitions.py +++ b/test/python/circuit/test_gate_definitions.py @@ -19,10 +19,9 @@ from ddt import ddt, data -from qiskit import QuantumCircuit, BasicAer, execute +from qiskit import QuantumCircuit from qiskit.quantum_info import Operator from qiskit.test import QiskitTestCase -from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.circuit import ParameterVector @@ -30,7 +29,7 @@ HGate, CHGate, IGate, RGate, RXGate, CRXGate, RYGate, CRYGate, RZGate, CRZGate, SGate, SdgGate, CSwapGate, TGate, TdgGate, U1Gate, CU1Gate, U2Gate, U3Gate, CU3Gate, XGate, CXGate, CCXGate, YGate, CYGate, - ZGate, CZGate + ZGate, CZGate, RYYGate ) from qiskit.extensions.standard.equivalence_library import StandardEquivalenceLibrary as std_eqlib @@ -112,20 +111,6 @@ def test_cx_definition(self): decomposed_circ = circ.decompose() self.assertTrue(Operator(circ).equiv(Operator(decomposed_circ))) - def test_ryy_matrix_representation(self): - """Test the matrix representation of the RYY gate. - """ - from qiskit.extensions.standard.ryy import RYYGate - theta = 0.991283 - expected = RYYGate(theta).to_matrix() - - circuit = QuantumCircuit(2) - circuit.ryy(theta, 0, 1) - backend = BasicAer.get_backend('unitary_simulator') - simulated = execute(circuit, backend).result().get_unitary() - - self.assertTrue(matrix_equal(expected, simulated)) - @ddt class TestStandardEquivalenceLibrary(QiskitTestCase): @@ -135,7 +120,7 @@ class TestStandardEquivalenceLibrary(QiskitTestCase): HGate, CHGate, IGate, RGate, RXGate, CRXGate, RYGate, CRYGate, RZGate, CRZGate, SGate, SdgGate, CSwapGate, TGate, TdgGate, U1Gate, CU1Gate, U2Gate, U3Gate, CU3Gate, XGate, CXGate, CCXGate, YGate, CYGate, - ZGate, CZGate + ZGate, CZGate, RYYGate ) def test_definition_parameters(self, gate_class): """Verify decompositions from standard equivalence library match definitions.""" From b05187dfa29e268669c2e8417fc970f4b103847b Mon Sep 17 00:00:00 2001 From: Ali Javadi Date: Wed, 25 Mar 2020 22:41:28 -0400 Subject: [PATCH 19/38] change u1->rz in RZZ definition --- qiskit/extensions/standard/iswap.py | 2 +- qiskit/extensions/standard/rxx.py | 25 +++++++++++++------------ qiskit/extensions/standard/ryy.py | 14 ++++++++------ qiskit/extensions/standard/rz.py | 8 ++++++++ qiskit/extensions/standard/rzz.py | 12 ++++++------ qiskit/extensions/standard/swap.py | 20 +++++++++++--------- qiskit/extensions/standard/u1.py | 6 +++--- qiskit/extensions/standard/x.py | 8 ++++---- qiskit/extensions/standard/y.py | 8 ++++---- qiskit/extensions/standard/z.py | 9 ++++----- 10 files changed, 62 insertions(+), 50 deletions(-) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index 7337e677d53f..4b74803adfb2 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -42,7 +42,7 @@ class iSwapGate(Gate): .. parsed-literal:: - ┌───┐┌───┐ ┌───┐ + ┌───┐┌───┐ ┌───┐ q_0: ┤ S ├┤ H ├──■──┤ X ├───── ├───┤└───┘┌─┴─┐└─┬─┘┌───┐ q_1: ┤ S ├─────┤ X ├──■──┤ H ├ diff --git a/qiskit/extensions/standard/rxx.py b/qiskit/extensions/standard/rxx.py index 2e1e32aa53bb..a3d27c045016 100644 --- a/qiskit/extensions/standard/rxx.py +++ b/qiskit/extensions/standard/rxx.py @@ -77,7 +77,7 @@ def __init__(self, theta): def _define(self): """Calculate a subcircuit that implements this unitary.""" from qiskit.extensions.standard.x import CXGate - from qiskit.extensions.standard.u1 import U1Gate + from qiskit.extensions.standard.rz import RZGate from qiskit.extensions.standard.h import HGate definition = [] q = QuantumRegister(2, 'q') @@ -86,7 +86,7 @@ def _define(self): (HGate(), [q[0]], []), (HGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []), - (U1Gate(theta), [q[1]], []), + (RZGate(theta), [q[1]], []), (CXGate(), [q[0], q[1]], []), (HGate(), [q[1]], []), (HGate(), [q[0]], []), @@ -99,17 +99,18 @@ def inverse(self): """Return inverse RXX gate (i.e. with the negative rotation angle).""" return RXXGate(-self.params[0]) - # NOTE: we should use the following as the canonical matrix - # definition but we don't include it yet since it differs from - # the circuit decomposition matrix by a global phase + # TODO: this is the correct matrix and is equal to the definition above, + # however the control mechanism cannot distinguish U1 and RZ yet. # def to_matrix(self): - # """Return a Numpy.array for the RXX gate.""" - # theta = float(self.params[0]) - # return np.array([ - # [np.cos(theta / 2), 0, 0, -1j * np.sin(theta / 2)], - # [0, np.cos(theta / 2), -1j * np.sin(theta / 2), 0], - # [0, -1j * np.sin(theta / 2), np.cos(theta / 2), 0], - # [-1j * np.sin(theta / 2), 0, 0, np.cos(theta / 2)]], dtype=complex) + # """Return a Numpy.array for the RXX gate.""" + # theta = float(self.params[0]) + # cos = np.cos(theta / 2) + # sin = np.sin(theta / 2) + # return np.array([ + # [cos, 0, 0, -1j * sin], + # [0, cos, -1j * sin, 0], + # [0, -1j * sin, cos, 0], + # [-1j * sin, 0, 0, cos]], dtype=complex) def rxx(self, theta, qubit1, qubit2): diff --git a/qiskit/extensions/standard/ryy.py b/qiskit/extensions/standard/ryy.py index 10242ddfd2e7..e756ca592e1b 100644 --- a/qiskit/extensions/standard/ryy.py +++ b/qiskit/extensions/standard/ryy.py @@ -101,16 +101,18 @@ def inverse(self): """Return inverse RYY gate (i.e. with the negative rotation angle).""" return RYYGate(-self.params[0]) - # TODO: this is the correct definition but has a global phase with respect - # to the decomposition above. Restore after allowing phase on circuits. + # TODO: this is the correct matrix and is equal to the definition above, + # however the control mechanism cannot distinguish U1 and RZ yet. # def to_matrix(self): # """Return a numpy.arry for the RYY gate.""" # theta = self.params[0] + # cos = np.cos(theta / 2) + # sin = np.sin(theta / 2) # return np.array([ - # [np.cos(theta / 2), 0, 0, 1j * np.sin(theta / 2)], - # [0, np.cos(theta / 2), -1j * np.sin(theta / 2), 0], - # [0, -1j * np.sin(theta / 2), np.cos(theta / 2), 0], - # [1j * np.sin(theta / 2), 0, 0, np.cos(theta / 2)] + # [cos, 0, 0, 1j * sin], + # [0, cos, -1j * sin, 0], + # [0, -1j * sin, cos, 0], + # [1j * sin, 0, 0, cos] # ], dtype=complex) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index cd7f31d84aed..9c5c7b743e21 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -101,6 +101,14 @@ def inverse(self): """ return RZGate(-self.params[0]) + # TODO: this is the correct matrix however the control mechanism + # cannot distinguish U1 and RZ yet. + # def to_matrix(self): + # """Return a numpy.array for the RZ gate.""" + # lam = float(self.params[0]) + # return np.array([[np.exp(-1j * lam / 2), 0], + # [0, np.exp(1j * lam / 2)]], dtype=complex) + @deprecate_arguments({'q': 'qubit'}) def rz(self, phi, qubit, *, q=None): # pylint: disable=invalid-name,unused-argument diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index d83157a18a32..bec7b12dd377 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -87,15 +87,15 @@ def __init__(self, theta): def _define(self): """ - gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; } + gate rzz(theta) a, b { cx a, b; rz(theta) b; cx a, b; } """ - from qiskit.extensions.standard.u1 import U1Gate + from qiskit.extensions.standard.rz import RZGate from qiskit.extensions.standard.x import CXGate definition = [] q = QuantumRegister(2, 'q') rule = [ (CXGate(), [q[0], q[1]], []), - (U1Gate(self.params[0]), [q[1]], []), + (RZGate(self.params[0]), [q[1]], []), (CXGate(), [q[0], q[1]], []) ] for inst in rule: @@ -106,11 +106,11 @@ def inverse(self): """Return inverse RZZ gate (i.e. with the negative rotation angle).""" return RZZGate(-self.params[0]) - # TODO: this is the correct definition but has a global phase with respect - # to the decomposition above. Restore after allowing phase on circuits. + # TODO: this is the correct matrix and is equal to the definition above, + # however the control mechanism cannot distinguish U1 and RZ yet. # def to_matrix(self): # """Return a numpy.array for the RZZ gate.""" - # theta = self.params[0] + # theta = float(self.params[0]) # return np.array([[np.exp(-1j*theta/2), 0, 0, 0], # [0, np.exp(1j*theta/2), 0, 0], # [0, 0, np.exp(1j*theta/2), 0], diff --git a/qiskit/extensions/standard/swap.py b/qiskit/extensions/standard/swap.py index 24f9276d5349..1a437abd8821 100644 --- a/qiskit/extensions/standard/swap.py +++ b/qiskit/extensions/standard/swap.py @@ -134,11 +134,11 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. parsed-literal:: - q_0: |0>─X─ - │ - q_1: |0>─X─ - │ - q_2: |0>─■─ + q_0: ─X─ + │ + q_1: ─X─ + │ + q_2: ─■─ **Matrix representation:** @@ -146,7 +146,8 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. math:: CSWAP\ q_2, q_1, q_0 = - |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle 1| \otimes SWAP = + |0 \rangle \langle 0| \otimes I \otimes I + + |1 \rangle \langle 1| \otimes SWAP = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ @@ -169,7 +170,8 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): .. math:: CSWAP\ q_0, q_1, q_2 = - |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle 1| \otimes SWAP = + |0 \rangle \langle 0| \otimes I \otimes I + + |1 \rangle \langle 1| \otimes SWAP = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ @@ -186,8 +188,8 @@ class CSwapGate(ControlledGate, metaclass=CSwapMeta): :math:`|1\rangle` state. .. math:: - `|0, b, c\rangle \rightarrow |0, b, c\rangle` - `|1, b, c\rangle \rightarrow |1, c, b\rangle` + |0, b, c\rangle \rightarrow |0, b, c\rangle + |1, b, c\rangle \rightarrow |1, c, b\rangle """ def __init__(self): diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 9614a8d21904..3cba37635bc3 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -153,9 +153,9 @@ class CU1Gate(ControlledGate, metaclass=CU1Meta): .. parsed-literal:: - q_0: |0>─■── - │λ - q_1: |0>─■── + q_0: ─■── + │λ + q_1: ─■── **Matrix representation:** diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index e25837752bc5..fee468eda33a 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -147,10 +147,10 @@ class CXGate(ControlledGate, metaclass=CXMeta): .. parsed-literal:: - ┌───┐ - q_0: |0>┤ X ├ - └─┬─┘ - q_1: |0>──■── + ┌───┐ + q_0: ┤ X ├ + └─┬─┘ + q_1: ──■── **Matrix representation:** diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index 5745fc111b73..3c30ccf922db 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -138,10 +138,10 @@ class CYGate(ControlledGate, metaclass=CYMeta): .. parsed-literal:: - ┌───┐ - q_0: |0>┤ Y ├ - └─┬─┘ - q_1: |0>──■── + ┌───┐ + q_0: ┤ Y ├ + └─┬─┘ + q_1: ──■── **Matrix representation:** diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index c36594bcdc6c..201d2b89cb1b 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -139,11 +139,10 @@ class CZGate(ControlledGate, metaclass=CZMeta): .. parsed-literal:: - ┌───┐ - q_0: |0>┤ Z ├ - └─┬─┘ - q_1: |0>──■── - + ┌───┐ + q_0: ┤ Z ├ + └─┬─┘ + q_1: ──■── **Matrix representation:** From 906dac95c0967da0daf5d5d62271157f7e868b28 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 10:06:05 -0400 Subject: [PATCH 20/38] Update qiskit/extensions/standard/rzx.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rzx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index f78931d90591..c9f56c86bab0 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2017, 2020. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory From 42905484b52ca4b28208f4df4979f5f5bf684d09 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 10:06:11 -0400 Subject: [PATCH 21/38] Update qiskit/extensions/standard/rz.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index 9c5c7b743e21..2bf1e7e0a380 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -40,7 +40,7 @@ class RZGate(Gate): .. math:: - RZ(\lambda) = exp(-i\frac{\theta}{2}Z) = + RZ(\lambda) = exp(-i\frac{\lambda}{2}Z) = \begin{pmatrix} e^{-i\frac{\lambda}{2}} & 0 \\ 0 & e^{i\frac{\lambda}{2}} From b437485df8a80e6176e030d55eff62b128bc5b79 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 10:10:19 -0400 Subject: [PATCH 22/38] Update rz.py --- qiskit/extensions/standard/rz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rz.py b/qiskit/extensions/standard/rz.py index 2bf1e7e0a380..b8470ef52b3b 100644 --- a/qiskit/extensions/standard/rz.py +++ b/qiskit/extensions/standard/rz.py @@ -53,7 +53,7 @@ class RZGate(Gate): .. math:: - U1(\lambda) = e^{i.{\lambda}/2}.RZ(\lambda) + U1(\lambda) = e^{i{\lambda}/2}RZ(\lambda) Reference for virtual Z gate implementation: `1612.00858 `_ From a8b511d729e68b9258464de3c4b72413afea7a35 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:46:57 -0400 Subject: [PATCH 23/38] Update qiskit/extensions/standard/rxx.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rxx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rxx.py b/qiskit/extensions/standard/rxx.py index a3d27c045016..c928d1035e06 100644 --- a/qiskit/extensions/standard/rxx.py +++ b/qiskit/extensions/standard/rxx.py @@ -41,7 +41,7 @@ class RXXGate(Gate): \newcommand{\th}{\frac{\theta}{2}} - R_{XX}(\theta) = exp(-i.\frac{\theta}{2}.X{\otimes}X) = + R_{XX}(\theta) = exp(-i \frac{\theta}{2} X{\otimes}X) = \begin{pmatrix} \cos(\th) & 0 & 0 & -i\sin(\th) \\ 0 & \cos(\th) & -i\sin(\th) & 0 \\ From 408e322cc55daee57ef64274439f87d9ae9de321 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:47:27 -0400 Subject: [PATCH 24/38] Update qiskit/extensions/standard/iswap.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/iswap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/iswap.py b/qiskit/extensions/standard/iswap.py index 4b74803adfb2..2391f420f2e3 100644 --- a/qiskit/extensions/standard/iswap.py +++ b/qiskit/extensions/standard/iswap.py @@ -53,7 +53,7 @@ class iSwapGate(Gate): .. math:: iSWAP = R_{XX+YY}(-\frac{\pi}{2}) - = exp(i.\frac{\pi}{4}.(X{\otimes}X+Y{\otimes}Y)) = + = exp(i \frac{\pi}{4} (X{\otimes}X+Y{\otimes}Y)) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0 \\ From a2095bbec85b761f5a698c4f22bb39f3f84ecae3 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:47:36 -0400 Subject: [PATCH 25/38] Update qiskit/extensions/standard/ry.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/ry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/ry.py b/qiskit/extensions/standard/ry.py index 3b581cde20ef..b60b2d737f86 100644 --- a/qiskit/extensions/standard/ry.py +++ b/qiskit/extensions/standard/ry.py @@ -139,7 +139,7 @@ class CRYGate(ControlledGate, metaclass=CRYMeta): \newcommand{\th}{\frac{\theta}{2}} CRY(\theta)\ q_1, q_0 = - |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes RY(\theta) = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes RY(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ From 81b8c7adb787f3859420471c521348ac452a48cb Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:47:46 -0400 Subject: [PATCH 26/38] Update qiskit/extensions/standard/rzx.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rzx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index c9f56c86bab0..2db185e4c8b2 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -44,7 +44,7 @@ class RZXGate(Gate): \newcommand{\th}{\frac{\theta}{2}} - R_{ZX}(\theta)\ q_1, q_0 = exp(-i.\frac{\theta}{2}.Z{\otimes}X) = + R_{ZX}(\theta)\ q_1, q_0 = exp(-i \frac{\theta}{2} Z{\otimes}X) = \begin{pmatrix} \cos(\th) & -i\sin(\th) & 0 & 0 \\ -i\sin(\th) & \cos(\th) & 0 & 0 \\ From 8bc124c8bd65461ab581ea9bb5043edd95785030 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:08 -0400 Subject: [PATCH 27/38] Update qiskit/extensions/standard/rzx.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rzx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rzx.py b/qiskit/extensions/standard/rzx.py index 2db185e4c8b2..f617db53c8e4 100644 --- a/qiskit/extensions/standard/rzx.py +++ b/qiskit/extensions/standard/rzx.py @@ -74,7 +74,7 @@ class RZXGate(Gate): \newcommand{\th}{\frac{\theta}{2}} - R_{ZX}(\theta)\ q_0, q_1 = exp(-i.\frac{\theta}{2}.X{\otimes}Z) = + R_{ZX}(\theta)\ q_0, q_1 = exp(-i \frac{\theta}{2} X{\otimes}Z) = \begin{pmatrix} \cos(\th) & 0 & -i\sin(\th) & 0 \\ 0 & \cos(\th) & 0 & i\sin(\th) \\ From 4d7986fd88f8f764a1d60ec75e1263834bcf8e67 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:16 -0400 Subject: [PATCH 28/38] Update qiskit/extensions/standard/u1.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/u1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/u1.py b/qiskit/extensions/standard/u1.py index 3cba37635bc3..b6df08f8bf3c 100644 --- a/qiskit/extensions/standard/u1.py +++ b/qiskit/extensions/standard/u1.py @@ -69,7 +69,7 @@ class U1Gate(Gate): .. math:: - U1(\lambda) = e^{i{\lambda}/2}.RZ(\lambda) + U1(\lambda) = e^{i{\lambda}/2} RZ(\lambda) :class:`~qiskit.extensions.standard.U3Gate`: U3 is a generalization of U2 that covers all single-qubit rotations, From 2c9981100b9264f377f863d4f2612f0941273653 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:25 -0400 Subject: [PATCH 29/38] Update qiskit/extensions/standard/u3.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/u3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/u3.py b/qiskit/extensions/standard/u3.py index 7888a19bc142..08cfe31ea6ba 100644 --- a/qiskit/extensions/standard/u3.py +++ b/qiskit/extensions/standard/u3.py @@ -31,7 +31,7 @@ class U3Gate(Gate): Implemented using two X90 pulses on IBM Quantum systems: .. math:: - U2(\phi, \lambda) = RZ(\phi+\pi/2).RX(\frac{\pi}{2}).RZ(\lambda-\pi/2) + U2(\phi, \lambda) = RZ(\phi+\pi/2) RX(\frac{\pi}{2}) RZ(\lambda-\pi/2) **Circuit symbol:** From c60426498056ac1e8bfc10cdade87c22cd08d417 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:36 -0400 Subject: [PATCH 30/38] Update qiskit/extensions/standard/x.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index fee468eda33a..53c83e9ee1f6 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -177,7 +177,7 @@ class CXGate(ControlledGate, metaclass=CXMeta): .. math:: CX\ q_0, q_1 = - I \otimes |0\rangle\langle0| + Y \otimes |1\rangle\langle1| = + I \otimes |0\rangle\langle 0| + Y \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ From 3e8d8a2fe59b70faa26cc54d4870dd59179e5adb Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:47 -0400 Subject: [PATCH 31/38] Update qiskit/extensions/standard/x.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 53c83e9ee1f6..883af9877ebd 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -284,7 +284,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: CCX\ q_2, q_1, q_0 = - I \otimes I \otimes |0\rangle\langle 0| + CX \otimes |1\rangle\langle1| = + I \otimes I \otimes |0\rangle\langle 0| + CX \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ From 3840035605c6672faca6522b47a2e96cd877fa1f Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:48:56 -0400 Subject: [PATCH 32/38] Update qiskit/extensions/standard/x.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index 883af9877ebd..afd0a7d85953 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -60,7 +60,7 @@ class XGate(Gate): 0 & -i \\ -i & 0 \end{pmatrix} - = -i.X + = -i X The gate is equivalent to a classical bit flip. From 7f4c9089b650fddfbfb448bec94b87844ee1485e Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:49:04 -0400 Subject: [PATCH 33/38] Update qiskit/extensions/standard/rzz.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/rzz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/rzz.py b/qiskit/extensions/standard/rzz.py index bec7b12dd377..0464941ae079 100644 --- a/qiskit/extensions/standard/rzz.py +++ b/qiskit/extensions/standard/rzz.py @@ -37,7 +37,7 @@ class RZZGate(Gate): .. math:: - R_{ZZ}(\theta) = exp(-i.\frac{\theta}{2}.Z{\otimes}Z) = + R_{ZZ}(\theta) = exp(-i \frac{\theta}{2} Z{\otimes}Z) = \begin{pmatrix} e^{-i\frac{\theta}{2}} & 0 & 0 & 0 \\ 0 & e^{i\frac{\theta}{2}} & 0 & 0 \\ From 743cd8fc6115bb80d3d4defec18739c099b528ba Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:49:33 -0400 Subject: [PATCH 34/38] Update qiskit/extensions/standard/x.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/x.py b/qiskit/extensions/standard/x.py index afd0a7d85953..10bb860bd52c 100644 --- a/qiskit/extensions/standard/x.py +++ b/qiskit/extensions/standard/x.py @@ -307,7 +307,7 @@ class CCXGate(ControlledGate, metaclass=CCXMeta): .. math:: CCX q_0, q_1, q_2 = - |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle1| \otimes CX = + |0\rangle\langle 0| \otimes I \otimes I + |1\rangle\langle 1| \otimes CX = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ From f7d7c0119fc331671bbd321c333ff4759594eb2a Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:49:41 -0400 Subject: [PATCH 35/38] Update qiskit/extensions/standard/y.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/y.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index 3c30ccf922db..be7361920560 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -149,7 +149,7 @@ class CYGate(ControlledGate, metaclass=CYMeta): .. math:: CY\ q_1, q_0 = - |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes Y = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes Y = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ From a77d823b52b4281ce3fec33d2df05cd56c9922d1 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:49:48 -0400 Subject: [PATCH 36/38] Update qiskit/extensions/standard/y.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/y.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index be7361920560..240cb5e7244b 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -168,7 +168,7 @@ class CYGate(ControlledGate, metaclass=CYMeta): .. math:: CY\ q_0, q_1 = - I \otimes |0\rangle\langle0| + Y \otimes |1\rangle\langle1| = + I \otimes |0\rangle\langle 0| + Y \otimes |1\rangle\langle 1| = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & -i \\ From 0469f3c4dbe457f4da7ae692923509da42add275 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:49:55 -0400 Subject: [PATCH 37/38] Update qiskit/extensions/standard/z.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/z.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/z.py b/qiskit/extensions/standard/z.py index 201d2b89cb1b..56b4d73fae3a 100644 --- a/qiskit/extensions/standard/z.py +++ b/qiskit/extensions/standard/z.py @@ -149,7 +149,7 @@ class CZGate(ControlledGate, metaclass=CZMeta): .. math:: CZ\ q_1, q_0 = - |0\rangle\langle0| \otimes I + |1\rangle\langle1| \otimes Z = + |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes Z = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ From 0299f8c942745814697fd286f925943bdd130ff4 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Thu, 26 Mar 2020 13:50:04 -0400 Subject: [PATCH 38/38] Update qiskit/extensions/standard/y.py Co-Authored-By: Julien Gacon --- qiskit/extensions/standard/y.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/extensions/standard/y.py b/qiskit/extensions/standard/y.py index 240cb5e7244b..84871ea34621 100644 --- a/qiskit/extensions/standard/y.py +++ b/qiskit/extensions/standard/y.py @@ -57,7 +57,7 @@ class YGate(Gate): 0 & -1 \\ 1 & 0 \end{pmatrix} - = -i.Y + = -i Y The gate is equivalent to a bit and phase flip.