mindquantum.algorithm.compiler.decompose.universal_decompose.one_qubit_decompose 源代码

# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
"""One-qubit gate decomposition."""

import numpy as np
from mindquantum.core import gates
from mindquantum.core.circuit import Circuit
from mindquantum.core.gates import QuantumGate, U3, RX, RZ
from mindquantum.utils.type_value_check import _check_input_type

from ..utils import params_u3, params_zyz

optional_basis = ['zyz', 'u3']


[文档]def euler_decompose(gate: QuantumGate, basis: str = 'zyz', with_phase: bool = True) -> Circuit: """ One-qubit Euler decomposition. Currently only support 'zyz' and 'u3' decomposition. Args: gate (QuantumGate): single-qubit quantum gate. basis (str): decomposition basis, can be one of ``'zyz'`` or ``'u3'``. Default: ``'zyz'``. with_phase (bool): whether return global phase in form of a :class:`~.core.gates.GlobalPhase` gate. Returns: :class:`~.core.circuit.Circuit`, quantum circuit after Euler decomposition. """ if len(gate.obj_qubits) != 1 or gate.ctrl_qubits: raise ValueError(f'{gate} is not a single-qubit gate with designated qubit for Euler decomposition') basis = basis.lower() tq = gate.obj_qubits[0] circ = Circuit() if basis == 'zyz': alpha, (theta, phi, lamda) = params_zyz(gate.matrix()) circ += gates.RZ(lamda).on(tq) circ += gates.RY(theta).on(tq) circ += gates.RZ(phi).on(tq) if with_phase: circ += gates.GlobalPhase(-alpha).on(tq) elif basis == 'u3': phase, (theta, phi, lamda) = params_u3(gate.matrix(), return_phase=True) circ += gates.U3(theta, phi, lamda).on(tq) if with_phase: circ += gates.GlobalPhase(-phase).on(tq) else: raise ValueError(f'{basis} is not a supported decomposition method of {optional_basis}') return circ
[文档]def u3_decompose(gate: U3, method: str = 'standard'): """ Decompose a U3 gate into a sequence of Z-X-Z-X-Z rotations. The decomposition follows one of two methods: 1. standard: U3(θ,φ,λ) = Rz(φ)Rx(-π/2)Rz(θ)Rx(π/2)Rz(λ) 2. alternative: U3(θ,φ,λ) = Rz(φ)Rx(π/2)Rz(π-θ)Rx(π/2)Rz(λ-π) When any rotation angle is a constant value and equals to 0, the corresponding RZ gate will be omitted. Args: gate (U3): The U3 gate to be decomposed. method (str): The decomposition method to use, either 'standard' or 'alternative'. Default: 'standard' Returns: Circuit, A quantum circuit implementing the U3 gate using ZXZXZ sequence. Raises: ValueError: If the method is not 'standard' or 'alternative'. """ _check_input_type('gate', U3, gate) if method not in ['standard', 'alternative']: raise ValueError("method must be either 'standard' or 'alternative'") theta, phi, lamda = gate.theta, gate.phi, gate.lamda qubits = gate.obj_qubits circ = Circuit() if method == 'standard': if not (lamda.is_const() and np.isclose(lamda.const, 0.0, atol=1e-8)): circ += RZ(lamda).on(qubits[0]) circ += RX(np.pi / 2).on(qubits[0]) if not (theta.is_const() and np.isclose(theta.const, 0.0, atol=1e-8)): circ += RZ(theta).on(qubits[0]) circ += RX(-np.pi / 2).on(qubits[0]) if not (phi.is_const() and np.isclose(phi.const, 0.0, atol=1e-8)): circ += RZ(phi).on(qubits[0]) else: # alternative method if not (lamda.is_const() and np.isclose(lamda.const - np.pi, 0.0, atol=1e-8)): circ += RZ(lamda - np.pi).on(qubits[0]) circ += RX(np.pi / 2).on(qubits[0]) if not (theta.is_const() and np.isclose(np.pi - theta.const, 0.0, atol=1e-8)): circ += RZ(np.pi - theta).on(qubits[0]) circ += RX(np.pi / 2).on(qubits[0]) if not (phi.is_const() and np.isclose(phi.const, 0.0, atol=1e-8)): circ += RZ(phi).on(qubits[0]) return circ