Przejdź do głównej treści

Dane wejściowe i wyjściowe Estimator

Wersje pakietów

Kod na tej stronie został opracowany przy użyciu następujących wymagań. Zalecamy używanie tych lub nowszych wersji.

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

Ta strona zawiera przegląd danych wejściowych i wyjściowych prymitywu Qiskit Runtime Estimator, który wykonuje obciążenia robocze na zasobach obliczeniowych IBM Quantum®. Estimator pozwala efektywnie definiować zwektoryzowane obciążenia robocze za pomocą struktury danych zwanej Primitive Unified Bloc (PUB). Są one używane jako dane wejściowe do metody run() prymitywu Estimator, który wykonuje zdefiniowane obciążenie robocze jako zadanie. Następnie, po zakończeniu zadania, wyniki są zwracane w formacie zależnym zarówno od użytych PUB-ów, jak i opcji środowiska uruchomieniowego określonych przez prymityw.

Dane wejściowe

Każdy PUB ma ten format:

(<pojedynczy obwód>, <jeden lub więcej obserwabli>, <opcjonalne wartości parametrów>, <opcjonalna precyzja>),

Opcjonalne wartości parametrów mogą być listą lub pojedynczym parametrem. Elementy z obserwabli i wartości parametrów są łączone zgodnie z regułami rozgłaszania NumPy opisanymi w temacie Dane wejściowe i wyjściowe prymitywu, i zwracana jest jedna szacowana wartość oczekiwana dla każdego elementu rozgłoszonego kształtu.

info

Jeśli dane wejściowe zawierają pomiary, są one ignorowane.

Dla prymitywu Estimator PUB może zawierać co najwyżej cztery wartości:

  • Pojedynczy QuantumCircuit, który może zawierać jeden lub więcej obiektów Parameter
  • Listę jednego lub więcej obserwabli, które określają szacowane wartości oczekiwane, ułożone w tablicę (na przykład pojedyncza obserwabla reprezentowana jako tablica 0-wymiarowa, lista obserwabli jako tablica 1-wymiarowa itd.). Dane mogą być w dowolnym formacie ObservablesArrayLike, takim jak Pauli, SparsePauliOp, PauliList lub str.
    Obserwable przemienne
    • Obserwable przemienne w tym samym PUB są grupowane razem za pomocą tej metody.
    • Obserwable przemienne w różnych PUB-ach, nawet jeśli mają ten sam obwód, nie są szacowane za pomocą tego samego pomiaru. Każdy PUB reprezentuje inną bazę pomiaru, dlatego dla każdego PUB wymagane są osobne pomiary.
    • Aby upewnić się, że obserwable przemienne są szacowane za pomocą tego samego pomiaru, zgrupuj je w tym samym PUB.
  • Kolekcja wartości parametrów do powiązania z obwodem. Można ją określić jako pojedynczy obiekt podobny do tablicy, gdzie ostatni indeks jest nad obiektami Parameter obwodu, lub pominąć (lub równoważnie ustawić na None), jeśli obwód nie ma obiektów Parameter.
  • (Opcjonalnie) Docelowa precyzja szacowania wartości oczekiwanych

