больше кодовввв
This commit is contained in:
89
task8/naive.py
Normal file
89
task8/naive.py
Normal file
@@ -0,0 +1,89 @@
|
||||
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)
|
||||
69
task8/qft.py
Normal file
69
task8/qft.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
Реализация Квантового Преобразования Фурье (QFT) для произвольного числа кубитов n.
|
||||
"""
|
||||
|
||||
import cirq
|
||||
import numpy as np
|
||||
|
||||
|
||||
# === Функция построения схемы QFT ===
|
||||
def qft_circuit(n: int) -> cirq.Circuit:
|
||||
"""Создаёт схему квантового преобразования Фурье (QFT) для n кубитов."""
|
||||
qubits = [cirq.LineQubit(i) for i in range(n)]
|
||||
circuit = cirq.Circuit()
|
||||
|
||||
# Для каждого кубита применяем Hadamard и контролируемые фазовые повороты
|
||||
for i in range(n):
|
||||
circuit.append(cirq.H(qubits[i]))
|
||||
for j in range(i + 1, n):
|
||||
angle = 1 / (2 ** (j - i))
|
||||
circuit.append(cirq.CZ(qubits[j], qubits[i]) ** angle)
|
||||
|
||||
# После всех поворотов меняем порядок кубитов на обратный
|
||||
for i in range(n // 2):
|
||||
circuit.append(cirq.SWAP(qubits[i], qubits[n - i - 1]))
|
||||
|
||||
return circuit
|
||||
|
||||
|
||||
# === Главная функция ===
|
||||
def main():
|
||||
n = 4 # число кубитов
|
||||
input_state_str = "0111"
|
||||
|
||||
print(f"=== Квантовое преобразование Фурье (QFT) для {n} кубитов ===")
|
||||
print(f"Исходное состояние: |{input_state_str}>")
|
||||
|
||||
# --- Создаём кубиты ---
|
||||
qubits = [cirq.LineQubit(i) for i in range(n)]
|
||||
circuit = cirq.Circuit()
|
||||
|
||||
# Переводим строку в установку нужных кубитов в |1>
|
||||
for i, bit in enumerate(
|
||||
reversed(input_state_str)
|
||||
): # reversed, чтобы младший бит был справа
|
||||
if bit == "1":
|
||||
circuit.append(cirq.X(qubits[i])) # применяем оператор X (NOT)
|
||||
|
||||
# --- Добавляем саму QFT ---
|
||||
circuit += qft_circuit(n)
|
||||
|
||||
print("\nСхема:")
|
||||
print(circuit)
|
||||
|
||||
# --- Симуляция ---
|
||||
simulator = cirq.Simulator()
|
||||
result = simulator.simulate(circuit)
|
||||
state = result.final_state_vector
|
||||
|
||||
# --- Вычисляем фазы ---
|
||||
phases = np.angle(state)
|
||||
|
||||
print("\n=== Результирующее состояние (амплитуды и фазы) ===")
|
||||
for i, (amp, phi) in enumerate(zip(state, phases)):
|
||||
if abs(amp) > 1e-9: # пропускаем элементы с амплитудой близкой к 0
|
||||
print(f"|{i:0{n}b}>: amp={abs(amp):.3f}, phase={phi:.3f} rad")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
106
task8/qpe.py
Normal file
106
task8/qpe.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
Адаптированный пример алгоритма квантовой оценки фазы (QPE)
|
||||
|
||||
Для каждого значения целевой фазы φ (от 0.0 до 0.9) проверяется,
|
||||
насколько точно QPE оценивает её с использованием заданного числа кубитов.
|
||||
|
||||
Схема QPE реализует следующую структуру:
|
||||
|
||||
---H---@------------------|QFT⁻¹|---M---
|
||||
|
|
||||
---H---@------------------|QFT⁻¹|---M---
|
||||
|
|
||||
---H---@------------------|QFT⁻¹|---M---
|
||||
|
|
||||
---|U|--|U²|--|U⁴|--|U⁸|------------
|
||||
|
||||
Измеренные биты M дают приближение фазы φ.
|
||||
"""
|
||||
|
||||
import cirq
|
||||
import numpy as np
|
||||
|
||||
|
||||
def run_phase_estimation(u_gate, n_qubits: int, repetitions: int):
|
||||
"""
|
||||
Строит и симулирует схему QPE (Quantum Phase Estimation).
|
||||
|
||||
Параметры:
|
||||
u_gate: унитарный оператор U, чья фаза e^{2πiφ} оценивается.
|
||||
n_qubits: количество кубитов в регистре фазы (точность ~1/2^n).
|
||||
repetitions: количество повторов измерений (для статистики).
|
||||
"""
|
||||
|
||||
# Кубит, к которому применяется оператор U.
|
||||
target = cirq.LineQubit(-1)
|
||||
|
||||
# Регистр для измерения фазы — n_qubits управляющих кубитов.
|
||||
phase_qubits = cirq.LineQubit.range(n_qubits)
|
||||
|
||||
# Контролируемые операторы U^(2^i)
|
||||
controlled_powers = [
|
||||
(u_gate ** (2**i)).on(target).controlled_by(phase_qubits[i])
|
||||
for i in range(n_qubits)
|
||||
]
|
||||
|
||||
# Схема QPE:
|
||||
circuit = cirq.Circuit(
|
||||
cirq.H.on_each(*phase_qubits), # 1. Адамар на все управляющие кубиты
|
||||
controlled_powers, # 2. Контролируемые степени U
|
||||
cirq.qft(*phase_qubits, without_reverse=True)
|
||||
** -1, # 3. Обратное квантовое преобразование Фурье
|
||||
cirq.measure(*phase_qubits, key="phase"), # 4. Измерение регистра фазы
|
||||
)
|
||||
|
||||
simulator = cirq.Simulator()
|
||||
result = simulator.run(circuit, repetitions=repetitions)
|
||||
return result
|
||||
|
||||
|
||||
def example_gate(phi: float):
|
||||
"""
|
||||
Пример 1-кубитного унитарного оператора U:
|
||||
U|0⟩ = e^{2πiφ}|0⟩,
|
||||
U|1⟩ = |1⟩.
|
||||
"""
|
||||
matrix = np.array([[np.exp(2j * np.pi * phi), 0], [0, 1]])
|
||||
return cirq.MatrixGate(matrix)
|
||||
|
||||
|
||||
def experiment(n_qubits: int, repetitions=100):
|
||||
"""
|
||||
Запускает серию экспериментов для разных значений фазы φ.
|
||||
"""
|
||||
print(f"\nТест с {n_qubits} кубитами")
|
||||
errors = []
|
||||
|
||||
for target_phi in np.arange(0, 1.0, 0.1):
|
||||
gate = example_gate(target_phi)
|
||||
result = run_phase_estimation(gate, n_qubits, repetitions)
|
||||
|
||||
# Наиболее часто встречающееся значение результата измерения
|
||||
mode = result.data["phase"].mode()[0]
|
||||
|
||||
# Переводим измеренный результат в оценку фазы
|
||||
phi_est = mode / (2**n_qubits)
|
||||
|
||||
print(
|
||||
f"target={target_phi:0.4f}, estimate={phi_est:0.4f} = {mode}/{2**n_qubits}"
|
||||
)
|
||||
errors.append((target_phi - phi_est) ** 2)
|
||||
|
||||
rms = np.sqrt(np.mean(errors))
|
||||
print(f"Среднеквадратичная ошибка (RMS): {rms:.4f}")
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Запускает эксперименты для разных количеств кубитов:
|
||||
2, 4 и 8 — для демонстрации роста точности.
|
||||
"""
|
||||
for n in (2, 4, 8):
|
||||
experiment(n, repetitions=200)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user