Ejemplos de Estimator
Versiones de paquetes
El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o más recientes.
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
Los ejemplos de esta sección ilustran algunas formas comunes de usar Estimator. Antes de ejecutar estos ejemplos, sigue las instrucciones en Instalar Qiskit.
Todos estos ejemplos usan los primitivos de IBM Quantum, pero también podrías usar los primitivos base en su lugar.
Calcula e interpreta eficientemente los valores de expectación de los operadores cuánticos necesarios para muchos algoritmos con Estimator. Explora sus usos en modelado molecular, aprendizaje automático y problemas de optimización complejos.
Ejecutar un solo experimento
Usa Estimator para determinar el valor de expectación de un único par circuito-observable.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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.012658227848101266
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
Ejecutar múltiples experimentos en un solo trabajo
Usa Estimator para determinar los valores de expectación de múltiples pares 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
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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.2650103519668737
>>> Standard errors for PUB 0: 0.49439861538856356
>>> Expectation values for PUB 1: -0.02099609375
>>> Standard errors for PUB 1: 0.013489459956524228
>>> Expectation values for PUB 2: 0.2788671023965142
>>> Standard errors for PUB 2: 0.4836236522960098
Ejecutar circuits parametrizados
Usa Estimator para ejecutar tres experimentos en un solo trabajo, aprovechando los valores de parámetros para aumentar la reutilización del circuit.
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
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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 IBM Quantum 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.9665404 0.90476418 0.77027221 0.53367788 0.27327396 -0.04118414
-0.32496864 -0.5686415 -0.78657426 -0.91870673 -0.95667336 -0.91656172
-0.78249875 -0.55877446 -0.2855005 0.0278851 0.31638861 0.58322755
0.78829027 0.92428375 0.96267938]
[ 0.01930507 0.31831912 0.5969556 0.80630833 0.92535625 0.96525339
0.91312971 0.7689852 0.55062343 0.27992348 -0.01158304 -0.30287506
-0.57679253 -0.80158932 -0.90562218 -0.96246488 -0.90669469 -0.77606373
-0.55641496 -0.29193553 0.01630206]
[-0.04719017 -0.35950326 -0.63599473 -0.84427497 -0.9669694 -1.00193302
-0.93565229 -0.77992474 -0.53861139 -0.25782991 0.05898771 0.34834922
0.62998871 0.83655294 0.95817487 1.00021701 0.93307828 0.77606373
0.54547542 0.26662444 -0.06670973]
[ 0.9969995 0.93543779 0.76426619 0.55963247 0.24967888 -0.06241972
-0.35221024 -0.63620924 -0.83440793 -0.96568239 -1.00536503 -0.93415078
-0.77949574 -0.56284998 -0.26855494 0.05362519 0.35070873 0.61797667
0.84212996 0.97104491 0.99850101]]
>>> Standard errors: [[0.00518482 0.00616652 0.00723301 0.01064988 0.01139583 0.01174119
0.01301757 0.01155567 0.00848267 0.00690879 0.00492396 0.00613768
0.00678488 0.00840832 0.01404782 0.01184222 0.00982484 0.00854968
0.00764619 0.00774419 0.00621175]
[0.01590044 0.01095813 0.01205478 0.00872719 0.00609088 0.0043678
0.00579195 0.00857024 0.01184119 0.01191681 0.01262258 0.01090978
0.01346398 0.00940893 0.00709353 0.00454548 0.00795003 0.00900232
0.00768466 0.01225787 0.01271092]
[0.01265687 0.01230849 0.00961079 0.00725756 0.00469446 0.00444008
0.00683132 0.00804195 0.01140408 0.01165563 0.01001761 0.01300941
0.01014068 0.00822676 0.00511424 0.00465829 0.00659315 0.00633185
0.00865837 0.0101667 0.01090357]
[0.00399857 0.0064308 0.0071202 0.00974728 0.01066452 0.01082351
0.01311009 0.01053503 0.00801145 0.00501261 0.00499458 0.00673144
0.00871285 0.00998373 0.01241673 0.01345925 0.00835253 0.00686725
0.00814337 0.00466632 0.00432618]]
>>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
Usar lotes y opciones avanzadas
Explora el modo de ejecución por lotes y las opciones avanzadas para optimizar el rendimiento del circuit en las QPUs.
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
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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.026385707741639945
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
> Another Expectation value: 0.0134052163776774
> More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
Próximos pasos
- Especifica opciones avanzadas de runtime.
- Practica con los primitivos trabajando en la lección de función de costo en IBM Quantum® Learning.
- Aprende a transpilar localmente en la sección Transpilar.
- Prueba la guía Comparar configuraciones del transpilador.
- Comprende los Límites de trabajos al enviar un trabajo a una QPU de IBM®.