Zum Hauptinhalt springen

Estimator-Beispiele

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese oder neuere Versionen zu verwenden.

qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1

Die Beispiele in diesem Abschnitt zeigen einige gängige Verwendungsweisen des Estimator. Bevor du diese Beispiele ausführst, folge den Anweisungen unter Qiskit installieren.

hinweis

Alle diese Beispiele verwenden die Primitives aus Qiskit Runtime, du könntest jedoch stattdessen die Basis-Primitives verwenden.

Berechne und interpretiere mit dem Estimator effizient Erwartungswerte der Quantenoperatoren, die für viele Algorithmen benötigt werden. Erkunde Anwendungen in der Molekülmodellierung, im maschinellen Lernen und bei komplexen Optimierungsproblemen.

Ein einzelnes Experiment ausführen

Verwende den Estimator, um den Erwartungswert eines einzelnen Circuit-Observable-Paares zu bestimmen.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

n_qubits = 50

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

mat = np.real(random_hermitian(n_qubits, seed=1234))
circuit = iqp(mat)
observable = SparsePauliOp("Z" * 50)

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)

estimator = Estimator(mode=backend)
job = estimator.run([(isa_circuit, isa_observable)])
result = job.result()

print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
> Expectation value: -0.0564042303172738
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Mehrere Experimente in einem einzigen Job ausführen

Verwende den Estimator, um die Erwartungswerte mehrerer Circuit-Observable-Paare zu bestimmen.

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

n_qubits = 50

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

rng = np.random.default_rng()
mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]

pubs = []
circuits = [iqp(mat) for mat in mats]
observables = [
SparsePauliOp("X" * 50),
SparsePauliOp("Y" * 50),
SparsePauliOp("Z" * 50),
]

# Get ISA circuits
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)

for qc, obs in zip(circuits, observables):
isa_circuit = pm.run(qc)
isa_obs = obs.apply_layout(isa_circuit.layout)
pubs.append((isa_circuit, isa_obs))

estimator = Estimator(backend)
job = estimator.run(pubs)
job_result = job.result()

for idx in range(len(pubs)):
pub_result = job_result[idx]
print(f">>> Expectation values for PUB {idx}: {pub_result.data.evs}")
print(f">>> Standard errors for PUB {idx}: {pub_result.data.stds}")
>>> Expectation values for PUB 0: 0.09218950064020487
>>> Standard errors for PUB 0: 0.2666311918779662
>>> Expectation values for PUB 1: -0.7159533073929961
>>> Standard errors for PUB 1: 0.5443960702392404
>>> Expectation values for PUB 2: -0.14271555996035679
>>> Standard errors for PUB 2: 0.2714876601210801

Parametrisierte Circuits ausführen

Verwende den Estimator, um drei Experimente in einem einzigen Job auszuführen, und nutze dabei Parameterwerte, um die Wiederverwendbarkeit des Circuit zu erhöhen.

import numpy as np

from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

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

# Step 1: Map classical inputs to a quantum problem
theta = Parameter("θ")

chsh_circuit = QuantumCircuit(2)
chsh_circuit.h(0)
chsh_circuit.cx(0, 1)
chsh_circuit.ry(theta, 0)

number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
individual_phases = [[ph] for ph in phases]

ZZ = SparsePauliOp.from_list([("ZZ", 1)])
ZX = SparsePauliOp.from_list([("ZX", 1)])
XZ = SparsePauliOp.from_list([("XZ", 1)])
XX = SparsePauliOp.from_list([("XX", 1)])
ops = [ZZ, ZX, XZ, XX]

# Step 2: Optimize problem for quantum execution.

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
chsh_isa_circuit = pm.run(chsh_circuit)
isa_observables = [
operator.apply_layout(chsh_isa_circuit.layout) for operator in ops
]

# Step 3: Execute using Qiskit primitives.

# Reshape observable array for broadcasting
reshaped_ops = np.fromiter(isa_observables, dtype=object)
reshaped_ops = reshaped_ops.reshape((4, 1))

