Skip to main content
IBM Quantum Platform

Exemplos de estimadores

  • O código desta página foi desenvolvido com base nos seguintes requisitos. Recomendamos usar essas versões ou versões mais recentes.

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

Os exemplos desta seção ilustram algumas formas comuns de usar o Estimator. Antes de executar estes exemplos, siga as instruções em Instalar o Qiskit.

Note

Todos esses exemplos utilizam as primitivas de Qiskit Runtime, mas você também pode usar as primitivas básicas.

Calcule e interprete com eficiência os valores esperados dos operadores quânticos necessários para muitos algoritmos com o Estimator. Explore as aplicações em modelagem molecular, aprendizado de máquina e problemas complexos de otimização.


Executar um único experimento

Use o Estimador para determinar o valor esperado de um único par circuito-observável.

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}

Execute várias experiências em uma única tarefa

Use o Estimator para determinar os valores esperados de vários pares de variáveis observáveis do 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

Executar circuitos parametrizados

Use o Estimator para executar três experimentos em uma única tarefa, aproveitando os valores dos parâmetros para aumentar a reutilização dos 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}

Use lotes e opções avançadas

Explore o modo de execução em lote e as opções avançadas para otimizar o desempenho dos circuitos nas 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,
    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óximas etapas

Recomendações
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.