pyqres.primitives.arithmetic 源代码

import pysparq

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


[文档] class Add_UInt_UInt(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.input_reg1 = reg_list[0] self.input_reg2 = reg_list[1] self.output_reg = reg_list[2]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Add_UInt_UInt(self.input_reg1, self.input_reg2, self.output_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 {})) n = reg_sz(self.input_reg1) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Add_UInt_UInt_InPlace(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.input_reg = reg_list[0] self.output_reg = 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.Add_UInt_UInt_InPlace(self.input_reg, self.output_reg)) 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 {})) n = reg_sz(self.input_reg) return 2 * (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Add_UInt_ConstUInt(Primitive):
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.input_reg = reg_list[0] self.output_reg = reg_list[1] self.add = 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.Add_UInt_ConstUInt(self.input_reg, self.add, self.output_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 {})) n = reg_sz(self.input_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Add_ConstUInt(Primitive):
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.input_reg = reg_list[0] self.output_reg = reg_list[1] if len(reg_list) > 1 else reg_list[0] self.add = 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.Add_UInt_ConstUInt(self.input_reg, self.add, self.output_reg)) 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 {})) n = reg_sz(self.input_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Mult_UInt_ConstUInt(Primitive):
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.input_reg = reg_list[0] self.output_reg = reg_list[1] self.multiplier = 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.Mult_UInt_ConstUInt(self.input_reg, self.multiplier, self.output_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 {})) n = reg_sz(self.input_reg) return (n - 1) ** 2 * mcx_t_count(ncontrols + 2)
[文档] class ShiftLeft(Primitive):
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg = reg_list[0] self.shift_bits = 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.ShiftLeft_InPlace(self.reg, self.shift_bits)) 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): return 0
[文档] class ShiftRight(Primitive):
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg = reg_list[0] self.shift_bits = 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.ShiftRight_InPlace(self.reg, self.shift_bits)) 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): return 0
[文档] class Compare_UInt_UInt(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.less_flag_reg = reg_list[2] self.equal_flag_reg = reg_list[3]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Compare_UInt_UInt( self.left_reg, self.right_reg, self.less_flag_reg, self.equal_flag_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 {})) n = reg_sz(self.left_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Less_UInt_UInt(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.less_flag_reg = reg_list[2]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Less_UInt_UInt(self.left_reg, self.right_reg, self.less_flag_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 {})) n = reg_sz(self.left_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class GetMid_UInt_UInt(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.mid_reg = reg_list[2]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.GetMid_UInt_UInt(self.left_reg, self.right_reg, self.mid_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 {})) n = reg_sz(self.left_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class Assign(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.src = reg_list[0] self.dst = 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.Assign(self.src, self.dst)) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): return 0
[文档] class Swap_General_General(Primitive):
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.reg1 = reg_list[0] self.reg2 = 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.Swap_General_General(self.reg1, self.reg2)) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): return 0
class Div_Sqrt_Arccos_Int_Int(Primitive): def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.output_reg = reg_list[2] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Div_Sqrt_Arccos_Int_Int(self.left_reg, self.right_reg, self.output_reg)) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError("Div_Sqrt_Arccos_Int_Int t_count not yet parameterized") class Sqrt_Div_Arccos_Int_Int(Primitive): def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.output_reg = reg_list[2] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Sqrt_Div_Arccos_Int_Int(self.left_reg, self.right_reg, self.output_reg)) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError("Sqrt_Div_Arccos_Int_Int t_count not yet parameterized") class GetRotateAngle_Int_Int(Primitive): def __init__(self, reg_list, param_list=None): super().__init__(reg_list=reg_list, param_list=param_list) self.left_reg = reg_list[0] self.right_reg = reg_list[1] self.output_reg = reg_list[2] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.GetRotateAngle_Int_Int(self.left_reg, self.right_reg, self.output_reg)) obj.set_controller(controllers_ctx) return obj def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError("GetRotateAngle_Int_Int t_count not yet parameterized") # ============================================================================== # New arithmetic primitives (Phase 2) # ==============================================================================
[文档] class Add_Mult_UInt_ConstUInt(Primitive): """Multiply-add: output = input * multiplier + add_const. Computes output = input * multiplier + add_const in a single fused operation. Used in block encoding and Shor's algorithm. """ __self_conjugate__ = True # Self-adjoint (XOR-based)
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.input_reg = reg_list[0] self.output_reg = reg_list[1] self.multiplier = param_list[0] self.add_constant = param_list[1] if len(param_list) > 1 else 0
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Add_Mult_UInt_ConstUInt(self.input_reg, self.multiplier, self.output_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 {})) n = reg_sz(self.input_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
class Mod_Mult_UInt_ConstUInt(Primitive): """Modular multiplication: |y⟩ → |y * a^(2^x) mod N⟩. Computes y * a^(2^x) mod N and stores the result back in the register (in-place). Core primitive for Shor's algorithm. Args: reg_list: [reg] — single UnsignedInteger register param_list: [a, x, N] a: base for exponentiation x: exponent bit position (computes a^(2^x) mod N) N: modulus Note: This is the C++ primitive (pysparq.Mod_Mult_UInt_ConstUInt). Compare: pysparq.ModMul which is a Python composite using this primitive. """ __self_conjugate__ = False # dagger requires modular inverse def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg = reg_list[0] self.a = param_list[0] self.x = param_list[1] self.N = param_list[2] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.Mod_Mult_UInt_ConstUInt(self.reg, self.a, self.x, self.N)) 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): n = reg_sz(self.reg) ncontrols = get_control_qubit_count( merge_controllers(self.controllers, controllers_ctx or {})) # Ripple-carry approach: 4n multi-controlled additions return 4 * n * mcx_t_count(ncontrols + 2)
[文档] class AddAssign_AnyInt_AnyInt(Primitive): """In-place addition: dst += src on arbitrary integer types. Type-flexible in-place addition across Integer register types. Used in CKS TOperator for column position finding. """ __self_conjugate__ = True # Self-adjoint (inverse = subtraction)
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.input_reg = reg_list[0] self.output_reg = 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.AddAssign_AnyInt_AnyInt(self.input_reg, self.output_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 {})) n = reg_sz(self.input_reg) return (n - 1) * mcx_t_count(ncontrols + 2)
[文档] class CustomArithmetic(Primitive): """Custom classical arithmetic function applied as a quantum operation. Args: reg_list: [reg1, reg2, ...] - input and output registers param_list: [func, in_sz, out_sz] func: callable f(input_values) -> output_values in_sz: total input bit size out_sz: total output bit size Used in Shor's modular exponentiation. """ __self_conjugate__ = True # Self-adjoint when func is its own inverse
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.regs = reg_list self.func = param_list[0] self.in_sz = param_list[1] self.out_sz = param_list[2]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.CustomArithmetic(self.regs, self.in_sz, self.out_sz, self.func)) obj.set_controller(controllers_ctx) return obj
[文档] def t_count(self, dagger_ctx=False, controllers_ctx=None): raise NotImplementedError("CustomArithmetic t_count depends on the function")
[文档] class PlusOneAndOverflow(Primitive): """Increment a register by 1, with separate overflow flag qubit. Used in block encoding for carry/borrow logic. Inverse = MinusOneAndOverflow (different op, use dagger). """ __self_conjugate__ = False # Inverse is MinusOneAndOverflow
[文档] def __init__(self, reg_list, param_list=None): super().__init__(reg_list, param_list) self.main_reg = reg_list[0] self.overflow_reg = reg_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 obj = PyQSparseOperationWrapper( pysparq.PlusOneAndOverflow(self.main_reg, self.overflow_reg)) 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 {})) return mcx_t_count(ncontrols + 1) # ripple-carry addition
[文档] class GetDataAddr(Primitive): """Compute XOR-based data address for QRAM access. data_addr ^= data_offset + row * row_size + col Self-adjoint: applying twice cancels (XOR property). Used in CKS TOperator for matrix element loading. """ __self_conjugate__ = True
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg_offset = reg_list[0] self.reg_row = reg_list[1] self.reg_col = reg_list[2] self.row_size = param_list[0] self.reg_data_offset = reg_list[3]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.GetDataAddr( self.reg_offset, self.reg_row, self.reg_col, self.row_size, self.reg_data_offset)) 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 {})) n = reg_sz(self.reg_offset) return n * mcx_t_count(ncontrols + 1)
[文档] class GetRowAddr(Primitive): """Compute XOR-based row address for sparse QRAM access. row_addr ^= sparse_offset + row * row_size Self-adjoint: applying twice cancels (XOR property). Used in CKS TOperator for column position finding. """ __self_conjugate__ = True
[文档] def __init__(self, reg_list, param_list): super().__init__(reg_list=reg_list, param_list=param_list) self.reg_offset = reg_list[0] self.reg_row = reg_list[1] self.row_size = param_list[0] self.reg_row_offset = reg_list[2]
[文档] def pyqsparse_object(self, dagger_ctx=False, controllers_ctx=None): controllers_ctx = merge_controllers(self.controllers, controllers_ctx or {}) obj = PyQSparseOperationWrapper( pysparq.GetRowAddr( self.reg_offset, self.reg_row, self.row_size, self.reg_row_offset)) 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 {})) n = reg_sz(self.reg_offset) return n * mcx_t_count(ncontrols + 1)