больше кодовввв

This commit is contained in:
2025-11-19 11:27:58 +03:00
parent 8fbcb933a6
commit 7c58e681b2
5 changed files with 739 additions and 0 deletions

89
task8/naive.py Normal file
View 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
View 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
View 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()