Skip to main content
IBM Quantum Platform

Ejemplos de estimadores

  • El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o posteriores.

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

Los ejemplos de esta sección muestran algunas formas habituales de utilizar Estimator. Antes de ejecutar estos ejemplos, sigue las instrucciones de la sección «Instalar Qiskit».

Note

Todos estos ejemplos utilizan las primitivas de Qiskit Runtime, pero también podrías utilizar las primitivas básicas.

Con Estimator, calcula e interpreta de forma eficiente los valores esperados de los operadores cuánticos necesarios para numerosos algoritmos. Descubre sus aplicaciones en el modelado molecular, el aprendizaje automático y los problemas de optimización complejos.


Realizar un único experimento

Utiliza Estimator para calcular el valor esperado de un par circuito-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
)

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}")

Output:

 > Expectation value: -0.0564042303172738
 > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Ejecutar varios experimentos en un solo trabajo

Utilice Estimator para determinar los valores esperados de múltiples pares de variables observables del circuito.

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}")

Output:

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

Ejecutar circuitos parametrizados

Utiliza Estimator para ejecutar tres experimentos en un solo trabajo, aprovechando los valores de los parámetros para aumentar la reutilización de los circuitos.

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}")

Output:

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

Utiliza lotes y opciones avanzadas

Explora el modo de ejecución por lotes y las opciones avanzadas para optimizar el rendimiento de los circuitos en las 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}")

Output:

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

Próximos pasos

Recomendaciones
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.