算子使用示例¶
本教程展示各类算子的使用方法。
[ ]:
import pysparq as ps
import numpy as np
算术算子¶
[ ]:
ps.System.clear()
ps.System.add_register("a", ps.UnsignedInteger, 4)
ps.System.add_register("b", ps.UnsignedInteger, 4)
ps.System.add_register("result", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("a", 7)(state)
ps.Init_Unsafe("b", 10)(state)
加法¶
[ ]:
# Out-of-place addition: result ^= a + b
ps.Add_UInt_UInt("a", "b", "result")(state)
print("Add_UInt_UInt:")
ps.pprint(state)
[ ]:
# In-place addition: b += a
ps.System.clear()
ps.System.add_register("a", ps.UnsignedInteger, 4)
ps.System.add_register("b", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("a", 7)(state)
ps.Init_Unsafe("b", 10)(state)
op = ps.Add_UInt_UInt_InPlace("a", "b")
op(state)
print("Add_UInt_UInt_InPlace:")
ps.pprint(state)
# b = (10 + 7) % 16 = 1
[ ]:
# Undo
op.dag(state)
print("After dagger:")
ps.pprint(state)
乘法¶
[ ]:
ps.System.clear()
ps.System.add_register("x", ps.UnsignedInteger, 4)
ps.System.add_register("triple", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("x", 5)(state)
# Multiply by an odd constant (guarantees bijectivity)
ps.Mult_UInt_ConstUInt("x", 3, "triple")(state)
print("Mult_UInt_ConstUInt(x, 3):")
ps.pprint(state)
比较与标志¶
[ ]:
ps.System.clear()
ps.System.add_register("a", ps.UnsignedInteger, 4)
ps.System.add_register("b", ps.UnsignedInteger, 4)
ps.System.add_register("less", ps.Boolean, 1)
ps.System.add_register("equal", ps.Boolean, 1)
state = ps.SparseState()
ps.Init_Unsafe("a", 3)(state)
ps.Init_Unsafe("b", 5)(state)
ps.Compare_UInt_UInt("a", "b", "less", "equal")(state)
print("Compare_UInt_UInt:")
ps.pprint(state)
量子门¶
[ ]:
ps.System.clear()
ps.System.add_register("q", ps.Boolean, 1)
state = ps.SparseState()
print("Initial:")
ps.pprint(state)
[ ]:
# X gate (NOT)
ps.X_Bool("q", 0)(state)
print("After X gate:")
ps.pprint(state)
[ ]:
# Hadamard
ps.Hadamard_Bool("q")(state)
print("After Hadamard:")
ps.pprint(state)
[ ]:
# Phase gate
ps.Phase_Bool("q", 0, np.pi/4)(state)
print("After Phase(π/4):")
ps.pprint(state)
QFT¶
[ ]:
ps.System.clear()
ps.System.add_register("q", ps.UnsignedInteger, 3)
state = ps.SparseState()
ps.Init_Unsafe("q", 1)(state)
print("Initial:")
ps.pprint(state)
[ ]:
# QFT
ps.QFT("q")(state)
print("After QFT:")
ps.pprint(state)
[ ]:
# InverseQFT
ps.InverseQFT("q")(state)
print("After InverseQFT:")
ps.pprint(state)
条件操作¶
[ ]:
ps.System.clear()
ps.System.add_register("x", ps.UnsignedInteger, 2)
ps.System.add_register("result", ps.UnsignedInteger, 2)
ps.System.add_register("ctrl", ps.Boolean, 1)
state = ps.SparseState()
ps.Init_Unsafe("x", 3)(state)
ps.Init_Unsafe("ctrl", 1)(state)
# Perform the addition when ctrl = 1
ps.Add_UInt_ConstUInt("x", 5, "result").conditioned_by_nonzeros("ctrl")(state)
print("Conditional addition (ctrl=1):")
ps.pprint(state)
[ ]:
# The condition does not trigger when ctrl = 0
ps.System.clear()
ps.System.add_register("x", ps.UnsignedInteger, 2)
ps.System.add_register("result", ps.UnsignedInteger, 2)
ps.System.add_register("ctrl", ps.Boolean, 1)
state = ps.SparseState()
ps.Init_Unsafe("x", 3)(state)
ps.Init_Unsafe("ctrl", 0)(state) # ctrl = 0
ps.Add_UInt_ConstUInt("x", 5, "result").conditioned_by_nonzeros("ctrl")(state)
print("Conditional addition (ctrl=0):")
ps.pprint(state)
# result stays 0
Block Encoding:三对角矩阵¶
Block Encoding 将经典矩阵编码为酉矩阵,是量子线性代数算法的核心。下面的例子使用 pysparq.algorithms.block_encoding 中的 BlockEncodingTridiagonal 对三对角矩阵 :math:A = \alpha I + \beta T 进行块编码。
[ ]:
from pysparq.algorithms.block_encoding import (
get_tridiagonal_matrix,
BlockEncodingTridiagonal,
)
alpha, beta, dim = 0.5, 0.3, 4
A = get_tridiagonal_matrix(alpha, beta, dim)
print(f"Tridiagonal matrix A:\n{A}")
# Build the Block Encoding circuit
ps.System.clear()
ps.System.add_register("main_reg", ps.UnsignedInteger, 2) # dim = 2^2
ps.System.add_register("anc_UA", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("main_reg", 0)(state)
ps.Init_Unsafe("anc_UA", 0)(state)
block_enc = BlockEncodingTridiagonal("main_reg", "anc_UA", alpha, beta)
block_enc(state)
print(f"Block Encoding applied successfully, number of basis states: {state.size()}")
block_enc.dag(state) # release the ancilla registers
print(f"After inverse Block Encoding, number of basis states: {state.size()}")
Python 侧自定义算子¶
当需要组合多个已有算子时,在 Python 侧直接封装:
[ ]:
class MyIncrement:
"""Add 1 to the register value (out-of-place result register)."""
def __init__(self, src: str, dst: str):
self.src = src
self.dst = dst
def __call__(self, state: ps.SparseState):
ps.Add_UInt_UInt(self.src, self.dst)(state)
def dag(self, state: ps.SparseState):
ps.Add_UInt_UInt(self.src, self.dst)(state) # XOR semantics: applying it twice restores the value
ps.System.clear()
ps.System.add_register("counter", ps.UnsignedInteger, 4)
ps.System.add_register("result", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("counter", 5)(state)
ps.Init_Unsafe("result", 0)(state)
my_inc = MyIncrement("counter", "result")
my_inc(state) # result = 0 + 5 = 5
print(f"After addition, result = {state.basis_states[0].get(ps.System.get_id('result')).value}")
my_inc.dag(state) # result = 5 + 5 = 0, restored
print(f"After dagger, result = {state.basis_states[0].get(ps.System.get_id('result')).value}")
如需新的 primitives(超出已有算子表达能力),使用 compile_operator 将 C++ 代码编译为动态链接库:
[ ]:
from pysparq.dynamic_operator import compile_operator
cpp_code = '''
class FlipOp : public SelfAdjointOperator {
size_t reg_id;
public:
FlipOp(size_t r) : reg_id(r) {}
void operator()(std::vector<System>& state) const override {
for (auto& s : state) {
s.get(reg_id).value ^= 1;
}
}
};
'''
FlipOp = compile_operator(
name="FlipOp",
cpp_code=cpp_code,
base_class="SelfAdjointOperator",
constructor_args=[("size_t", "reg_id")],
)
ps.System.clear()
ps.System.add_register("q", ps.UnsignedInteger, 4)
state = ps.SparseState()
ps.Init_Unsafe("q", 1)(state)
print("Initial:", state.basis_states[0].get(ps.System.get_id("q")).value)
flip = FlipOp(reg_id=0)
flip(state) # flip bit 0
print("After flip:", state.basis_states[0].get(ps.System.get_id("q")).value)
总结¶
本教程展示了:
算术算子:Add, Mult, Compare
量子门:X, Hadamard, Phase
QFT / InverseQFT
条件操作
Block Encoding:用
BlockEncodingTridiagonal对三对角矩阵进行块编码自定义算子:Python 侧组合已有算子,或通过
compile_operator编译 C++ 代码