Erstellen Sie eine Qiskit-Funktionsvorlage für die Hamilton-Simulation
Diese Vorlage kapselt einen Workflow zur Simulation der zeitlichen Entwicklung eines Anfangszustands gegenüber einem benutzerdefinierten spinbasierten Hamilton-Operator und gibt mithilfe des AQC-Tensor -Qiskit-Add-ons eine Reihe von festgelegten Erwartungswerten zurück.
Diese Vorlage ist wie ein Qiskit-Muster mit den folgenden Schritten aufgebaut:
1. Sammeln von Input und Erfassen des Problems
Dieser Abschnitt nimmt als Eingabe den zu simulierenden Hamiltonian, einen Anfangszustand in Form einer QuantumCircuit, einen Satz von Beobachtungswerten zur Schätzung von Erwartungswerten und eine Spezifikation von Optionen für das AQC-Addon. In diesem Schritt wird überprüft, ob alle erforderlichen Eingabedaten vorhanden sind und ob sie das richtige Format haben.
Die Eingangsargumente werden dann verwendet, um die entsprechenden Quantenschaltungen und Operatoren für den Arbeitsablauf zu konstruieren. Es wird eine Zielschaltung erstellt und mit Hilfe des AQC-Addons eine Matrixprodukt-Zustandsdarstellung dieser Schaltung gefunden. Anschließend wird ein Ansatzschaltkreis erzeugt und mit Hilfe von Tensornetzmethoden optimiert, so dass ein endgültiger Schaltkreis entsteht, der den Rest der Zeitentwicklung ausführt.
2. Bereiten Sie die generierten Schaltungen für die Ausführung vor
Die vom AQC-Addon generierten Schaltkreise werden dann zur Ausführung auf einem ausgewählten Backend transpiliert. Eine EstimatorV2 instanz wird mit einem Standardsatz von Optionen zur Fehlerbegrenzung erstellt, um die Ausführung der Schaltung zu verwalten.
3. Ausführung
Schließlich wird der Ansatzschaltkreis transpiliert und auf einer QPU ausgeführt und sammelt Schätzungen für alle angegebenen Erwartungswerte, die in einem serialisierbaren Format für den Zugriff durch den Benutzer zurückgegeben werden.
Schreiben Sie die Funktionsvorlage
Schreiben Sie zunächst eine Funktionsvorlage für die Hamilton-Simulation, die das AQC-Tensor-Qiskit-Add-on verwendet, um die Problemdarstellung auf einen Schaltkreis mit reduzierter Tiefe für die Ausführung auf Hardware abzubilden.
Wenn Sie diese Seite herunterladen und lokal in einem Notizbuch-Editor anzeigen, werden Sie feststellen, dass einige der Codezellen den Befehl „magic“ enthalten %%writefile. Dieser magische Befehl speichert den Code in ./source_files/template_hamiltonian_simulation.py, einer Funktionsvorlage, die Sie auf hochladen und über Qiskit Serverless remote ausführen können.
Die Eingaben sammeln und validieren
Beginnen Sie damit, die Eingaben für die Vorlage zu erhalten. Dieses Beispiel verfügt über domänenspezifische Eingaben, die für die Hamilton-Simulation relevant sind (z. B. Hamiltonian und Observable), sowie über fähigkeitsspezifische Optionen (z. B. wie stark Sie die anfänglichen Schichten des Trotter-Schaltkreises mit AQC-Tensor komprimieren möchten, oder erweiterte Optionen für die Feinabstimmung der Fehlerunterdrückung und -minderung, die über die Standardeinstellungen in diesem Beispiel hinausgehen).
from qiskit import QuantumCircuit
from qiskit_serverless import get_arguments, save_result
# Extract parameters from arguments
#
# Do this at the top of the program so it fails early if any required arguments
# are missing or invalid.
arguments = get_arguments()
dry_run = arguments.get("dry_run", False)
backend_name = arguments["backend_name"]
aqc_evolution_time = arguments["aqc_evolution_time"]
aqc_ansatz_num_trotter_steps = arguments["aqc_ansatz_num_trotter_steps"]
aqc_target_num_trotter_steps = arguments["aqc_target_num_trotter_steps"]
remainder_evolution_time = arguments["remainder_evolution_time"]
remainder_num_trotter_steps = arguments["remainder_num_trotter_steps"]
# Stop if this fidelity is achieved
aqc_stopping_fidelity = arguments.get("aqc_stopping_fidelity", 1.0)
# Stop after this number of iterations, even if stopping fidelity is not achieved
aqc_max_iterations = arguments.get("aqc_max_iterations", 500)
hamiltonian = arguments["hamiltonian"]
observable = arguments["observable"]
initial_state = arguments.get("initial_state",
QuantumCircuit(hamiltonian.num_qubits))import numpy as np
import json
from mergedeep import merge
# Configure `EstimatorOptions`, to control the parameters
# of the hardware experiment
#
# Set default options
estimator_default_options = {
"resilience": {
"measure_mitigation": True,
"zne_mitigation": True,
"zne": {
"amplifier": "gate_folding",
"noise_factors": [1, 2, 3],
"extrapolated_noise_factors": list(np.linspace(0, 3, 31)),
"extrapolator": ["exponential", "linear", "fallback"],
},
"measure_noise_learning": {
"num_randomizations": 512,
"shots_per_randomization": 512,
},
},
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": 300,
"shots_per_randomization": 100,
"strategy": "active",
},
}
# Merge with user-provided options
estimator_options = merge(
arguments.get("estimator_options", {}), estimator_default_options
)Wenn die Funktionsschablone läuft, ist es hilfreich, Informationen in den Protokollen mit Hilfe von Druckanweisungen zurückzugeben, so daß Sie den Fortschritt der Arbeitslast besser beurteilen können. Nachfolgend finden Sie ein einfaches Beispiel für das Drucken von estimator_options , um die tatsächlich verwendeten Estimator-Optionen zu dokumentieren. Es gibt noch viele weitere ähnliche Beispiele im gesamten Programm, um den Fortschritt während der Ausführung zu melden, einschließlich des Wertes der Zielfunktion während der iterativen Komponente von AQC-Tensor und der Zwei-Qubit-Tiefe der endgültigen ISA-Schaltung, die für die Ausführung auf Hardware vorgesehen ist.
print("estimator_options =", json.dumps(estimator_options, indent=4))Überprüfen Sie die Eingaben
Ein wichtiger Aspekt, um sicherzustellen, dass die Vorlage für eine Reihe von Eingaben wiederverwendet werden kann, ist die Eingabevalidierung. Der folgende Code ist ein Beispiel dafür, wie überprüft werden kann, ob die Anhaltetreue bei AQC-Tensor richtig angegeben wurde, und wenn nicht, eine informative Fehlermeldung zurückgegeben wird, wie der Fehler behoben werden kann.
# Perform parameter validation
if not 0.0 < aqc_stopping_fidelity <= 1.0:
raise ValueError(
f"Invalid stopping fidelity: {aqc_stopping_fidelity}. "
f"It must be a positive float no greater than 1."
)Bereiten Sie die Funktionsausgänge vor
Bereiten Sie zunächst ein Wörterbuch vor, das alle Ausgaben der Funktionsvorlagen enthält. Diesem Wörterbuch werden während des gesamten Arbeitsablaufs Schlüssel hinzugefügt, und es wird am Ende des Programms zurückgegeben.
output = {}Das Problem abbilden und die Schaltung mit AQC vorverarbeiten
Die AQC-Tensor-Optimierung erfolgt in Schritt 1 eines Qiskit-Musters. Zunächst wird ein Zielzustand konstruiert. In diesem Beispiel wird er aus einer Zielschaltung konstruiert, die denselben Hamiltonian für denselben Zeitraum entwickelt wie der AQC-Teil. Anschließend wird ein Ersatzschaltbild mit weniger Trotter-Schritten erstellt. Im Hauptteil des AQC-Algorithmus wird dieser Ansatz iterativ an den Zielzustand herangeführt. Schließlich wird das Ergebnis mit den verbleibenden Trotter-Schritten kombiniert, die erforderlich sind, um die gewünschte Entwicklungszeit zu erreichen.
Beachten Sie die zusätzlichen Beispiele für die Protokollierung, die im folgenden Code enthalten sind.
import os
os.environ["NUMBA_CACHE_DIR"] = "/data"
import datetime
import quimb.tensor
from scipy.optimize import OptimizeResult, minimize
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
from qiskit_addon_aqc_tensor.ansatz_generation import (
generate_ansatz_from_circuit,
AnsatzBlock,
)
from qiskit_addon_aqc_tensor.simulation import (
tensornetwork_from_circuit,
compute_overlap,
)
from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator
from qiskit_addon_aqc_tensor.objective import OneMinusFidelity
print("Hamiltonian:", hamiltonian)
print("Observable:", observable)
simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend="jax")
# Construct the AQC target circuit
aqc_target_circuit = initial_state.copy()
if aqc_evolution_time:
aqc_target_circuit.compose(
generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
time=aqc_evolution_time,
),
inplace=True,
)
# Construct matrix-product state representation of the AQC target state
aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings)
print("Target MPS maximum bond dimension:", aqc_target_mps.psi.max_bond())
output["target_bond_dimension"] = aqc_target_mps.psi.max_bond()
# Generate an ansatz and initial parameters from a Trotter circuit with fewer steps
aqc_good_circuit = initial_state.copy()
if aqc_evolution_time:
aqc_good_circuit.compose(
generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),
time=aqc_evolution_time,
),
inplace=True,
)
aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit)
print("Number of AQC parameters:", len(aqc_initial_parameters))
output["num_aqc_parameters"] = len(aqc_initial_parameters)
# Calculate the fidelity of ansatz circuit vs. the target state, before optimization
good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings)
starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2
print("Starting fidelity of AQC portion:", starting_fidelity)
output["aqc_starting_fidelity"] = starting_fidelity
# Optimize the ansatz parameters by using MPS calculations
def callback(intermediate_result: OptimizeResult):
fidelity = 1 - intermediate_result.fun
print(f"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}")
if intermediate_result.fun < stopping_point:
raise StopIteration
objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings)
stopping_point = 1.0 - aqc_stopping_fidelity
result = minimize(
objective,
aqc_initial_parameters,
method="L-BFGS-B",
jac=True,
options={"maxiter": aqc_max_iterations},
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.")
output["num_iterations"] = result.nit
aqc_final_parameters = result.x
output["aqc_final_parameters"] = list(aqc_final_parameters)
# Construct an optimized circuit for initial portion of time evolution
aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)
# Calculate fidelity after optimization
aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings)
aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2
print("Fidelity of AQC portion:", aqc_fidelity)
output["aqc_fidelity"] = aqc_fidelity
# Construct final circuit, with remainder of time evolution
final_circuit = aqc_final_circuit.copy()
if remainder_evolution_time:
remainder_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),
time=remainder_evolution_time,
)
final_circuit.compose(remainder_circuit, inplace=True)Optimieren Sie den endgültigen Schaltkreis für die Ausführung
Nach dem AQC-Teil des Workflows wird die final_circuit wie gewohnt auf die Hardware übertragen.
from qiskit_serverless import get_runtime_service
from qiskit.transpiler import generate_preset_pass_manager
service = get_runtime_service()
backend = service.backend(backend_name)
# Transpile PUBs (circuits and observables) to match ISA
pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3)
isa_circuit = pass_manager.run(final_circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)
print("ISA circuit two-qubit depth:", isa_2qubit_depth)
output["twoqubit_depth"] = isa_2qubit_depthBei Verwendung des Trockenlaufmodus frühzeitig beenden
Wenn der Trockenlaufmodus gewählt wurde, wird das Programm angehalten, bevor es auf der Hardware ausgeführt wird. Dies kann nützlich sein, wenn Sie beispielsweise zunächst die Zwei-Qubit-Tiefe der ISA-Schaltung prüfen wollen, bevor Sie sich für die Ausführung in Hardware entscheiden.
# Exit now if dry run; don't execute on hardware
if dry_run:
import sys
print("Exiting before hardware execution since `dry_run` is True.")
save_result(output)
sys.exit(0)Führen Sie den Schaltkreis auf der Hardware aus
# ## Step 3: Execute quantum experiments on backend
from qiskit_ibm_runtime import EstimatorV2 as Estimator
estimator = Estimator(backend, options=estimator_options)
# Submit the underlying Estimator job. Note that this is not the
# actual function job.
job = estimator.run([(isa_circuit, isa_observable)])
print("Job ID:", job.job_id())
output["job_id"] = job.job_id()
# Wait until job is complete
hw_results = job.result()
hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results]
# Save hardware results to serverless output dictionary
output["hw_results"] = hw_results_dicts
# Reorganize expectation values
hw_expvals = [pub_result_data["evs"].tolist()
for pub_result_data in hw_results_dicts]
# Save expectation values to Qiskit Serverless
print("Hardware expectation values", hw_expvals)
output["hw_expvals"] = hw_expvals[0]Die Ausgabe speichern
Diese Funktionsvorlage liefert die relevanten Ausgaben auf Domänenebene für diesen Hamilton-Simulations-Workflow (Erwartungswerte) sowie wichtige Metadaten, die auf dem Weg generiert wurden.
save_result(output)Stellen Sie die Funktion auf IBM Quantum Platform bereit
Im vorigen Abschnitt wurde ein Programm erstellt, das aus der Ferne ausgeführt werden soll. Mit dem Code in diesem Abschnitt wird das Programm auf Qiskit Serverless hochgeladen.
Verwenden Sie qiskit-ibm-catalog , um sich auf QiskitServerless mit Ihrem API-Schlüssel zu authentifizieren, den Sie auf dem Dashboard der Quantum-Plattform IBM finden, und laden Sie das Programm hoch.
Sie können optional verwenden, save_account() um Ihre Anmeldedaten zu speichern (siehe Anleitung zum Einrichten Ihres IBM Cloud -Kontos ). Beachten Sie, dass Ihre Anmeldedaten in dieselbe Datei wie QiskitRuntimeService.save_account(). geschrieben werden.
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
# Authenticate to the remote cluster and submit the pattern
# for remote execution
serverless = QiskitServerless()Dieses Programm hat eigene pip Abhängigkeiten. Fügen Sie sie bei der Erstellung der Instanz QiskitFunction zu einem Array dependencies hinzu:
template = QiskitFunction(
title="template_hamiltonian_simulation",
entrypoint="template_hamiltonian_simulation.py",
working_dir="./source_files/",
dependencies=[
"qiskit-addon-utils~=0.1.0",
"qiskit-addon-aqc-tensor[quimb-jax]~=0.1.2",
"mergedeep==1.3.4",
],
)serverless.upload(template)Output:
QiskitFunction(template_hamiltonian_simulation)
Prüfen Sie schließlich, ob das Programm erfolgreich hochgeladen wurde, indem Sie serverless.list() verwenden:
serverless.list()Output:
QiskitFunction(template_hamiltonian_simulation),
Führen Sie die Funktionsvorlage remote aus
Die Funktionsvorlage wurde hochgeladen, sodass Sie sie mit Qiskit Serverless aus der Ferne ausführen können. Laden Sie zunächst die Vorlage nach ihrem Namen:
template = serverless.load("template_hamiltonian_simulation")Führen Sie anschließend die Vorlage mit den Eingaben auf Domänenebene für die Hamilton-Simulation aus. Dieses Beispiel spezifiziert ein 50-Qubit-XXZ-Modell mit zufälligen Kopplungen, einem Anfangszustand und einer Beobachtungsgröße.
from itertools import chain
import numpy as np
from qiskit.quantum_info import SparsePauliOp
L = 50
# Generate the edge list for this spin-chain
edges = [(i, i + 1) for i in range(L - 1)]
# Generate an edge-coloring so we can make hw-efficient circuits
edges = edges[::2] + edges[1::2]
# Generate random coefficients for our XXZ Hamiltonian
np.random.seed(0)
Js = np.random.rand(L - 1) + 0.5 * np.ones(L - 1)
hamiltonian = SparsePauliOp.from_sparse_list(
chain.from_iterable(
[
[
("XX", (i, j), Js[i] / 2),
("YY", (i, j), Js[i] / 2),
("ZZ", (i, j), Js[i]),
]
for i, j in edges
]
),
num_qubits=L,
)
observable = SparsePauliOp.from_sparse_list(
[("ZZ", (L // 2 - 1, L // 2), 1.0)], num_qubits=L
)from qiskit import QuantumCircuit
initial_state = QuantumCircuit(L)
for i in range(L):
if i % 2:
initial_state.x(i)job = template.run(
dry_run=True,
initial_state=initial_state,
hamiltonian=hamiltonian,
observable=observable,
backend_name="ibm_fez",
estimator_options={},
aqc_evolution_time=0.2,
aqc_ansatz_num_trotter_steps=1,
aqc_target_num_trotter_steps=32,
remainder_evolution_time=0.2,
remainder_num_trotter_steps=4,
aqc_max_iterations=300,
)
print(job.job_id)Output:
853b0edb-d63f-4629-be71-398b6dcf33cb
Überprüfen Sie den Status des Auftrags:
job.status()Output:
'QUEUED'
Nachdem der Auftrag ausgeführt wurde, können Sie die Protokolle abrufen, die von den print() Ausgaben erstellt wurden. Diese können verwertbare Informationen über den Fortschritt des Hamilton-Simulationsablaufs liefern. Zum Beispiel der Wert der Zielfunktion während der iterativen Komponente von AQC oder die Zwei-Qubit-Tiefe des endgültigen ISA-Schaltkreises, der für die Ausführung in Hardware vorgesehen ist.
print(job.logs())Output:
No logs yet.
Blockieren Sie den Rest des Programms, bis ein Ergebnis vorliegt. Nach Abschluss der Arbeit können Sie die Ergebnisse abrufen. Dazu gehören die Ergebnisse der Hamilton-Simulation auf Domänenebene (Erwartungswert) und nützliche Metadaten.
result = job.result()
del result[
"aqc_final_parameters"
] # the list is too long to conveniently display here
resultOutput:
{'target_bond_dimension': 5,
'num_aqc_parameters': 816,
'aqc_starting_fidelity': 0.9914382555614002,
'num_iterations': 72,
'aqc_fidelity': 0.9998108844412502,
'twoqubit_depth': 33}
Nach Beendigung des Auftrags steht die gesamte Protokollierung zur Verfügung.
print(job.logs())Output:
2024-12-17 14:50:15,580 INFO job_manager.py:531 -- Runtime env is setting up.
estimator_options = {
"resilience": {
"measure_mitigation": true,
"zne_mitigation": true,
"zne": {
"amplifier": "gate_folding",
"noise_factors": [
1,
2,
3
],
"extrapolated_noise_factors": [
0.0,
0.1,
0.2,
0.30000000000000004,
0.4,
0.5,
0.6000000000000001,
0.7000000000000001,
0.8,
0.9,
1.0,
1.1,
1.2000000000000002,
1.3,
1.4000000000000001,
1.5,
1.6,
1.7000000000000002,
1.8,
1.9000000000000001,
2.0,
2.1,
2.2,
2.3000000000000003,
2.4000000000000004,
2.5,
2.6,
2.7,
2.8000000000000003,
2.9000000000000004,
3.0
],
"extrapolator": [
"exponential",
"linear",
"fallback"
]
},
"measure_noise_learning": {
"num_randomizations": 512,
"shots_per_randomization": 512
}
},
"twirling": {
"enable_gates": true,
"enable_measure": true,
"num_randomizations": 300,
"shots_per_randomization": 100,
"strategy": "active"
}
}
Hamiltonian: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXX', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYY', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'XXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'YYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],
coeffs=[0.52440675+0.j, 0.52440675+0.j, 1.0488135 +0.j, 0.55138169+0.j,
0.55138169+0.j, 1.10276338+0.j, 0.4618274 +0.j, 0.4618274 +0.j,
0.9236548 +0.j, 0.46879361+0.j, 0.46879361+0.j, 0.93758721+0.j,
0.73183138+0.j, 0.73183138+0.j, 1.46366276+0.j, 0.64586252+0.j,
0.64586252+0.j, 1.29172504+0.j, 0.53402228+0.j, 0.53402228+0.j,
1.06804456+0.j, 0.28551803+0.j, 0.28551803+0.j, 0.57103606+0.j,
0.2601092 +0.j, 0.2601092 +0.j, 0.5202184 +0.j, 0.63907838+0.j,
0.63907838+0.j, 1.27815675+0.j, 0.73930917+0.j, 0.73930917+0.j,
1.47861834+0.j, 0.48073968+0.j, 0.48073968+0.j, 0.96147936+0.j,
0.30913721+0.j, 0.30913721+0.j, 0.61827443+0.j, 0.32167664+0.j,
0.32167664+0.j, 0.64335329+0.j, 0.51092416+0.j, 0.51092416+0.j,
1.02184832+0.j, 0.38227781+0.j, 0.38227781+0.j, 0.76455561+0.j,
0.47807517+0.j, 0.47807517+0.j, 0.95615033+0.j, 0.2593949 +0.j,
0.2593949 +0.j, 0.5187898 +0.j, 0.55604786+0.j, 0.55604786+0.j,
1.11209572+0.j, 0.72187404+0.j, 0.72187404+0.j, 1.44374808+0.j,
0.42975395+0.j, 0.42975395+0.j, 0.8595079 +0.j, 0.5988156 +0.j,
0.5988156 +0.j, 1.1976312 +0.j, 0.58338336+0.j, 0.58338336+0.j,
1.16676672+0.j, 0.35519128+0.j, 0.35519128+0.j, 0.71038256+0.j,
0.40771418+0.j, 0.40771418+0.j, 0.81542835+0.j, 0.60759468+0.j,
0.60759468+0.j, 1.21518937+0.j, 0.52244159+0.j, 0.52244159+0.j,
1.04488318+0.j, 0.57294706+0.j, 0.57294706+0.j, 1.14589411+0.j,
0.6958865 +0.j, 0.6958865 +0.j, 1.391773 +0.j, 0.44172076+0.j,
0.44172076+0.j, 0.88344152+0.j, 0.51444746+0.j, 0.51444746+0.j,
1.02889492+0.j, 0.71279832+0.j, 0.71279832+0.j, 1.42559664+0.j,
0.29356465+0.j, 0.29356465+0.j, 0.5871293 +0.j, 0.66630992+0.j,
0.66630992+0.j, 1.33261985+0.j, 0.68500607+0.j, 0.68500607+0.j,
1.37001215+0.j, 0.64957928+0.j, 0.64957928+0.j, 1.29915856+0.j,
0.64026459+0.j, 0.64026459+0.j, 1.28052918+0.j, 0.56996051+0.j,
0.56996051+0.j, 1.13992102+0.j, 0.72233446+0.j, 0.72233446+0.j,
1.44466892+0.j, 0.45733097+0.j, 0.45733097+0.j, 0.91466194+0.j,
0.63711684+0.j, 0.63711684+0.j, 1.27423369+0.j, 0.53421697+0.j,
0.53421697+0.j, 1.06843395+0.j, 0.55881775+0.j, 0.55881775+0.j,
1.1176355 +0.j, 0.558467 +0.j, 0.558467 +0.j, 1.116934 +0.j,
0.59091015+0.j, 0.59091015+0.j, 1.1818203 +0.j, 0.46851598+0.j,
0.46851598+0.j, 0.93703195+0.j, 0.28011274+0.j, 0.28011274+0.j,
0.56022547+0.j, 0.58531893+0.j, 0.58531893+0.j, 1.17063787+0.j,
0.31446315+0.j, 0.31446315+0.j, 0.6289263 +0.j])
Observable: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII'],
coeffs=[1.+0.j])
Target MPS maximum bond dimension: 5
Number of AQC parameters: 816
Starting fidelity of AQC portion: 0.9914382555614002
2024-12-17 14:52:23.400028 Intermediate result: Fidelity 0.99764093
2024-12-17 14:52:23.429669 Intermediate result: Fidelity 0.99788003
2024-12-17 14:52:23.459674 Intermediate result: Fidelity 0.99795970
2024-12-17 14:52:23.489666 Intermediate result: Fidelity 0.99799067
2024-12-17 14:52:23.518545 Intermediate result: Fidelity 0.99803401
2024-12-17 14:52:23.546952 Intermediate result: Fidelity 0.99809821
2024-12-17 14:52:23.575271 Intermediate result: Fidelity 0.99824660
2024-12-17 14:52:23.604049 Intermediate result: Fidelity 0.99845326
2024-12-17 14:52:23.632709 Intermediate result: Fidelity 0.99870497
2024-12-17 14:52:23.660527 Intermediate result: Fidelity 0.99891442
2024-12-17 14:52:23.688273 Intermediate result: Fidelity 0.99904488
2024-12-17 14:52:23.716105 Intermediate result: Fidelity 0.99914438
2024-12-17 14:52:23.744336 Intermediate result: Fidelity 0.99922827
2024-12-17 14:52:23.773399 Intermediate result: Fidelity 0.99929071
2024-12-17 14:52:23.801482 Intermediate result: Fidelity 0.99932432
2024-12-17 14:52:23.830466 Intermediate result: Fidelity 0.99936460
2024-12-17 14:52:23.860738 Intermediate result: Fidelity 0.99938891
2024-12-17 14:52:23.889958 Intermediate result: Fidelity 0.99940607
2024-12-17 14:52:23.918703 Intermediate result: Fidelity 0.99941965
2024-12-17 14:52:23.949744 Intermediate result: Fidelity 0.99944337
2024-12-17 14:52:23.980871 Intermediate result: Fidelity 0.99946875
2024-12-17 14:52:24.012124 Intermediate result: Fidelity 0.99949009
2024-12-17 14:52:24.044359 Intermediate result: Fidelity 0.99952191
2024-12-17 14:52:24.075840 Intermediate result: Fidelity 0.99953669
2024-12-17 14:52:24.106303 Intermediate result: Fidelity 0.99955242
2024-12-17 14:52:24.139329 Intermediate result: Fidelity 0.99958412
2024-12-17 14:52:24.169725 Intermediate result: Fidelity 0.99960176
2024-12-17 14:52:24.198749 Intermediate result: Fidelity 0.99961606
2024-12-17 14:52:24.227874 Intermediate result: Fidelity 0.99963811
2024-12-17 14:52:24.256818 Intermediate result: Fidelity 0.99964383
2024-12-17 14:52:24.285889 Intermediate result: Fidelity 0.99964717
2024-12-17 14:52:24.315228 Intermediate result: Fidelity 0.99966064
2024-12-17 14:52:24.345322 Intermediate result: Fidelity 0.99966517
2024-12-17 14:52:24.374921 Intermediate result: Fidelity 0.99967089
2024-12-17 14:52:24.404309 Intermediate result: Fidelity 0.99968305
2024-12-17 14:52:24.432664 Intermediate result: Fidelity 0.99968889
2024-12-17 14:52:24.461639 Intermediate result: Fidelity 0.99969997
2024-12-17 14:52:24.491244 Intermediate result: Fidelity 0.99971666
2024-12-17 14:52:24.520354 Intermediate result: Fidelity 0.99972441
2024-12-17 14:52:24.549965 Intermediate result: Fidelity 0.99973561
2024-12-17 14:52:24.583464 Intermediate result: Fidelity 0.99973811
2024-12-17 14:52:24.617537 Intermediate result: Fidelity 0.99974074
2024-12-17 14:52:24.652247 Intermediate result: Fidelity 0.99974467
2024-12-17 14:52:24.686831 Intermediate result: Fidelity 0.99974991
2024-12-17 14:52:24.725476 Intermediate result: Fidelity 0.99975230
2024-12-17 14:52:24.764637 Intermediate result: Fidelity 0.99975373
2024-12-17 14:52:24.802499 Intermediate result: Fidelity 0.99975552
2024-12-17 14:52:24.839960 Intermediate result: Fidelity 0.99975885
2024-12-17 14:52:24.877472 Intermediate result: Fidelity 0.99976469
2024-12-17 14:52:24.916233 Intermediate result: Fidelity 0.99976517
2024-12-17 14:52:24.993750 Intermediate result: Fidelity 0.99976875
2024-12-17 14:52:25.034953 Intermediate result: Fidelity 0.99976887
2024-12-17 14:52:25.076197 Intermediate result: Fidelity 0.99977244
2024-12-17 14:52:25.112340 Intermediate result: Fidelity 0.99977638
2024-12-17 14:52:25.149947 Intermediate result: Fidelity 0.99977828
2024-12-17 14:52:25.190049 Intermediate result: Fidelity 0.99978174
2024-12-17 14:52:25.310903 Intermediate result: Fidelity 0.99978222
2024-12-17 14:52:25.347512 Intermediate result: Fidelity 0.99978508
2024-12-17 14:52:25.385201 Intermediate result: Fidelity 0.99978543
2024-12-17 14:52:25.457436 Intermediate result: Fidelity 0.99978770
2024-12-17 14:52:25.497133 Intermediate result: Fidelity 0.99978818
2024-12-17 14:52:25.541179 Intermediate result: Fidelity 0.99978913
2024-12-17 14:52:25.584791 Intermediate result: Fidelity 0.99978937
2024-12-17 14:52:25.621484 Intermediate result: Fidelity 0.99979068
2024-12-17 14:52:25.655847 Intermediate result: Fidelity 0.99979211
2024-12-17 14:52:25.691710 Intermediate result: Fidelity 0.99979700
2024-12-17 14:52:25.767711 Intermediate result: Fidelity 0.99979759
2024-12-17 14:52:25.804517 Intermediate result: Fidelity 0.99979807
2024-12-17 14:52:25.839394 Intermediate result: Fidelity 0.99980236
2024-12-17 14:52:25.874438 Intermediate result: Fidelity 0.99980296
2024-12-17 14:52:25.909900 Intermediate result: Fidelity 0.99980320
2024-12-17 14:52:26.713044 Intermediate result: Fidelity 0.99980320
Done after 72 iterations.
Fidelity of AQC portion: 0.9998108844412502
ISA circuit two-qubit depth: 33
Exiting before hardware execution since `dry_run` is True.
Nächste Schritte
Für einen tieferen Einblick in das AQC-Tensor Qiskit Addon, schauen Sie sich das Improved Trotterized Time Evolution with Approximate Quantum Compilation Tutorial oder das qiskit-addon-aqc-tensor Repository an.
Hier ist der gesamte Quelltext von
./source_files/template_hamiltonian_simulation.pyals ein Codeblock../source_files/template_hamiltonian_simulation_full.pyfrom qiskit import QuantumCircuit from qiskit_serverless import get_arguments, save_result # Extract parameters from arguments # # Do this at the top of the program so it fails early # if any required arguments are missing or invalid. arguments = get_arguments() dry_run = arguments.get("dry_run", False) backend_name = arguments["backend_name"] aqc_evolution_time = arguments["aqc_evolution_time"] aqc_ansatz_num_trotter_steps = arguments["aqc_ansatz_num_trotter_steps"] aqc_target_num_trotter_steps = arguments["aqc_target_num_trotter_steps"] remainder_evolution_time = arguments["remainder_evolution_time"] remainder_num_trotter_steps = arguments["remainder_num_trotter_steps"] # Stop if this fidelity is achieved aqc_stopping_fidelity = arguments.get("aqc_stopping_fidelity", 1.0) # Stop after this number of iterations, even if stopping fidelity is not achieved aqc_max_iterations = arguments.get("aqc_max_iterations", 500) hamiltonian = arguments["hamiltonian"] observable = arguments["observable"] initial_state = arguments.get("initial_state", QuantumCircuit(hamiltonian.num_qubits)) import numpy as np import json from mergedeep import merge # Configure `EstimatorOptions` to control the hardware experiment's parameters # # Set default options estimator_default_options = { "resilience": { "measure_mitigation": True, "zne_mitigation": True, "zne": { "amplifier": "gate_folding", "noise_factors": [1, 2, 3], "extrapolated_noise_factors": list(np.linspace(0, 3, 31)), "extrapolator": ["exponential", "linear", "fallback"], }, "measure_noise_learning": { "num_randomizations": 512, "shots_per_randomization": 512, }, }, "twirling": { "enable_gates": True, "enable_measure": True, "num_randomizations": 300, "shots_per_randomization": 100, "strategy": "active", }, } # Merge with user-provided options estimator_options = merge( arguments.get("estimator_options", {}), estimator_default_options ) print("estimator_options =", json.dumps(estimator_options, indent=4)) # Perform parameter validation if not 0.0 < aqc_stopping_fidelity <= 1.0: raise ValueError( f"Invalid stopping fidelity: {aqc_stopping_fidelity}. " It must be a positive float no greater than 1." ) output = {} import os os.environ["NUMBA_CACHE_DIR"] = "/data" import datetime import quimb.tensor from scipy.optimize import OptimizeResult, minimize from qiskit.synthesis import SuzukiTrotter from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit from qiskit_addon_aqc_tensor.ansatz_generation import ( generate_ansatz_from_circuit, AnsatzBlock, ) from qiskit_addon_aqc_tensor.simulation import ( tensornetwork_from_circuit, compute_overlap, ) from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator from qiskit_addon_aqc_tensor.objective import OneMinusFidelity print("Hamiltonian:", hamiltonian) print("Observable:", observable) simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend="jax") # Construct the AQC target circuit aqc_target_circuit = initial_state.copy() if aqc_evolution_time: aqc_target_circuit.compose( generate_time_evolution_circuit( hamiltonian, synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps), time=aqc_evolution_time, ), inplace=True, ) # Construct matrix-product state representation of the AQC target state aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings) print("Target MPS maximum bond dimension:", aqc_target_mps.psi.max_bond()) output["target_bond_dimension"] = aqc_target_mps.psi.max_bond() # Generate an ansatz and initial parameters from a Trotter circuit with fewer steps aqc_good_circuit = initial_state.copy() if aqc_evolution_time: aqc_good_circuit.compose( generate_time_evolution_circuit( hamiltonian, synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps), time=aqc_evolution_time, ), inplace=True, ) aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit) print("Number of AQC parameters:", len(aqc_initial_parameters)) output["num_aqc_parameters"] = len(aqc_initial_parameters) # Calculate the fidelity of ansatz circuit vs. the target state, before optimization good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings) starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2 print("Starting fidelity of AQC portion:", starting_fidelity) output["aqc_starting_fidelity"] = starting_fidelity # Optimize the ansatz parameters by using MPS calculations def callback(intermediate_result: OptimizeResult): fidelity = 1 - intermediate_result.fun print(f"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}") if intermediate_result.fun < stopping_point: raise StopIteration objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings) stopping_point = 1.0 - aqc_stopping_fidelity result = minimize( objective, aqc_initial_parameters, method="L-BFGS-B", jac=True, options={"maxiter": aqc_max_iterations}, 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.") output["num_iterations"] = result.nit aqc_final_parameters = result.x output["aqc_final_parameters"] = list(aqc_final_parameters) # Construct an optimized circuit for initial portion of time evolution aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters) # Calculate fidelity after optimization aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings) aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2 print("Fidelity of AQC portion:", aqc_fidelity) output["aqc_fidelity"] = aqc_fidelity # Construct final circuit, with remainder of time evolution final_circuit = aqc_final_circuit.copy() if remainder_evolution_time: remainder_circuit = generate_time_evolution_circuit( hamiltonian, synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps), time=remainder_evolution_time, ) final_circuit.compose(remainder_circuit, inplace=True) from qiskit.transpiler import generate_preset_pass_manager from qiskit_ibm_catalog import QiskitFunctionsCatalog from qiskit_serverless import get_runtime_service service = get_runtime_service() backend = service.backend(backend_name) # Transpile PUBs (circuits and observables) to match ISA pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3) isa_circuit = pass_manager.run(final_circuit) isa_observable = observable.apply_layout(isa_circuit.layout) isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2) print("ISA circuit two-qubit depth:", isa_2qubit_depth) output["twoqubit_depth"] = isa_2qubit_depth # Exit now if dry run; don't execute on hardware if dry_run: import sys print("Exiting before hardware execution since `dry_run` is True.") save_result(output) sys.exit(0) # ## Step 3: Execute quantum experiments on backend from qiskit_ibm_runtime import EstimatorV2 as Estimator estimator = Estimator(backend, options=estimator_options) # Submit the underlying Estimator job. Note that this is not the # actual function job. job = estimator.run([(isa_circuit, isa_observable)]) print("Job ID:", job.job_id()) output["job_id"] = job.job_id() # Wait until job is complete hw_results = job.result() hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results] # Save hardware results to serverless output dictionary output["hw_results"] = hw_results_dicts # Reorganize expectation values hw_expvals = [pub_result_data["evs"].tolist() for pub_result_data in hw_results_dicts] # Save expectation values to Qiskit Serverless output["hw_expvals"] = hw_expvals[0] save_result(output)