Zum Hauptinhalt springen

Estimator-Schnellstart

Das Estimator-Primitive berechnet die Erwartungswerte für eine oder mehrere Observablen bezüglich der von Quantum Circuits präparierten Zustände. Die Circuits können parametrisiert sein, solange die Parameterwerte ebenfalls als Eingabe an das Primitive übergeben werden.

Dieses Primitive verfügt über mehrere eingebaute Fehlerminderungs- und -unterdrückungstechniken, darunter Dynamical Decoupling, Pauli-Twirling, Gate-Folding ZNE, PEA und PEC. Es unterstützt außerdem eine Option resilience_level, mit der du den Kompromiss zwischen Kosten und Genauigkeit einfach konfigurieren kannst. Die Schritte in diesem Thema beschreiben, wie du den Estimator einrichtest, die verfügbaren Konfigurationsoptionen erkundest und ihn in einem Programm aufrufst.

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime

Schritte zur Verwendung des Estimator-Primitives​

1. Konto initialisieren​

Du musst zunächst dein Konto initialisieren. Danach kannst du den QPU auswählen, den du zur Berechnung des Erwartungswerts verwenden möchtest.

Folge den Schritten unter IBM Cloud-Konto einrichten, falls du noch kein Konto hast.

Fractional Gates

Um die neu unterstützten Fractional Gates zu verwenden, setze use_fractional_gates=True, wenn du ein Backend von einer QiskitRuntimeService-Instanz anforderst. Zum Beispiel:

service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Dies ist eine experimentelle Funktion und kann sich in Zukunft ändern.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

print(backend.name)
ibm_fez

2. Circuit und Observable erstellen​

Du benötigst mindestens einen Circuit und eine Observable als Eingaben für das Estimator-Primitive.

from qiskit.circuit.library import qaoa_ansatz
from qiskit.quantum_info import SparsePauliOp

entanglement = [tuple(edge) for edge in backend.coupling_map.get_edges()]
observable = SparsePauliOp.from_sparse_list(
[("ZZ", [i, j], 0.5) for i, j in entanglement],
num_qubits=backend.num_qubits,
)
circuit = qaoa_ansatz(observable, reps=2)
# The circuit is parametrized, so we will define the parameter values for execution
param_values = [0.1, 0.2, 0.3, 0.4]

Der Circuit und die Observable müssen so transformiert werden, dass sie nur Anweisungen verwenden, die vom QPU unterstützt werden (bezeichnet als Instruction Set Architecture (ISA)-Circuits). Verwende dafür den Transpiler.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")
>>> Circuit ops (ISA): OrderedDict([('rz', 4472), ('sx', 1884), ('cz', 1120)])

3. Den IBM Quantum Estimator initialisieren​

Wenn du den Estimator initialisierst, verwende den Parameter mode, um den gewünschten Ausführungsmodus festzulegen. Mögliche Werte sind batch-, session- oder backend-Objekte für den Batch-, Session- bzw. Job-Ausführungsmodus. Weitere Informationen findest du unter Einführung in die IBM Quantum Compute Service-Ausführungsmodi. Beachte, dass Nutzer des Open Plan keine Session-Jobs einreichen können.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Estimator aufrufen und Ergebnisse abrufen​

Rufe als Nächstes die Methode run() auf, um Erwartungswerte für die Eingabe-Circuits und Observablen zu berechnen. Circuit, Observable und optionale Parameterwert-Sets werden als Primitive Unified Bloc (PUB)-Tupel übergeben.

job = estimator.run([(isa_circuit, isa_observable, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")
>>> Job ID: dab7lfurrl7c7386gjn0
>>> Job Status: QUEUED
result = job.result()
print(f">>> {result}")
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
>>> PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
> Expectation value: 28.60306448415693
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Nächste Schritte​

Empfehlungen