pyqres.primitives.cond_rot 源代码

import pysparq

from ..core.operation import Primitive
from ..core.utils import merge_controllers, get_control_qubit_count, mcx_t_count, reg_sz
from ..core.simulator import PyQSparseOperationWrapper


[文档] class CondRot_General_Bool(Primitive): """Conditional rotation based on rational value register. Supports two forms: - 2-arg (resource estimation only): reg_list=[cond_reg, target_reg] - 3-arg (simulation): reg_list=[cond_reg, target_reg], param_list=[angle_function] where angle_function is a Callable[[int], list[complex]]. pysparq requires the 3-arg form: CondRot_General_Bool(reg_in, reg_out, angle_function). angle_function receives the register value and returns a 2x2 unitary matrix. """
[文档] def __init__(self, reg_list, param_list=None, angle_function=None): super().__init__(reg_list, param_list) self.cond_reg = reg_list[0] self.target_reg = reg_list[1] # Prefer keyword arg; fall back to param_list[0] self.angle_function = angle_function if angle_function is not None else ( param_list[0] if param_list else None)
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) if self.angle_function is not None: obj = PyQSparseOperationWrapper( pysparq.CondRot_General_Bool( self.cond_reg, self.target_reg, self.angle_function)) else: # Fallback for resource estimation without angle_function: # use identity rotation (theta=0) n = reg_sz(self.cond_reg) default_func = lambda value, _n=n: [complex(1, 0), 0j, 0j, complex(1, 0)] obj = PyQSparseOperationWrapper( pysparq.CondRot_General_Bool( self.cond_reg, self.target_reg, default_func)) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): if self.angle_function is not None: raise NotImplementedError( "CondRot_General_Bool (3-arg) t_count depends on angle_function") ncontrols = get_control_qubit_count( merge_controllers(self.controllers, controllers_ctx or {})) if ncontrols == 0: return 0 return 4 * ncontrols + 3
[文档] class CondRot_General_Bool_QW(Primitive): """Conditional rotation for quantum walk operations. Similar to CondRot_General_Bool but optimized for quantum walk style amplitude loading with 2x2 rotation matrices. Uses CondRot_Rational_Bool internally with a matrix-structured angle function. """
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.j_reg = reg_list[0] self.k_reg = reg_list[1] self.reg_in = reg_list[2] self.reg_out = reg_list[3]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError( "CondRot_General_Bool_QW: use CondRot_Rational_Bool or " "CondRot_General_Bool with angle_function instead")
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError( "CondRot_General_Bool_QW t_count depends on matrix structure")
[文档] class ZeroConditionalPhaseFlip(Primitive): """Apply phase flip to states where all specified qubits are zero."""
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.qubit_regs = reg_list
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) # Multi-controlled Z gate obj = PyQSparseOperationWrapper( pysparq.ZeroConditionalPhaseFlip([r for r in self.qubit_regs])) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): ncontrols = len(self.qubit_regs) if ncontrols == 0: return 0 return 4 * ncontrols + 1
[文档] class RangeConditionalPhaseFlip(Primitive): """Apply phase flip to states in a specified range."""
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg = reg_list[0] self.low = param_list[0] self.high = 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.RangeConditionalPhaseFlip(self.reg, self.low, self.high)) 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 {})) size = self.high - self.low + 1 return size * (mcx_t_count(ncontrols + 1) + 3)
# ============================================================================== # New conditional rotation primitives (Phase 2) # ==============================================================================
[文档] class CondRot_Rational_Bool(Primitive): """Conditional rotation using rational (fractional) angle encoding. Applies a rotation to the target qubit based on the rational value in the input register. Used in CKS quantum walk and block encoding. Note: pysparq marks this as self-adjoint (CondRot_Rational_Bool† = CondRot_Rational_Bool). """ __self_conjugate__ = True
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.reg_in = reg_list[0] self.reg_out = reg_list[1]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.CondRot_Rational_Bool(self.reg_in, self.reg_out)) 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 return 4 * ncontrols + 3
[文档] class Rot_GeneralUnitary(Primitive): """General unitary rotation specified by an arbitrary 2x2 complex matrix. Args: reg_list: [register_name] param_list: [unitary_matrix] where unitary_matrix is a 4-element list [a, b, c, d] representing [[a, b], [c, d]]. Used in block encoding for arbitrary rotation angles. """ __self_conjugate__ = False # Inverse = conjugate transpose
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg = reg_list[0] self.unitary_matrix = param_list[0] # list of 4 complex numbers
[文档] 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 unitary = pysparq.stateprep_unitary_build_schmidt(self.unitary_matrix) obj = PyQSparseOperationWrapper( pysparq.Rot_GeneralUnitary(self.reg, unitary)) obj.set_dagger(dagger) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError( "Rot_GeneralUnitary t_count depends on the matrix decomposition")
class Rot_Bool(Primitive): """Single-qubit rotation via general 2x2 unitary using pysparq Rot_Bool. Args: reg_list: [register_name] param_list: [unitary_matrix] where unitary_matrix is a 4-element list [a, b, c, d] representing [[a, b], [c, d]] (row-major). Uses pysparq.Rot_Bool which accepts u22_t directly as a Python sequence, avoiding the DenseMatrix_complex API limitation. """ __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.unitary_matrix = 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 obj = PyQSparseOperationWrapper( pysparq.Rot_Bool(self.reg, self.unitary_matrix)) obj.set_dagger(dagger) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError( "Rot_Bool t_count depends on the matrix decomposition") class CondRot_Fixed_Bool(Primitive): """Conditional rotation using a pre-computed rational angle. Uses a rotation angle that has already been computed and stored in the input register (e.g. by GetQWRotateAngle_Int_Int_Int). Inherits the rotation logic from CondRot_Rational_Bool. Args: reg_list: [reg_in, reg_out] reg_in: register holding the pre-computed rational angle reg_out: boolean output register for the rotation Note: self-adjoint in C++ (CondRot_Rational_Bool::dag calls operator()). """ __self_conjugate__ = True def __init__(self, reg_list, param_list=None): super().__init__(reg_list=reg_list, param_list=param_list) self.reg_in = reg_list[0] self.reg_out = reg_list[1] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.CondRot_Fixed_Bool(self.reg_in, self.reg_out)) 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 return 4 * ncontrols + 3 class CondRot_General_Bool_QW_fast(Primitive): """Fast quantum-walk conditional rotation using a SparseMatrix. Combines SortExceptKey + rotation angle computation + conditional rotation into a single optimized operation using the SparseMatrix directly. Forward: SortExceptKey → compute rotation from mat → apply rotation per group The rotation angle is derived from mat[row, col] at runtime. Args: reg_list: [j, k, reg_in, reg_out] j: row index register k: column/index register reg_in: input register (e.g. data from QRAM) reg_out: boolean output register for rotation param_list: [mat] where mat is a pysparq.SparseMatrix object Reference: CKS quantum walk (hamiltonian_simulation.h T::impl) """ __self_conjugate__ = False # Has explicit dag() method def __init__(self, reg_list, param_list=None): super().__init__(reg_list=reg_list, param_list=param_list) self.j_reg = reg_list[0] self.k_reg = reg_list[1] self.reg_in = reg_list[2] self.reg_out = reg_list[3] self.mat = param_list[0] if param_list else None 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.CondRot_General_Bool_QW_fast( self.j_reg, self.k_reg, self.reg_in, self.reg_out, self.mat)) obj.set_dagger(dagger) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError( "CondRot_General_Bool_QW_fast t_count depends on matrix sparsity") class GetQWRotateAngle_Int_Int_Int(Primitive): """Compute quantum-walk rotation angle from a SparseMatrix element. Reads the value at mat[row, col], computes the rotation angle (arcsin(sqrt(|value|/Amax))) and stores it as a rational number in the output register. Used together with CondRot_Fixed_Bool. Self-adjoint: dag() calls the same operation (no uncomputation needed since the result register is consumed by CondRot_Fixed_Bool). Args: reg_list: [data, row, col, out] data: register holding the matrix value (from QRAM) row: row index register col: column index register out: output register for the rational angle param_list: [mat] where mat is a pysparq.SparseMatrix object Reference: GetQWRotateAngle_Int_Int_Int in hamiltonian_simulation.h """ __self_conjugate__ = True def __init__(self, reg_list, param_list=None): super().__init__(reg_list=reg_list, param_list=param_list) self.data_reg = reg_list[0] self.row_reg = reg_list[1] self.col_reg = reg_list[2] self.out_reg = reg_list[3] self.mat = param_list[0] if param_list else None def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.GetQWRotateAngle_Int_Int_Int( self.data_reg, self.row_reg, self.col_reg, self.out_reg, self.mat)) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): # Angle computation is classical arithmetic on register values ncontrols = get_control_qubit_count( merge_controllers(self.controllers, controllers_ctx or {})) if ncontrols == 0: return 0 return 4 * ncontrols + 3