Poniższy kod demonstruje przykładowy zestaw zwektoryzowanych danych wejściowych dla prymitywu Estimator i wykonuje je na backendzie IBM® jako pojedynczy obiekt RuntimeJobV2.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit.circuit import (
Parameter,
QuantumCircuit,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp

from qiskit_ibm_runtime import (
QiskitRuntimeService,
EstimatorV2 as Estimator,
)

import numpy as np

# Instantiate runtime service and get
# the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Define a circuit with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.rz(Parameter("b"), 0)
circuit.cx(0, 1)
circuit.h(0)

# Transpile the circuit
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
layout = transpiled_circuit.layout

# Now define a sweep over parameter values, the last axis of dimension 2 is
# for the two parameters "a" and "b"
params = np.vstack(
[
np.linspace(-np.pi, np.pi, 100),
np.linspace(-4 * np.pi, 4 * np.pi, 100),
]
).T

# Define three observables. The inner length-1 lists cause this array of
# observables to have shape (3, 1), rather than shape (3,) if they were
# omitted.
observables = [
[SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
[SparsePauliOp("XX")],
[SparsePauliOp("IY")],
]
# Apply the same layout as the transpiled circuit.
observables = [
[observable.apply_layout(layout) for observable in observable_set]
for observable_set in observables
]

# Estimate the expectation value for all 300 combinations of observables
# and parameter values, where the pub result will have shape (3, 100).
#
# This shape is due to our array of parameter bindings having shape
# (100, 2), combined with our array of observables having shape (3, 1).
estimator_pub = (transpiled_circuit, observables, params)

# Instantiate the new Estimator object, then run the transpiled circuit
# using the set of parameters and observables.
estimator = Estimator(mode=backend)
job = estimator.run([estimator_pub])
result = job.result()

Dane wyjściowe

Po wysłaniu jednego lub więcej PUB-ów do QPU i pomyślnym zakończeniu zadania dane są zwracane jako obiekt kontenera PrimitiveResult dostępny przez wywołanie metody RuntimeJobV2.result().

PrimitiveResult zawiera iterowalną listę obiektów PubResult, które zawierają wyniki wykonania dla każdego PUB.

Każdy element tej listy odpowiada każdemu PUB przesłanemu do metody run() prymitywu (na przykład zadanie przesłane z 20 PUB-ami zwróci obiekt PrimitiveResult zawierający listę 20 obiektów PubResult, po jednym odpowiadającym każdemu PUB).

Każdy PubResult dla prymitywu Estimator zawiera co najmniej tablicę wartości oczekiwanych (PubResult.data.evs) i powiązanych odchyleń standardowych (albo PubResult.data.stds, albo PubResult.data.ensemble_standard_error w zależności od użytego resilience_level), ale może zawierać więcej danych w zależności od opcji łagodzenia błędów, które zostały określone.

Każdy obiekt PubResult posiada zarówno atrybut data, jak i metadata.

  • Atrybut data to dostosowany DataBin, który zawiera rzeczywiste wartości pomiaru, odchylenia standardowe i tym podobne.
  • DataBin ma różne atrybuty w zależności od kształtu lub struktury powiązanego PUB oraz opcji łagodzenia błędów określonych przez prymityw użyty do przesłania zadania (na przykład ZNE lub PEC).
  • Atrybut metadata zawiera informacje o opcjach środowiska uruchomieniowego i łagodzenia błędów (wyjaśnione później w sekcji Metadane wyników na tej stronie).

Poniżej przedstawiono wizualny zarys struktury danych PrimitiveResult dla danych wyjściowych Estimator:

└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── evs
│ │ └── List of estimated expectation values in the shape
| | specified by the first pub
│ └── stds
│ └── List of calculated standard deviations in the
| same shape as above
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| ├── evs
| │ └── List of estimated expectation values in the shape
| | specified by the second pub
| └── stds
| └── List of calculated standard deviations in the
| same shape as above
├── ...
├── ...
└── ...

Mówiąc prosto, pojedyncze zadanie zwraca obiekt PrimitiveResult i zawiera listę jednego lub więcej obiektów PubResult. Te obiekty PubResult przechowują następnie dane pomiaru dla każdego PUB przesłanego do zadania.

Poniższy fragment kodu opisuje format PrimitiveResult (i powiązanego PubResult) dla zadania utworzonego powyżej.

print(
f"The result of the submitted job had {len(result)} "
f"PUBs and has a value:\n {result}\n"
)
print(
"The associated PubResult of this job has the following data bins:\n "
"{result[0].data}\n"
)
print(f"And this DataBin has attributes: {result[0].data.keys()}")
print(
"Recall that this shape is due to our array of parameter binding sets"
"having shape (100, 2), where 2 is the number of parameters in the "
"circuit, combined with our array of observables having shape (3, 1). \n"
)
with np.printoptions(threshold=200):
print(
"The expectation values measured from this PUB are: \n"
"{result[0].data.evs}\n"
)
The result of the submitted job had 1 PUB and has a value:
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), 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})

The associated PubResult of this job has the following data bins:
DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100))

And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding sets having shape (100, 2) -- where 2 is the
number of parameters in the circuit -- combined with our array of observables having shape (3, 1).

