Lumaktaw sa pangunahing nilalaman

Pagsisimula sa Approximate quantum compilation gamit ang tensor networks (AQC-Tensor)

Mga bersyon ng package

Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na requirements. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago pa.

qiskit[all]~=2.3.0
qiskit-aer~=0.17
qiskit-addon-utils~=0.3.0
qiskit-addon-aqc-tensor[aer,quimb-jax]~=0.2.0; sys.platform != 'darwin'
scipy~=1.16.3

Ipinapakita ng gabay na ito ang isang simpleng halimbawa para makapagsimula sa AQC-Tensor. Sa halimbawang ito, kukuha ka ng Trotter circuit na nagsi-simulate ng ebolusyon ng isang transverse field Ising model at gagamitin ang pamamaraang AQC-Tensor para bawasan ang lalim ng circuit. Bukod dito, kailangan din ng halimbawang ito ang qiskit-addon-utils package para sa problem generator, qiskit-aer para sa tensor-network simulation, at scipy para sa parameter optimization.

Para magsimula, alalahanin na ang Hamiltonian ng transverse field Ising model ay may sumusunod na anyo

HIsing=βˆ‘i=1NJi,(i+1)ZiZi+1+hiXi\mathcal{H}_{Ising} = \sum_{i=1}^N J_{i,(i+1)}Z_iZ_{i+1} + h_i X_i

kung saan ipinapalagay natin ang periodic boundary conditions na nangangahulugang para sa i=10i=10 makukuha natin ang i+1=11β†’1i+1=11\rightarrow 1, ang JJ ay ang coupling strength sa pagitan ng dalawang site, at ang hh ay ang lakas ng external na magnetic field.

Ang sumusunod na code snippet ay gagawa ng Hamiltonian ng isang 10-site Ising chain na may periodic boundary conditions.

# Added by doQumentation β€” required packages for this notebook
!pip install -q qiskit qiskit-addon-aqc-tensor qiskit-addon-utils qiskit-aer scipy
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import (
generate_time_evolution_circuit,
)
from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
from qiskit_addon_aqc_tensor.simulation import tensornetwork_from_circuit
from qiskit_addon_aqc_tensor.simulation import compute_overlap
from qiskit_addon_aqc_tensor.objective import MaximizeStateFidelity
from qiskit_aer import AerSimulator
from scipy.optimize import OptimizeResult, minimize

# Generate some coupling map to use for this example
coupling_map = CouplingMap.from_heavy_hex(3, bidirectional=False)

# Choose a 10-qubit circle on this coupling map
reduced_coupling_map = coupling_map.reduce(
[0, 13, 1, 14, 10, 16, 4, 15, 3, 9]
)

# Get a qubit operator describing the Ising field model
hamiltonian = generate_xyz_hamiltonian(
reduced_coupling_map,
coupling_constants=(0.0, 0.0, 1.0),
ext_magnetic_field=(0.4, 0.0, 0.0),
)

Hatiin ang time evolution sa dalawang bahagi para sa classical at quantum na pagpapatupad​

Ang pangkalahatang layunin ng halimbawang ito ay i-simulate ang time evolution ng model Hamiltonian. Ginagawa natin ito dito sa pamamagitan ng Trotter evolution, na hahatiin sa dalawang bahagi.

  1. Isang paunang bahagi na masi-simulate gamit ang matrix product states (MPS). Ito ang magiging 'kompil' gamit ang AQC-Tensor.
  2. Isang kasunod na bahagi na ipapatupad sa quantum hardware.

Pag-eevolvein natin ang sistema hanggang sa oras na tf=5t_f=5 at gagamitin ang AQC-Tensor para i-compress ang time evolution hanggang sa oras na t=4t=4, pagkatapos ay mag-eevolve gamit ang ordinaryong Trotter steps hanggang tft_f.

Mula dito, gagawa tayo ng dalawang circuit β€” isa ang ico-compress gamit ang AQC-Tensor at isa ang ipapatupad sa QPU. Para sa unang circuit, dahil ito ay klasikal na si-simulate gamit ang matrix product states, gagamit tayo ng maraming layers para mabawasan ang Trotter error. Samantala, ang pangalawang circuit na nag-si-simulate ng time evolution mula ti=4t_i=4 hanggang tf=5t_f=5 ay gagamit ng mas kaunting layers para mabawasan ang lalim.

# Generate circuit to be compressed
aqc_evolution_time = 4.0
aqc_target_num_trotter_steps = 45

aqc_target_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
time=aqc_evolution_time,
)

# Generate circuit to execute on hardware
subsequent_evolution_time = 1.0
subsequent_num_trotter_steps = 5

subsequent_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=subsequent_num_trotter_steps),
time=subsequent_evolution_time,
)

Para sa paghahambing, gagawa rin tayo ng ikatlong circuit β€” isa na nag-eevolve hanggang t=4t=4, ngunit may parehong bilang ng layers tulad ng pangalawang circuit na nag-eevolve mula ti=4t_i=4 hanggang tf=5t_f=5. Ito ang circuit na sana ay ginamit natin kung hindi tayo gumamit ng pamamaraang AQC-Tensor. Tatawagin natin itong comparison circuit.

aqc_comparison_num_trotter_steps = int(
subsequent_num_trotter_steps
/ subsequent_evolution_time
* aqc_evolution_time
)
aqc_comparison_num_trotter_steps

