Aller au contenu principal

Exemples Estimator

Versions des packages

Le code sur cette page a été développé en utilisant les exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

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

Les exemples de cette section illustrent quelques façons courantes d'utiliser Estimator. Avant d'exécuter ces exemples, suis les instructions dans Installer Qiskit.

remarque

Ces exemples utilisent tous les primitives de Qiskit Runtime, mais tu pourrais utiliser les primitives de base à la place.

Calcule et interprète efficacement les valeurs d'espérance des opérateurs quantiques requis par de nombreux algorithmes avec Estimator. Explore les applications en modélisation moléculaire, apprentissage automatique et problèmes d'optimisation complexes.

Exécuter une seule expérience

Utilise Estimator pour déterminer la valeur d'espérance d'une paire circuit-observable unique.

# 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}

Exécuter plusieurs expériences dans un seul job

Utilise Estimator pour déterminer les valeurs d'espérance de plusieurs paires circuit-observable.

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

Exécuter des circuits paramétrés

Utilise Estimator pour exécuter trois expériences dans un seul job, en tirant parti des valeurs de paramètres pour augmenter la réutilisabilité des circuits.

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}

Utiliser les batches et les options avancées

Explore le mode d'exécution batch et les options avancées pour optimiser les performances des circuits sur les QPU.

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}

Étapes suivantes

Recommandations