import sympy as sp
import pysparq
from ..core.operation import Primitive
from ..core.utils import reg_sz, get_control_qubit_count, merge_controllers, mcx_t_count
from ..core.simulator import PyQSparseOperationWrapper
from ..core.metadata import RegisterMetadata
[文档]
class Hadamard(Primitive):
__self_conjugate__ = True # H† = H
[文档]
def __init__(self, reg_list, param_list=None):
super().__init__(reg_list, param_list)
self.reg = reg_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(pysparq.Hadamard_Int_Full(self.reg))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 0
raise NotImplementedError("Controlled Hadamard not implemented.")
[文档]
class Hadamard_NDigits(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.n_digits = param_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(pysparq.Hadamard_Int(self.reg, self.n_digits))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 0
raise NotImplementedError("Controlled Hadamard_NDigits not implemented.")
[文档]
class X(Primitive):
__self_conjugate__ = True # X† = X
[文档]
def __init__(self, reg_list, param_list=None):
if param_list is None:
super().__init__(reg_list)
self.qubit_index = None
else:
super().__init__(reg_list=reg_list, param_list=param_list)
self.qubit_index = param_list[0]
self.reg = reg_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
if self.qubit_index is None:
obj = PyQSparseOperationWrapper(pysparq.FlipBools(self.reg))
else:
obj = PyQSparseOperationWrapper(pysparq.Xgate_Bool(self.reg, self.qubit_index))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
sz = reg_sz(self.reg) if self.qubit_index is None else 1
return mcx_t_count(ncontrols) * sz
[文档]
class Y(Primitive):
__self_conjugate__ = True # Y† = Y (Hermitian)
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.qubit_index = param_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(pysparq.Ygate_Bool(self.reg, self.qubit_index))
obj.set_dagger(dagger_ctx ^ self.dagger_flag)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
return mcx_t_count(ncontrols)
[文档]
class CNOT(Primitive):
__self_conjugate__ = True # CNOT† = CNOT
[文档]
def __init__(self, reg_list, param_list=None):
if param_list is None:
super().__init__(reg_list)
self.control_qubit_index = None
self.target_qubit_index = None
else:
super().__init__(reg_list=reg_list, param_list=param_list)
self.control_qubit_index = param_list[0]
self.target_qubit_index = param_list[1]
self.control_reg = reg_list[0]
self.target_reg = reg_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
if self.control_qubit_index is None:
obj = PyQSparseOperationWrapper(pysparq.FlipBools(self.target_reg))
additional_controller = {'conditioned_by_all_ones': [self.control_reg]}
controllers_ctx = merge_controllers(controllers_ctx, additional_controller)
obj.set_controller(controllers_ctx)
else:
obj = PyQSparseOperationWrapper(
pysparq.Xgate_Bool(self.target_reg, self.target_qubit_index))
additional_controller = {
'conditioned_by_bit': [(self.control_reg, self.control_qubit_index)]}
controllers_ctx = merge_controllers(controllers_ctx, additional_controller)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
sz = reg_sz(self.control_reg) if self.control_qubit_index is None else 1
return mcx_t_count(ncontrols + 1) * sz
[文档]
class Toffoli(Primitive):
__self_conjugate__ = True # Toffoli† = Toffoli
[文档]
def __init__(self, reg_list, param_list=None):
if param_list is None:
super().__init__(reg_list)
self.control_qubit_index1 = None
self.control_qubit_index2 = None
self.target_qubit_index = None
else:
super().__init__(reg_list=reg_list, param_list=param_list)
self.control_qubit_index1 = param_list[0]
self.control_qubit_index2 = param_list[1]
self.target_qubit_index = param_list[2]
self.control_reg1 = reg_list[0]
self.control_reg2 = reg_list[1]
self.target_reg = reg_list[2]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
if self.control_qubit_index1 is None:
obj = PyQSparseOperationWrapper(pysparq.FlipBools(self.target_reg))
additional_controller = {
'conditioned_by_all_ones': [self.control_reg1, self.control_reg2]}
controllers_ctx = merge_controllers(controllers_ctx, additional_controller)
obj.set_controller(controllers_ctx)
else:
obj = PyQSparseOperationWrapper(
pysparq.Xgate_Bool(self.target_reg, self.target_qubit_index))
additional_controller = {
'conditioned_by_bit': [
(self.control_reg1, self.control_qubit_index1),
(self.control_reg2, self.control_qubit_index2)]}
controllers_ctx = merge_controllers(controllers_ctx, additional_controller)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
sz = reg_sz(self.control_reg1) if self.control_qubit_index1 is None else 1
return mcx_t_count(ncontrols + 2) * sz
[文档]
class Rx(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.angle = param_list[0]
self.eps = param_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
angle = -self.angle if dagger else self.angle
obj = PyQSparseOperationWrapper(pysparq.RXgate_Bool(self.reg, angle))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 3 * sp.ceiling(sp.log(1 / self.eps))
return 6 * sp.ceiling(sp.log(1 / self.eps)) + mcx_t_count(ncontrols)
[文档]
class Ry(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.angle = param_list[0]
self.eps = param_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
angle = -self.angle if dagger else self.angle
obj = PyQSparseOperationWrapper(pysparq.RYgate_Bool(self.reg, angle))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 3 * sp.ceiling(sp.log(1 / self.eps))
return 6 * sp.ceiling(sp.log(1 / self.eps)) + mcx_t_count(ncontrols)
[文档]
class PhaseGate(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.angle = param_list[0]
self.eps = param_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
angle = -self.angle if dagger else self.angle
obj = PyQSparseOperationWrapper(pysparq.Phase_Bool(self.reg, angle))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 3 * sp.ceiling(sp.log(1 / self.eps))
return 6 * sp.ceiling(sp.log(1 / self.eps)) + mcx_t_count(ncontrols)
[文档]
class Rz(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.angle = param_list[0]
self.eps = param_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
angle = -self.angle if dagger else self.angle
obj = PyQSparseOperationWrapper(pysparq.RZgate_Bool(self.reg, angle))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 3 * sp.ceiling(sp.log(1 / self.eps))
return 6 * sp.ceiling(sp.log(1 / self.eps)) + mcx_t_count(ncontrols)
[文档]
class U3(Primitive):
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.theta = param_list[0]
self.phi = param_list[1]
self.lambda_ = param_list[2]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
obj = PyQSparseOperationWrapper(
pysparq.U3gate_Bool(self.reg, self.theta, self.phi, self.lambda_))
obj.set_dagger(dagger)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 3 * sp.ceiling(sp.log(1 / self.eps))
return 6 * sp.ceiling(sp.log(1 / self.eps)) + mcx_t_count(ncontrols)
# ==============================================================================
# New gate primitives (Phase 2)
# ==============================================================================
[文档]
class Hadamard_Bool(Primitive):
"""Hadamard gate on a single boolean qubit.
Maps |0⟩ → (|0⟩+|1⟩)/√2, |1⟩ → (|0⟩−|1⟩)/√2.
Self-conjugate: H† = H.
"""
__self_conjugate__ = True
[文档]
def __init__(self, reg_list, param_list=None):
super().__init__(reg_list, param_list)
self.reg = reg_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(pysparq.Hadamard_Bool(self.reg))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 0 # Clifford gate
[文档]
class Hadamard_PartialQubit(Primitive):
"""Hadamard on a subset of qubits within a register.
Args:
reg_list: [register_name]
param_list: [set of qubit positions (int)] e.g. {0, 2}
"""
__self_conjugate__ = True
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.qubit_positions = set(param_list[0])
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(
pysparq.Hadamard_PartialQubit(self.reg, self.qubit_positions))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 0 # Clifford gate
[文档]
class Sgate(Primitive):
"""Phase gate S = diag(1, i) on a boolean qubit.
Also known as P-gate or Phase gate. Clifford: T-count = 0.
"""
__self_conjugate__ = False # S† = S^3, not self-adjoint
[文档]
def __init__(self, reg_list, param_list=None):
super().__init__(reg_list, param_list)
self.reg = reg_list[0]
self.digit = param_list[0] if param_list else 0
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
obj = PyQSparseOperationWrapper(pysparq.Sgate_Bool(self.reg, self.digit))
obj.set_dagger(dagger)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 0 # Clifford gate
[文档]
class Tgate(Primitive):
"""T gate = diag(1, e^{iπ/4}) on a boolean qubit.
Non-Clifford. T-count = 4 (fourth root of Z).
"""
__self_conjugate__ = False # T† = T^7
[文档]
def __init__(self, reg_list, param_list=None):
super().__init__(reg_list, param_list)
self.reg = reg_list[0]
self.digit = param_list[0] if param_list else 0
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
obj = PyQSparseOperationWrapper(pysparq.Tgate_Bool(self.reg, self.digit))
obj.set_dagger(dagger)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 4 # Standard T-gate decomposition
[文档]
class SXgate(Primitive):
"""Square-root of X gate: SX = √X = [[1+i, 1-i], [1-i, 1+i]]/2.
Non-Clifford (depth-2 from T/T†).
"""
__self_conjugate__ = False # SX† = SX^3
[文档]
def __init__(self, reg_list, param_list=None):
super().__init__(reg_list, param_list)
self.reg = reg_list[0]
self.digit = param_list[0] if param_list else 0
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
obj = PyQSparseOperationWrapper(pysparq.SXgate_Bool(self.reg, self.digit))
obj.set_dagger(dagger)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 2 # ~2 T-gates per SX via Clifford+T decomposition
[文档]
class U2gate(Primitive):
"""Two-parameter unitary gate U2(φ, λ) = [[1, e^{iλ}], [e^{iφ}, -e^{i(φ+λ)]]]/√2.
Args:
reg_list: [register_name]
param_list: [digit_position, phi, lambda_]
"""
__self_conjugate__ = False
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg = reg_list[0]
self.digit = param_list[0]
self.phi = param_list[1]
self.lambda_ = param_list[2]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
obj = PyQSparseOperationWrapper(
pysparq.U2gate_Bool(self.reg, self.digit, self.phi, self.lambda_))
obj.set_dagger(dagger)
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
# U2(φ,λ) = e^{i(φ+λ)/2} RZ(φ) RY(π/2) RZ(λ)
# Approx: RZ gates need ~1 T + RY(π/2) needs ~2 T
base = 6
if ncontrols == 0:
return base
return base + mcx_t_count(ncontrols)
[文档]
class Swap_Bool_Bool(Primitive):
"""Swap two individual boolean qubits in different registers.
Args:
reg_list: [register1, register2]
param_list: [digit1, digit2]
"""
__self_conjugate__ = True # Swap† = Swap
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.reg1 = reg_list[0]
self.reg2 = reg_list[1]
self.digit1 = param_list[0]
self.digit2 = param_list[1]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
obj = PyQSparseOperationWrapper(
pysparq.Swap_Bool_Bool(self.reg1, self.digit1, self.reg2, self.digit2))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
ncontrols = get_control_qubit_count(
merge_controllers(self.controllers, controllers_ctx or {}))
if ncontrols == 0:
return 0 # No T-gates for SWAP (CNOT-based)
return mcx_t_count(ncontrols + 1)
[文档]
class GlobalPhase(Primitive):
"""Global phase gate: multiplies state by e^{iφ}.
Physically unobservable but affects interference. Not a physical resource.
T-count = 0 by convention.
"""
__self_conjugate__ = False # GlobalPhase(φ)† = GlobalPhase(-φ)
[文档]
def __init__(self, reg_list, param_list):
super().__init__(reg_list=reg_list, param_list=param_list)
self.phase = param_list[0]
[文档]
def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None):
controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {})
dagger = dagger_ctx ^ self.dagger_flag
phase = complex(-self.phase.imag, self.phase.real) if dagger else self.phase
obj = PyQSparseOperationWrapper(pysparq.GlobalPhase_Int(phase))
obj.set_controller(controllers_ctx)
return obj
[文档]
def t_count(self, dagger_ctx=False, controllers_ctx=None):
return 0 # Global phase is not a physical resource