Quimb-Schaltkreis-basiertes Backend
qiskit_addon_mpf.backends.quimb_circuit
Ein schaltkreisbasiertes Zeitentwicklungs-Backend mit quimb.
Dieses Backend ist nur verfügbar, wenn die optionalen Abhängigkeiten installiert wurden:
pip install "qiskit-addon-mpf[quimb]"Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
CircuitEvolver | Eine Zeitentwicklungsmaschine auf der Grundlage von Quantenschaltungen. |
CircuitState | Eine MPO-ähnliche Darstellung eines Zeitentwicklungszustands auf der Grundlage von Quantenschaltungen. |
Zugrunde liegende Methode
Quimb bietet eine direkte Unterstützung für die Simulation von Quantenschaltungen in Form einer auf Tensornetzen basierenden quimb.tensor.Circuit darstellung. Wir können dies nutzen, um jeden expliziten Zeitentwicklungsalgorithmus zu umgehen und stattdessen die Zeitentwicklung direkt in einem QuantumCircuit und verwenden quimb um die Überlappung zwischen zwei solchen Schaltungen zu berechnen. Weitere Informationen finden Sie in ihrem Leitfaden über Quantenschaltungen.
Codebeispiel
Dieser Abschnitt zeigt ein einfaches Beispiel, um Ihnen den Einstieg in die Verwendung dieses Backends zu erleichtern. Das Beispiel zeigt, wie die drei Fabrikfunktionen erstellt werden, die für die setup_dynamic_lse().
Das IdentityStateFactory protokoll wird bereits durch den CircuitState konstruktor erfüllt, so dass das Argument identity_factory trivial ist:
>>> from qiskit_addon_mpf.backends.quimb_circuit import CircuitState
>>> identity_factory = CircuitStateDie Einrichtung des CircuitEvolver ist etwas komplizierter. Es benötigt ein parametrisiertes QuantumCircuit objekt als Eingabe, wobei der Parameter an die Stelle des Zeitschritts der Trotter-Methode treten soll (dt).
Um zu zeigen, wie eine solche parametrisierte Trotter-Schaltungsvorlage aufgebaut ist, verwenden wir dieselbe Hamiltonformel und Suzuki-Trotter-Formel zweiter Ordnung wie in quimb_layers.
>>> from qiskit.quantum_info import SparsePauliOp
>>> hamil = SparsePauliOp.from_sparse_list(
... [("ZZ", (i, i+1), 1.0) for i in range(0, 9, 2)] +
... [("Z", (i,), 0.5) for i in range(10)] +
... [("ZZ", (i, i+1), 1.0) for i in range(1, 9, 2)] +
... [("X", (i,), 0.25) for i in range(10)],
... num_qubits=10,
... )Aber dieses Mal geben wir ein Parameter als Argument time an, wenn wir die eigentlichen Schaltungen konstruieren.
>>> from functools import partial
>>> from qiskit.circuit import Parameter
>>> from qiskit.synthesis import SuzukiTrotter
>>> from qiskit_addon_mpf.backends.quimb_circuit import CircuitEvolver
>>> from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
>>> dt = Parameter("dt")
>>> suzuki_2 = generate_time_evolution_circuit(hamil, time=dt, synthesis=SuzukiTrotter(order=2))
>>> approx_evolver_factory = partial(CircuitEvolver, circuit=suzuki_2)Es ist notwendig, dass der Name der Parameterdt ist!
Wir können eine Trotter-Formel höherer Ordnung für die exact_evolver_factory wählen. Beachten Sie aber, dass wir wieder eine parametrisierte Schaltung verwenden müssen, auch wenn wir deren Parameter sofort beim Aufbau der Funktion partial binden.
>>> suzuki_4 = generate_time_evolution_circuit(hamil, time=dt, synthesis=SuzukiTrotter(order=4))
>>> exact_evolver_factory = partial(CircuitEvolver, circuit=suzuki_4, dt=0.05)Diese Werksfunktionen können nun verwendet werden, um die setup_dynamic_lse(). Weitere Einzelheiten dazu finden Sie in der Dokumentation.