Source code for mimiqcircuits.operations.gates.standard.cu

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

import mimiqcircuits.operations.control as mctrl
from mimiqcircuits.operations.gates.standard.cpauli import GateCX
from mimiqcircuits.operations.gates.standard.u import GateU
from mimiqcircuits.operations.gates.standard.phase import GateP


[docs] class GateCU(mctrl.Control): r"""Two qubit controlled unitary gate. **Matrix representation:** .. math:: \operatorname{CU}(\theta, \phi, \lambda, \gamma) = \frac{1}{2} e^{i\gamma} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & e^{i\gamma} \cos\left(\frac{\theta}{2}\right) & -e^{i\gamma} e^{i\lambda}\sin\left(\frac{\theta}{2}\right) \\ 0 & 0 & e^{i\gamma} \mathrm{e}^{i\phi}\sin\left(\frac{\theta}{2}\right) & e^{i\gamma} \mathrm{e}^{i(\phi+\lambda)}\cos\left(\frac{\theta}{2}\right) \end{pmatrix} Parameters: theta (float): Euler angle 1 in radians. phi (float): Euler angle 2 in radians. lmbda (float): Euler angle 3 in radians. gamma (float): Global phase of the CU gate. Examples: >>> from mimiqcircuits import * >>> from symengine import * >>> theta, phi, lmbda, gamma = symbols('theta phi lambda gamma') >>> GateCU(theta, phi, lmbda, gamma), GateCU(theta, phi, lmbda, gamma).num_controls, GateCU(theta, phi, lmbda, gamma).num_targets, GateCU(theta, phi, lmbda, gamma).num_qubits (CU(theta, phi, lambda, gamma), 1, 1, 2) >>> GateCU(theta, phi, lmbda, gamma).matrix() [1.0, 0, 0, 0] [0, 1.0, 0, 0] [0, 0, exp(I*gamma)*cos((1/2)*theta), -exp(I*(gamma + lambda))*sin((1/2)*theta)] [0, 0, exp(I*(gamma + phi))*sin((1/2)*theta), exp(I*(gamma + lambda + phi))*cos((1/2)*theta)] <BLANKLINE> >>> c = Circuit().push(GateCU(theta, phi, lmbda, gamma), 0, 1) >>> c 2-qubit circuit with 1 instructions: └── CU(theta, phi, lambda, gamma) @ q[0], q[1] <BLANKLINE> >>> GateCU(theta, phi, lmbda, gamma).power(2), GateCU(theta, phi, lmbda, gamma).inverse() (C(U(theta, phi, lambda, gamma)**2), CU(-theta, -lambda, -phi, -gamma)) >>> GateCU(theta, phi, lmbda, gamma).decompose() 2-qubit circuit with 7 instructions: ├── P(gamma) @ q[0] ├── P((1/2)*(lambda + phi)) @ q[0] ├── P((1/2)*(lambda - phi)) @ q[1] ├── CX @ q[0], q[1] ├── U((-1/2)*theta, 0, (-1/2)*(lambda + phi), 0.0) @ q[1] ├── CX @ q[0], q[1] └── U((1/2)*theta, phi, 0, 0.0) @ q[1] <BLANKLINE> """ def __init__(self, *args, **kwargs): super().__init__(1, GateU(*args, **kwargs)) self.theta = args[0] self.phi = args[1] self.lmbda = args[2] self.gamma = args[3] def _decompose(self, circ, qubits, bits): c, t = qubits theta = self.op.theta phi = self.op.phi lmbda = self.op.lmbda gamma = self.op.gamma circ.push(GateP(gamma), c) circ.push(GateP((lmbda + phi) / 2), c) circ.push(GateP((lmbda - phi) / 2), t) circ.push(GateCX(), c, t) circ.push(GateU(-theta / 2, 0, -(lmbda + phi) / 2), t) circ.push(GateCX(), c, t) circ.push(GateU(theta / 2, phi, 0), t) return circ