QPE и IPE с шумом Athens
Сравните QPE и IPE в присутствии шума. Оценивается φ=1/3 для P(2π/3) на $|1\rangle$ с той же точностью, что у четырёх счётных кубитов QPE.
A. Сколько требуется классических битов? Запишите число в n.
B. Постройте IPE на одном вспомогательном и одном физическом кубите.
C. Постройте данную QPE для сравнения.
D. Выберите initial_layout по свойствам backend и транспилируйте IPE с optimization_level=3 в IPE_trans; напечатайте глубину. Для QPE исходный код транспилирует 500 экземпляров и выбирает наименьшую глубину.
E. Создайте NoiseModel.from_backend(backend) и выполните обе транспилированные схемы в шумовом симуляторе.
F. Вычислите точное идеальное распределение оценки фазы предоставленной программой.
G. Постройте сравнение и обсудите результат (в исходнике оба последних шага названы G).
В тексте автора устройство названо ibmq_Athens, но сохранённая программа использует именно FakeAthens — офлайн-модель. Доступ к действующему процессору не требуется. Точные данные и класс восстановлены из официального Qiskit 0.25.3: архив Athens, файлы fake_athens.py, conf_athens.json, props_athens.json, defs_athens.json, __init__.py. Нужна совместимая историческая среда Qiskit/Aer. Её запуск и новые шумовые результаты при подготовке не заявляются. Программа задаёт shots=20000, но в строке execute эта переменная явно не передана; оригинальная строка сохранена. Исходный образец сравнения находится в разборе.
Исходные определения и заготовки (код сохранён без исполнения):
from qiskit import *
import numpy as np
from qiskit.visualization import plot_histogram
import qiskit.tools.jupyter
import matplotlib.pyplot as plt
sim = Aer.get_backend('qasm_simulator')
## your answer goes here
n =
q = QuantumRegister(2)
c = ClassicalRegister(n)
IPE = QuantumCircuit(q,c)
########## your code goes here ############
#####################
IPE.draw()
def qft(n):
"""Creates an n-qubit QFT circuit"""
circuit = QuantumCircuit(n)
def swap_registers(circuit, n):
for qubit in range(n//2):
circuit.swap(qubit, n-qubit-1)
return circuit
def qft_rotations(circuit, n):
"""Performs qft on the first n qubits in circuit (without swaps)"""
if n == 0:
return circuit
n -= 1
circuit.h(n)
for qubit in range(n):
circuit.cp(np.pi/2**(n-qubit), qubit, n)
qft_rotations(circuit, n)
qft_rotations(circuit, n)
swap_registers(circuit, n)
return circuit
# define the parameters
t, psi = 4, 1/3*np.pi*2
# building a circuit
QPE = QuantumCircuit(t+1,t)
QPE.h(range(t))
QPE.x(t)
for idx in range(t):
QPE.cp(psi*2**idx, idx, t)
qft_dag = qft(t).to_gate().inverse()
qft_dag.label = 'QFT+'
QPE.append(qft_dag, range(t))
QPE.measure(range(t), range(t))
QPE.draw()
from qiskit.providers.fake_provider import FakeAthens
import qiskit.tools.jupyter
backend = FakeAthens()
backend
######## your code to transpile IPE circuit goes here ########
#####################
print(IPE_trans.depth())
num = 500
QPE_trans = transpile([QPE]*num, backend, optimization_level=3)
QPE_trans_depth = np.array([QPE_trans[idx].depth() for idx in range(num)])
print(min(QPE_trans_depth), max(QPE_trans_depth))
best_arg = np.argmin(QPE_trans_depth)
QPE_trans_best = QPE_trans[best_arg]
from qiskit.providers.aer.noise import NoiseModel
noise_model = NoiseModel.from_backend(backend)
shots = 20000
counts = execute([IPE_trans, QPE_trans_best], sim, noise_model=noise_model).result().get_counts()
from qiskit.quantum_info import Statevector
QPE_exact = QuantumCircuit(t+1)
QPE_exact.h(range(t))
QPE_exact.x(t)
for idx in range(t):
QPE_exact.cp(psi*2**idx, idx, t)
qft_dag = qft(t).to_gate().inverse()
qft_dag.label = 'QFT+'
QPE_exact.append(qft_dag, range(t))
#QPE_exact.draw('mpl')
state = Statevector.from_instruction(QPE_exact)
pmf = state.probabilities_dict(range(4))
def count_new(count):
phi_est = np.array([round(int(key, 2)/2**t, 3) for key in list(count.keys())])
key_new = list(map(str, phi_est))
count_new = dict(zip(key_new, count.values()))
return count_new
pmf_new = count_new(pmf)
count_IPE = count_new(counts[0])
count_QPE = count_new(counts[1])
fig, ax = plt.subplots(1, 2, figsize=(32,10))
fig.suptitle('QPE .vs. IPE for estimating $\\theta=1/3$', fontsize=23)
plot_histogram([pmf_new, count_QPE], ax=ax[0], legend=['No_noise', 'Athens_sim'])
plot_histogram([pmf_new, count_IPE], ax=ax[1], legend=['No_noise', 'Athens_sim'])
ax[0].set_title('QPE circuit result', fontsize=16)
ax[0].set_xlabel('$\\theta$', fontsize=16)
ax[1].set_title('IPE circuit result', fontsize=16)
ax[1].set_xlabel('$\\theta$', fontsize=16)
plt.show()