Pular para o conteúdo principal

Início rápido do Estimator

A primitiva Estimator calcula os valores esperados para um ou mais observáveis em relação aos estados preparados por Circuits quânticos. Os circuitos podem ser parametrizados, desde que os valores dos parâmetros também sejam fornecidos como entrada para a primitiva.

Esta primitiva tem várias técnicas de mitigação e supressão de erros integradas, incluindo desacoplamento dinâmico, Pauli-twirling, ZNE de dobragem de gate, PEA e PEC. Ela também suporta uma opção resilience_level que permite configurar facilmente o trade-off entre custo e precisão. Os passos neste tópico descrevem como configurar o Estimator, explorar as opções que você pode usar para configurá-lo e invocá-lo em um programa.

Versões dos pacotes

O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos usar essas versões ou versões mais recentes.

qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
```json

{/*Verified the v2 examples 2/29/24 - updated 10/29/24*/}

## Passos para usar a primitiva Estimator \{#steps-to-use-the-estimator-primitive}

### 1. Inicializar a conta \{#1-initialize-the-account}

Como o Qiskit Runtime é um serviço gerenciado, primeiro você precisa inicializar sua conta. Você pode então selecionar a QPU que deseja usar para calcular o valor esperado.

Siga os passos em [Configurar sua conta IBM Cloud](cloud-setup) se você ainda não tiver uma conta.

:::note[Gates fracionários]

Para usar os [gates fracionários](/guides/fractional-gates) recém-suportados, defina `use_fractional_gates=True` ao solicitar um Backend de uma instância `QiskitRuntimeService`. Por exemplo:
```python
service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Esta é uma funcionalidade experimental e pode mudar no futuro.

:::

from qiskit_ibm_runtime import QiskitRuntimeService

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

print(backend.name)
ibm_fez

2. Criar um circuito e um observável

Você precisa de pelo menos um circuito e um observável como entradas para a primitiva Estimator.

from qiskit.circuit.library import qaoa_ansatz
from qiskit.quantum_info import SparsePauliOp

entanglement = [tuple(edge) for edge in backend.coupling_map.get_edges()]
observable = SparsePauliOp.from_sparse_list(
[("ZZ", [i, j], 0.5) for i, j in entanglement],
num_qubits=backend.num_qubits,
)
circuit = qaoa_ansatz(observable, reps=2)
# The circuit is parametrized, so we will define the parameter values for execution
param_values = [0.1, 0.2, 0.3, 0.4]

O circuito e o observável precisam ser transformados para usar apenas instruções suportadas pela QPU (referidos como circuitos de arquitetura de conjunto de instruções (ISA)). Use o Transpiler para isso.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")
>>> Circuit ops (ISA): OrderedDict([('rz', 4472), ('sx', 1884), ('cz', 1120)])

3. Inicializar o Estimator do Qiskit Runtime

Ao inicializar o Estimator, use o parâmetro mode para especificar o modo em que você quer executá-lo. Os valores possíveis são objetos batch, session ou backend para os modos de execução em lote, Session e job, respectivamente. Para mais informações, veja Introdução aos modos de execução do Qiskit Runtime. Note que usuários do Plano Aberto não podem enviar jobs de Session.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Invocar o Estimator e obter resultados

Em seguida, invoque o método run() para calcular os valores esperados para os circuitos e observáveis de entrada. O circuito, o observável e os conjuntos opcionais de valores de parâmetros são fornecidos como tuplas de bloco unificado primitivo (PUB).

job = estimator.run([(isa_circuit, isa_observable, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")
>>> Job ID: d82869ntjchs73bnokog
>>> Job Status: QUEUED
result = job.result()
print(f">>> {result}")
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
>>> PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
> Expectation value: 30.60337496305257
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Próximos passos

Recomendações