Vai al contenuto principale

Avvio rapido con Estimator

La primitiva Estimator calcola i valori di aspettazione per uno o più osservabili rispetto agli stati preparati da circuito quantistici. I circuito possono essere parametrizzati, purché i valori dei parametri siano forniti anche come input alla primitiva.

Questa primitiva dispone di diverse tecniche integrate di mitigazione e soppressione degli errori, tra cui il decoupling dinamico, il Pauli-twirling, ZNE con gate-folding, PEA e PEC. Supporta inoltre un'opzione resilience_level che ti consente di configurare facilmente il compromesso costo-accuratezza. I passaggi in questo argomento descrivono come configurare Estimator, esplorare le opzioni che puoi usare per configurarlo e invocarlo in un programma.

Versioni dei pacchetti

Il codice in questa pagina è stato sviluppato con i seguenti requisiti. Ti consigliamo di utilizzare queste versioni o versioni più recenti.

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

## Passaggi per utilizzare la primitiva Estimator \{#steps-to-use-the-estimator-primitive}

### 1. Inizializza l'account \{#1-initialize-the-account}

Poiché Qiskit Runtime è un servizio gestito, devi prima inizializzare il tuo account. Puoi quindi selezionare la QPU che desideri utilizzare per calcolare il valore di aspettazione.

Segui i passaggi in [Configura il tuo account IBM Cloud](cloud-setup) se non hai già un account.

:::note[gate frazionari]

Per utilizzare i [gate frazionari](/guides/fractional-gates) supportati di recente, imposta `use_fractional_gates=True` quando richiedi un backend da un'istanza di `QiskitRuntimeService`. Ad esempio:
```python
service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Questa è una funzionalità sperimentale e potrebbe cambiare in 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. Crea un circuito e un osservabile

Hai bisogno di almeno un circuito e un osservabile come input per la 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]

Il circuito e l'osservabile devono essere trasformati per usare solo le istruzioni supportate dalla QPU (chiamati circuiti instruction set architecture (ISA)). Usa il Transpiler per farlo.

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. Inizializza Qiskit Runtime Estimator

Quando inizializzi Estimator, usa il parametro mode per specificare la modalità in cui vuoi che venga eseguito. I valori possibili sono oggetti batch, session o backend per la modalità di esecuzione batch, session e job rispettivamente. Per ulteriori informazioni, consulta Introduzione alle modalità di esecuzione di Qiskit Runtime. Nota che gli utenti del piano Open non possono inviare job di Session.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Invoca Estimator e ottieni i risultati

Poi, invoca il metodo run() per calcolare i valori di aspettazione per i circuito di input e gli osservabili. Il circuito, l'osservabile e i set opzionali di valori dei parametri vengono passati come tuple primitive unified bloc (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}

Passi successivi

Raccomandazioni