90 lines
3.1 KiB
Python
90 lines
3.1 KiB
Python
from math import acos, cos, pi, sqrt
|
||
|
||
import cirq
|
||
import numpy as np
|
||
|
||
|
||
def naive_kitaev_single(phi_real: float, repetitions: int = 2000):
|
||
"""
|
||
Наивный вариант алгоритма Китаева
|
||
---------------------------------------------------
|
||
Реализует схему:
|
||
H --●-- H -- измерение
|
||
|
|
||
U
|
||
где U|1> = e^{i2πφ}|1>.
|
||
|
||
После схемы:
|
||
P(0) = cos²(πφ)
|
||
P(1) = sin²(πφ)
|
||
|
||
Измеряя P(0), можно получить множество кандидатов для φ из уравнения:
|
||
φ = (±arccos(√P(0)) + mπ) / π
|
||
где m ∈ ℤ, φ ∈ [0,1).
|
||
"""
|
||
|
||
# Симулятор и кубиты
|
||
sim = cirq.Simulator()
|
||
a, u = cirq.LineQubit.range(2) # a — фазовый кубит, u — системный
|
||
|
||
# Создаём унитар U с фазой φ
|
||
U = cirq.MatrixGate(np.diag([1.0, np.exp(1j * 2 * np.pi * phi_real)]))
|
||
|
||
# Собираем схему
|
||
circuit = cirq.Circuit(
|
||
cirq.X(u), # подготавливаем |ψ⟩ = |1⟩
|
||
cirq.H(a), # суперпозиция на фазовом кубите
|
||
cirq.ControlledGate(U).on(a, u),
|
||
cirq.H(a), # интерференция
|
||
cirq.measure(a, key="m"), # измеряем фазовый кубит
|
||
)
|
||
|
||
# Запускаем симуляцию
|
||
result = sim.run(circuit, repetitions=repetitions)
|
||
m = result.measurements["m"][:, 0]
|
||
|
||
# Эмпирическая вероятность
|
||
p0_emp = np.mean(m == 0)
|
||
p0_theory = cos(pi * phi_real) ** 2
|
||
|
||
# Решаем уравнение cos²(πφ) = p0_emp
|
||
c = sqrt(max(0.0, min(1.0, p0_emp))) # защита от ошибок округления
|
||
alpha = acos(c) # угол α ∈ [0, π/2]
|
||
|
||
# Все кандидаты φ = (±α + mπ) / π в [0,1)
|
||
candidates = []
|
||
for m in range(2): # m=0 и m=1 дают все уникальные решения в [0,1)
|
||
for sign in (+1, -1):
|
||
phi_c = (sign * alpha + m * pi) / pi
|
||
phi_c_mod = phi_c % 1.0
|
||
candidates.append((m, sign, phi_c_mod))
|
||
|
||
# Удалим дубли и отсортируем
|
||
uniq = {}
|
||
for m, sign, val in candidates:
|
||
key = round(val, 12)
|
||
if key not in uniq:
|
||
uniq[key] = (m, sign, val)
|
||
candidates_unique = sorted(uniq.values(), key=lambda t: t[2])
|
||
|
||
print(f"φ(real) = {phi_real:.6f}")
|
||
print(f"P(0)_emp = {p0_emp:.6f}")
|
||
print(f"P(0)_theory = {p0_theory:.6f}")
|
||
print(f"c = sqrt(P0) = {c:.6f}, α = arccos(c) = {alpha:.6f} рад")
|
||
print()
|
||
print("Все кандидаты φ (m, sign, φ ∈ [0,1)):")
|
||
for m, sign, val in candidates_unique:
|
||
s = "+" if sign > 0 else "-"
|
||
print(f" m={m:1d}, sign={s} → φ = {val:.12f}")
|
||
print()
|
||
print(f"repetitions = {repetitions}")
|
||
|
||
return candidates_unique
|
||
|
||
|
||
# === Пример запуска ===
|
||
if __name__ == "__main__":
|
||
phi_real = 0.228 # истинная фаза
|
||
repetitions = 2000
|
||
naive_kitaev_single(phi_real, repetitions)
|