comparison_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_comparison_num_trotter_steps),
time=aqc_evolution_time,
)

Gumawa ng ansatz at buuin ang MPS simulation​

Susunod, gagawa tayo ng ansatz na io-optimize natin. Mag-eevolve ito sa parehong evolution time tulad ng ating unang circuit (mula ti=0t_i=0 hanggang tf=4t_f=4), ngunit may mas kaunting Trotter steps.

Kapag nagawa na ang circuit, ipapasa natin ito sa generate_ansatz_from_circuit() function ng AQC-Tensor, na sinusuri ang two-qubit connectivity at nagbabalik ng dalawang bagay. Una ay isang nabuong ansatz circuit na may parehong two-qubit connectivity, at pangalawa ay isang set ng mga parameter na, kapag nilagyan ng halaga ang ansatz, nagbibigay ng input circuit.

aqc_ansatz_num_trotter_steps = 5

aqc_good_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),
time=aqc_evolution_time,
)

aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(
aqc_good_circuit, qubits_initially_zero=True
)
aqc_ansatz.draw("mpl", fold=-1)

Output of the previous code cell

Susunod, itatayo natin ang MPS representation ng estado na aaproksimahin ng AQC. Kalkulahin din natin ang fidelity ∣⟨ψ1∣ψ2⟩∣2|\langle\psi_1 | \psi_2 \rangle |^2 sa pagitan ng estado na ginawa ng comparison circuit kumpara sa circuit na gumagawa ng target state (na gumamit ng mas maraming Trotter steps).

# Generate MPS simulator settings and obtain the MPS representation of the target state
simulator_settings = AerSimulator(
method="matrix_product_state",
matrix_product_state_max_bond_dimension=100,
)
aqc_target_mps = tensornetwork_from_circuit(
aqc_target_circuit, simulator_settings
)

# Compute the fidelity between the MPS representation of the target state and the state produced by the comparison circuit
comparison_mps = tensornetwork_from_circuit(
comparison_circuit, simulator_settings
)
comparison_fidelity = (
abs(compute_overlap(comparison_mps, aqc_target_mps)) ** 2
)
print(f"Comparison fidelity: {comparison_fidelity}")
Comparison fidelity: 0.9997111919739693

I-optimize ang mga parameter ng ansatz gamit ang MPS​

Sa huli, io-optimize natin ang ansatz circuit para makagawa ito ng target state na may mas mataas na fidelity kaysa sa ating comparison_fidelity. Ang cost function na imi-minimize ay ang MaximizeStateFidelity at io-optimize gamit ang L-BFGS optimizer ng scipy.

objective = MaximizeStateFidelity(
aqc_target_mps, aqc_ansatz, simulator_settings
)

stopping_point = 1 - comparison_fidelity

def callback(intermediate_result: OptimizeResult):
print(f"Intermediate result: Fidelity {1 - intermediate_result.fun:.8}")
if intermediate_result.fun < stopping_point:
# Good enough for now
raise StopIteration

result = minimize(
objective,
aqc_initial_parameters,
method="L-BFGS-B",
jac=True,
options={"maxiter": 100},
callback=callback,
)
if (
result.status
not in (
0,
1,
99,
)
): # 0 => success; 1 => max iterations reached; 99 => early termination via StopIteration
raise RuntimeError(
f"Optimization failed: {result.message} (status={result.status})"
)

print(f"Done after {result.nit} iterations.")
aqc_final_parameters = result.x
Intermediate result: Fidelity 0.95084365
Intermediate result: Fidelity 0.98409893
Intermediate result: Fidelity 0.99142033
Intermediate result: Fidelity 0.99521405
Intermediate result: Fidelity 0.99566673
Intermediate result: Fidelity 0.99650054
Intermediate result: Fidelity 0.99683487
Intermediate result: Fidelity 0.99720426
Intermediate result: Fidelity 0.99761726
Intermediate result: Fidelity 0.99809073
Intermediate result: Fidelity 0.99838244
Intermediate result: Fidelity 0.99861841
Intermediate result: Fidelity 0.99874617
Intermediate result: Fidelity 0.99892696
Intermediate result: Fidelity 0.99908129
Intermediate result: Fidelity 0.99917737
Intermediate result: Fidelity 0.99925456
Intermediate result: Fidelity 0.99933134
Intermediate result: Fidelity 0.99947173
Intermediate result: Fidelity 0.99956469
Intermediate result: Fidelity 0.99964488
Intermediate result: Fidelity 0.99967419
Intermediate result: Fidelity 0.99968821
Intermediate result: Fidelity 0.9997448
Done after 24 iterations.

Sa puntong ito, mayroon na tayong set ng mga parameter na gumagawa ng target state na may mas mataas na fidelity kaysa sa gagawin sana ng comparison circuit nang hindi gumagamit ng AQC. Gamit ang mga pinakamainam na parameter na ito, ang compressed circuit ay may mas maliit na Trotter error at mas mababaw na lalim kaysa sa orihinal na circuit.

Bilang huling hakbang, itatayo ng sumusunod na code snippet ang buong time evolution circuit na maaaring ipasa sa isang transpiler pipeline at ipatupad sa quantum hardware.

final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)
final_circuit.compose(subsequent_circuit, inplace=True)
final_circuit.draw("mpl", fold=-1)

Output of the previous code cell

Mga susunod na hakbang​

Mga Rekomendasyon