Files
2025-11-19 11:27:58 +03:00

107 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Адаптированный пример алгоритма квантовой оценки фазы (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()