estimator = Estimator(backend, options={"default_shots": int(1e4)})
job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])
# Get results for the first (and only) PUB
pub_result = job.result()[0]
print(f">>> Expectation values: {pub_result.data.evs}")
print(f">>> Standard errors: {pub_result.data.stds}")
print(f">>> Metadata: {pub_result.metadata}")
>>> Expectation values: [[ 0.9821299 0.92848415 0.78219632 0.56555001 0.29732126 -0.02496591
-0.30928839 -0.5779298 -0.79292547 -0.92084995 -0.9806856 -0.93075378
-0.80014701 -0.57627916 -0.32496945 -0.00495192 0.29938456 0.56513735
0.80117866 0.92580187 0.98151091]
[-0.00330128 0.30949472 0.58123108 0.78549759 0.9357057 0.97903496
0.93240442 0.78879887 0.58267539 0.2948453 0.0041266 -0.29835291
-0.57339055 -0.78075201 -0.92477022 -0.97882863 -0.93075378 -0.79148116
-0.57958044 -0.30557445 0.00598356]
[-0.01031649 -0.34250749 -0.59257922 -0.80819387 -0.95159309 -0.99616033
-0.9336424 -0.78054568 -0.57112092 -0.30639977 0.00866585 0.30474913
0.57627916 0.81149515 0.95035511 0.99224006 0.9530374 0.78673557
0.57834246 0.30557445 -0.00866585]
[ 0.99616033 0.93446772 0.80344829 0.5841197 0.29401998 -0.01980766
-0.31300232 -0.59361087 -0.81170148 -0.94849814 -0.99327171 -0.93880064
-0.80860653 -0.58019943 -0.30186051 0.01856968 0.29009972 0.59835645
0.80613057 0.94437155 0.98976411]]
>>> Standard errors: [[0.00346988 0.00453617 0.00722056 0.00981693 0.01144016 0.01501324
0.01334599 0.01100181 0.00916772 0.00689316 0.00381375 0.00555949
0.00576968 0.01074419 0.01298665 0.01231428 0.0128399 0.00946472
0.00819982 0.00494361 0.00359142]
[0.01087106 0.01070164 0.00869617 0.00735853 0.00475886 0.00351362
0.00422178 0.00865889 0.00830071 0.01030088 0.01114086 0.01184411
0.00958307 0.00740947 0.00577496 0.00417023 0.00434772 0.00825295
0.00805684 0.01071724 0.01320466]
[0.01346985 0.01132597 0.01143045 0.00729025 0.00490636 0.00287136
0.0051666 0.00718324 0.00899331 0.00980723 0.00957352 0.01211162
0.00932736 0.00658862 0.00555066 0.00271584 0.00581507 0.00778402
0.00935326 0.01223799 0.01214173]
[0.00297333 0.00520897 0.00730712 0.01099862 0.01320699 0.01250301
0.0151248 0.00924768 0.00639241 0.00529221 0.00270411 0.00463968
0.00729108 0.00685512 0.00993793 0.0101938 0.01109962 0.01130657
0.00795711 0.00532976 0.00299901]]
>>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Batches und erweiterte Optionen verwenden

Erkunde den Batch-Ausführungsmodus und erweiterte Optionen, um die Circuit-Performance auf QPUs zu optimieren.

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Batch,
EstimatorV2 as Estimator,
)

n_qubits = 15

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

rng = np.random.default_rng(1234)
mat = np.real(random_hermitian(n_qubits, seed=rng))
circuit = iqp(mat)
mat = np.real(random_hermitian(n_qubits, seed=rng))
another_circuit = iqp(mat)
observable = SparsePauliOp("X" * n_qubits)
another_observable = SparsePauliOp("Y" * n_qubits)

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
another_isa_circuit = pm.run(another_circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
another_isa_observable = another_observable.apply_layout(
another_isa_circuit.layout
)

# The context manager automatically closes the batch.
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)

estimator.options.resilience_level = 1

job = estimator.run([(isa_circuit, isa_observable)])
another_job = estimator.run(
[(another_isa_circuit, another_isa_observable)]
)
result = job.result()
another_result = another_job.result()

# first job
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")

# second job
print(f" > Another Expectation value: {another_result[0].data.evs}")
print(f" > More Metadata: {another_result[0].metadata}")
> Expectation value: -0.03391665163268988
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
> Another Expectation value: -0.011113040458412918
> More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Nächste Schritte

Empfehlungen