The expectation values measured from this PUB are:
[[-0.00369065 0.15107692 0.30110431 ... -0.30159536 -0.15431523
0.00576586]
[ 0.00601655 0.04412133 0.1253447 ... -0.12434194 -0.04662823
0.01153171]
[-0.01339784 0.2580325 0.47686391 ... -0.47884878 -0.26200223
0. ]]

Jak prymityw Estimator oblicza błąd

Oprócz szacowania średniej obserwabli przekazanych we wejściowych PUB-ach (pole evs w DataBin), Estimator próbuje również dostarczyć szacowanie błędu związanego z tymi wartościami oczekiwanymi. Wszystkie zapytania Estimator wypełnią pole stds wartością podobną do standardowego błędu średniej dla każdej wartości oczekiwanej, ale niektóre opcje łagodzenia błędów generują dodatkowe informacje, takie jak ensemble_standard_error.

Rozważ pojedynczą obserwablę O\mathcal{O}. W przypadku braku ZNE możesz myśleć o każdym strzale (shot) wykonania Estimator jako o dostarczającym punktowe szacowanie wartości oczekiwanej O\langle \mathcal{O} \rangle. Jeśli szacowania punktowe są w wektorze Os, wartość zwrócona w ensemble_standard_error jest równoważna następującej (gdzie σO\sigma_{\mathcal{O}} to odchylenie standardowe szacowania wartości oczekiwanej, a NshotsN_{shots} to liczba pomiarów):

σONshots,\frac{ \sigma_{\mathcal{O}} }{ \sqrt{N_{shots}} },

co traktuje wszystkie pomiary jako część jednego zespołu. Jeśli zażądałeś twirlingowania bramek (twirling.enable_gates = True), możesz posortować punktowe szacowania O\langle \mathcal{O} \rangle w zestawy dzielące wspólny twirl. Nazwijmy te zestawy szacowań O_twirls, a jest ich num_randomizations (liczba twirli). Wtedy stds to standardowy błąd średniej O_twirls, jak:

σONtwirls,\frac{ \sigma_{\mathcal{O}} }{ \sqrt{N_{twirls}} },

gdzie σO\sigma_{\mathcal{O}} to odchylenie standardowe O_twirls, a NtwirlsN_{twirls} to liczba twirli. Gdy nie włączasz twirlingowania, stds i ensemble_standard_error są równe.

Jeśli włączysz ZNE, opisane powyżej stds stają się wagami w nieliniowej regresji do modelu ekstrapolacyjnego. To, co ostatecznie jest zwracane w stds w tym przypadku, to niepewność modelu dopasowania obliczona przy współczynniku szumu równym zero. Przy złym dopasowaniu lub dużej niepewności dopasowania, raportowane stds mogą stać się bardzo duże. Gdy ZNE jest włączone, pub_result.data.evs_noise_factors i pub_result.data.stds_noise_factors są również wypełniane, dzięki czemu możesz wykonać własną ekstrapolację.

Metadane wyników

Oprócz wyników wykonania, zarówno obiekty PrimitiveResult, jak i PubResult zawierają atrybut metadanych o przesłanym zadaniu. Metadane zawierające informacje dla wszystkich przesłanych PUB-ów (takie jak różne opcje środowiska uruchomieniowego) można znaleźć w PrimitiveResult.metatada, natomiast metadane specyficzne dla każdego PUB są w PubResult.metadata.

uwaga

W polu metadanych implementacje prymitywów mogą zwracać wszelkie informacje o wykonaniu, które są dla nich istotne, i nie ma par klucz-wartość, które są gwarantowane przez prymityw bazowy. Dlatego zwrócone metadane mogą być różne w różnych implementacjach prymitywów.

# Print out the results metadata
print("The metadata of the PrimitiveResult is:")
for key, val in result.metadata.items():
print(f"'{key}' : {val},")

print("\nThe metadata of the PubResult result is:")
for key, val in result[0].metadata.items():
print(f"'{key}' : {val},")
The metadata of the PrimitiveResult is:
'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,

The metadata of the PubResult result is:
'shots' : 4096,
'target_precision' : 0.015625,
'circuit_metadata' : {},
'resilience' : {},
'num_randomizations' : 32,