Input dan output primitif
Keluaran beta bagi model pelaksanaan baharu kini tersedia. Model pelaksanaan terarah memberikan lebih fleksibiliti semasa menyesuaikan aliran kerja pengurangan ralat anda. Lihat panduan Model pelaksanaan terarah untuk maklumat lanjut.
Versi pakej
Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan penggunaan versi ini atau yang lebih baharu.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Halaman ini memberikan gambaran keseluruhan tentang input dan output primitif Qiskit Runtime yang melaksanakan beban kerja pada sumber pengkomputeran IBM Quantum®. Primitif ini membolehkan anda mentakrifkan beban kerja yang divektorkan dengan cekap menggunakan struktur data yang dikenali sebagai Primitive Unified Bloc (PUB). PUB ini merupakan unit kerja asas yang diperlukan oleh QPU untuk melaksanakan beban kerja tersebut. Ia digunakan sebagai input kepada kaedah run() untuk primitif Sampler dan Estimator, yang melaksanakan beban kerja yang ditakrifkan sebagai satu tugas. Kemudian, selepas tugas selesai, hasilnya dikembalikan dalam format yang bergantung pada PUB yang digunakan serta pilihan masa jalan yang ditetapkan daripada primitif Sampler atau Estimator.
Gambaran keseluruhan PUB​
Apabila menggunakan kaedah run() sesebuah primitif, argumen utama yang diperlukan ialah satu list yang mengandungi satu atau lebih tupel — satu bagi setiap Circuit yang dilaksanakan oleh primitif tersebut. Setiap tupel ini dianggap sebagai PUB, dan elemen yang diperlukan bagi setiap tupel dalam senarai bergantung pada primitif yang digunakan. Data yang diberikan kepada tupel ini juga boleh disusun dalam pelbagai bentuk untuk memberikan fleksibiliti dalam beban kerja melalui penyiaran — peraturannya diterangkan dalam bahagian berikut.
Estimator PUB​
Untuk primitif Estimator, format PUB mestilah mengandungi paling banyak empat nilai:
- Satu
QuantumCircuittunggal, yang mungkin mengandungi satu atau lebih objekParameter - Senarai satu atau lebih boleh cerap (observables), yang menentukan nilai jangkaan untuk dianggarkan, disusun dalam suatu tatasusunan (contohnya, satu boleh cerap tunggal diwakili sebagai tatasusunan 0-d, senarai boleh cerap sebagai tatasusunan 1-d, dan seterusnya). Data boleh berada dalam mana-mana satu format
ObservablesArrayLikesepertiPauli,SparsePauliOp,PauliList, ataustr.notaJika anda mempunyai dua boleh cerap yang bertukar-tukar (commuting) dalam PUB yang berbeza tetapi dengan Circuit yang sama, ia tidak akan dianggarkan menggunakan pengukuran yang sama. Setiap PUB mewakili asas pengukuran yang berbeza, justeru pengukuran berasingan diperlukan untuk setiap PUB. Untuk memastikan boleh cerap yang bertukar-tukar dianggarkan menggunakan pengukuran yang sama, ia mesti dikumpulkan dalam PUB yang sama.
- Koleksi nilai parameter untuk mengikat Circuit. Ini boleh ditetapkan sebagai satu objek seperti tatasusunan di mana indeks terakhir adalah atas objek
ParameterCircuit, atau diabaikan (atau setara, ditetapkan kepadaNone) jika Circuit tidak mempunyai objekParameter. - (Pilihan) ketepatan sasaran untuk nilai jangkaan yang hendak dianggarkan
Sampler PUB​
Untuk primitif Sampler, format tupel PUB mengandungi paling banyak tiga nilai:
- Satu
QuantumCircuittunggal, yang mungkin mengandungi satu atau lebih objekParameterNota: Circuit ini juga seharusnya mengandungi arahan pengukuran untuk setiap Qubit yang hendak dipersamplkan. - Koleksi nilai parameter untuk mengikat Circuit terhadap (hanya diperlukan jika ada objek
Parameteryang mesti diikat semasa masa jalan) - (Pilihan) bilangan tembakan untuk mengukur Circuit
Kod berikut menunjukkan contoh set input yang divektorkan kepada primitif Estimator dan melaksanakannya pada Backend IBM® sebagai satu objek RuntimeJobV2 .
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit.circuit import (
Parameter,
QuantumCircuit,
ClassicalRegister,
QuantumRegister,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives.containers import BitArray
from qiskit_ibm_runtime import (
QiskitRuntimeService,
EstimatorV2 as Estimator,
SamplerV2 as Sampler,
)
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()
Peraturan penyiaran​
PUB menggabungkan elemen daripada pelbagai tatasusunan (boleh cerap dan nilai parameter) dengan mengikuti peraturan penyiaran yang sama seperti NumPy. Bahagian ini meringkaskan peraturan tersebut secara ringkas. Untuk penjelasan terperinci, lihat dokumentasi peraturan penyiaran NumPy.
Peraturan:
- Tatasusunan input tidak perlu mempunyai bilangan dimensi yang sama.
- Tatasusunan yang terhasil akan mempunyai bilangan dimensi yang sama dengan tatasusunan input yang mempunyai dimensi terbesar.
- Saiz setiap dimensi ialah saiz terbesar bagi dimensi yang sepadan.
- Dimensi yang tiada dianggap mempunyai saiz satu.
- Perbandingan bentuk bermula dari dimensi paling kanan dan diteruskan ke kiri.
- Dua dimensi serasi jika saiznya sama atau jika salah satunya ialah 1.
Contoh pasangan tatasusunan yang boleh disiarkan:
A1 (1d array): 1
A2 (2d array): 3 x 5
Result (2d array): 3 x 5
A1 (3d array): 11 x 2 x 7
A2 (3d array): 11 x 1 x 7
Result (3d array): 11 x 2 x 7
Contoh pasangan tatasusunan yang tidak boleh disiarkan:
A1 (1d array): 5
A2 (1d array): 3
A1 (2d array): 2 x 1
A2 (3d array): 6 x 5 x 4 # This would work if the middle dimension were 2, but it is 5.
EstimatorV2 mengembalikan satu anggaran nilai jangkaan bagi setiap elemen bentuk yang disiarkan.
Berikut adalah beberapa contoh corak biasa yang dinyatakan dari segi penyiaran tatasusunan. Representasi visual yang menyertainya ditunjukkan dalam rajah yang berikut:
Set nilai parameter diwakili oleh tatasusunan n x m, dan tatasusunan boleh cerap diwakili oleh satu atau lebih tatasusunan lajur tunggal. Bagi setiap contoh dalam kod sebelumnya, set nilai parameter digabungkan dengan tatasusunan boleh cerap mereka untuk menghasilkan anggaran nilai jangkaan.
-
Contoh 1: (siarkan satu boleh cerap) mempunyai set nilai parameter yang merupakan tatasusunan 5x1 dan tatasusunan boleh cerap 1x1. Item tunggal dalam tatasusunan boleh cerap digabungkan dengan setiap item dalam set nilai parameter untuk menghasilkan tatasusunan 5x1 tunggal di mana setiap item adalah gabungan item asal dalam set nilai parameter dengan item dalam tatasusunan boleh cerap.
-
Contoh 2: (zip) mempunyai set nilai parameter 5x1 dan tatasusunan boleh cerap 5x1. Output ialah tatasusunan 5x1 di mana setiap item adalah gabungan item ke-n dalam set nilai parameter dengan item ke-n dalam tatasusunan boleh cerap.
-
Contoh 3: (luar/hasil) mempunyai set nilai parameter 1x6 dan tatasusunan boleh cerap 4x1. Gabungan mereka menghasilkan tatasusunan 4x6 yang dicipta dengan menggabungkan setiap item dalam set nilai parameter dengan setiap item dalam tatasusunan boleh cerap, justeru setiap nilai parameter menjadi satu lajur penuh dalam output.
-
Contoh 4: (Generalisasi nd piawai) mempunyai tatasusunan set nilai parameter 3x6 dan dua tatasusunan boleh cerap 3x1. Ini digabungkan untuk menghasilkan dua tatasusunan output 3x6 dengan cara yang serupa dengan contoh sebelumnya.
# Broadcast single observable
parameter_values = np.random.uniform(size=(5,)) # shape (5,)
observables = SparsePauliOp("ZZZ") # shape ()
# >> pub result has shape (5,)
# Zip
parameter_values = np.random.uniform(size=(5,)) # shape (5,)
observables = [
SparsePauliOp(pauli) for pauli in ["III", "XXX", "YYY", "ZZZ", "XYZ"]
] # shape (5,)
# >> pub result has shape (5,)
# Outer/Product
parameter_values = np.random.uniform(size=(1, 6)) # shape (1, 6)
observables = [
[SparsePauliOp(pauli)] for pauli in ["III", "XXX", "YYY", "ZZZ"]
] # shape (4, 1)
# >> pub result has shape (4, 6)
# Standard nd generalization
parameter_values = np.random.uniform(size=(3, 6)) # shape (3, 6)
observables = [
[
[SparsePauliOp(["XII"])],
[SparsePauliOp(["IXI"])],
[SparsePauliOp(["IIX"])],
],
[
[SparsePauliOp(["ZII"])],
[SparsePauliOp(["IZI"])],
[SparsePauliOp(["IIZ"])],
],
] # shape (2, 3, 1)
# >> pub result has shape (2, 3, 6)
Setiap SparsePauliOp dikira sebagai satu elemen dalam konteks ini, tanpa mengira bilangan Pauli yang terkandung dalam SparsePauliOp. Oleh itu, bagi tujuan peraturan penyiaran ini, semua elemen berikut mempunyai bentuk yang sama:
a = SparsePauliOp("Z") # shape ()
b = SparsePauliOp("IIIIZXYIZ") # shape ()
c = SparsePauliOp.from_list(["XX", "XY", "IZ"]) # shape ()
Senarai pengoperasi berikut, walaupun setara dari segi maklumat yang terkandung, mempunyai bentuk yang berbeza:
list1 = SparsePauliOp.from_list(["XX", "XY", "IZ"]) # shape ()
list2 = [SparsePauliOp("XX"), SparsePauliOp("XY"), SparsePauliOp("IZ")] # shape (3, )
Gambaran keseluruhan output primitif​
Setelah satu atau lebih PUB dihantar ke QPU untuk dilaksanakan dan tugas berjaya diselesaikan, data dikembalikan sebagai objek kontena PrimitiveResult yang diakses dengan memanggil kaedah RuntimeJobV2.result(). PrimitiveResult mengandungi senarai boleh ulang bagi objek PubResult yang mengandungi hasil pelaksanaan bagi setiap PUB. Bergantung pada primitif yang digunakan, data ini akan berbentuk nilai jangkaan dan bar ralat dalam kes Estimator, atau sampel output Circuit dalam kes Sampler.
Setiap elemen dalam senarai ini sepadan dengan setiap PUB yang diserahkan kepada kaedah run() primitif (contohnya, tugas yang diserahkan dengan 20 PUB akan mengembalikan objek PrimitiveResult yang mengandungi senarai 20 PubResult, satu sepadan dengan setiap PUB).
Setiap objek PubResult ini mempunyai atribut data dan metadata. Atribut data ialah DataBin yang disesuaikan dan mengandungi nilai pengukuran sebenar, sisihan piawai, dan sebagainya. DataBin ini mempunyai pelbagai atribut bergantung pada bentuk atau struktur PUB yang berkaitan serta pilihan pengurangan ralat yang ditetapkan oleh primitif yang digunakan untuk menghantar tugas (contohnya, ZNE atau PEC). Sementara itu, atribut metadata mengandungi maklumat tentang pilihan masa jalan dan pengurangan ralat yang digunakan (diterangkan kemudian dalam bahagian Metadata hasil pada halaman ini).
Berikut ialah garis besar visual struktur data PrimitiveResult:
- Output Estimator
- Output Sampler
└── 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
├── ...
├── ...
└── ...
└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── NAME_OF_CLASSICAL_REGISTER
│ │ └── BitArray of count data (default is 'meas')
| |
│ └── NAME_OF_ANOTHER_CLASSICAL_REGISTER
│ └── BitArray of count data (exists only if more than one
| ClassicalRegister was specified in the circuit)
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| └── NAME_OF_CLASSICAL_REGISTER
| └── BitArray of count data for second pub
├── ...
├── ...
└── ...
Ringkasnya, satu tugas mengembalikan objek PrimitiveResult dan mengandungi senarai satu atau lebih objek PubResult. Objek PubResult ini kemudian menyimpan data pengukuran bagi setiap PUB yang diserahkan kepada tugas tersebut.
Setiap PubResult mempunyai format dan atribut yang berbeza berdasarkan jenis primitif yang digunakan untuk tugas tersebut. Perinciannya diterangkan di bawah.
Output Estimator​
Setiap PubResult untuk primitif Estimator mengandungi sekurang-kurangnya satu tatasusunan nilai jangkaan (PubResult.data.evs) dan sisihan piawai yang berkaitan (sama ada PubResult.data.stds atau PubResult.data.ensemble_standard_error bergantung pada resilience_level yang digunakan), tetapi boleh mengandungi lebih banyak data bergantung pada pilihan pengurangan ralat yang ditetapkan.
Petikan kod di bawah menerangkan format PrimitiveResult (dan PubResult yang berkaitan) bagi tugas yang dibuat di atas.
print(
f"The result of the submitted job had {len(result)} PUB and has a value:\n {result}\n"
)
print(
f"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\n\
number of parameters in the circuit -- combined with our array of observables having shape (3, 1). \n"
)
print(
f"The expectation values measured from this PUB are: \n{result[0].data.evs}"
)
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.00948597 0.12163221 0.29100944 0.40535344 0.46625814 0.54716103
0.57690846 0.59809047 0.5784682 0.50924868 0.4579837 0.40035644
0.37174056 0.32887613 0.25850853 0.26396412 0.25852429 0.26074166
0.29282485 0.34388535 0.37368314 0.43562138 0.46912323 0.51955146
0.54430185 0.55467261 0.5162183 0.52744696 0.47261781 0.42613541
0.35400013 0.33217125 0.29600426 0.27561903 0.25307754 0.25672088
0.28783701 0.36612701 0.40433263 0.44428286 0.51028376 0.55034507
0.55979913 0.57160124 0.54127534 0.49753533 0.42942659 0.32552331
0.20215918 0.04303087 -0.08115732 -0.18473659 -0.34015892 -0.44489319
-0.49112115 -0.54588034 -0.60601287 -0.55869218 -0.53353861 -0.51628053
-0.44978534 -0.38090252 -0.32481576 -0.28832245 -0.27057547 -0.26542929
-0.27054473 -0.29367389 -0.31531828 -0.38462352 -0.40276794 -0.47168997
-0.48548191 -0.5382924 -0.52716406 -0.53277032 -0.50776933 -0.48512907
-0.44335198 -0.38756463 -0.34438156 -0.29199194 -0.2729216 -0.24602918
-0.23527174 -0.3019153 -0.35159518 -0.38303379 -0.42434541 -0.47743033
-0.54652609 -0.5877912 -0.59175701 -0.57386895 -0.56416812 -0.48022381
-0.3853372 -0.2639702 -0.12030502 0.02081148]
[ 0.00581765 0.0552677 0.15998546 0.20725389 0.25452232 0.34178711
0.39196437 0.47050268 0.50031815 0.527952 0.57231161 0.64066903
0.72429779 0.77011181 0.78174711 0.86610308 0.88646487 0.91337151
0.94245978 0.98100173 0.97372966 1.00936279 1.01881647 1.0544496
1.01954368 1.03699664 0.99845469 1.03845105 1.00936279 1.00354513
0.95409508 0.95264067 0.91264431 0.91846196 0.8355604 0.80283611
0.77956549 0.74102354 0.69520953 0.64575948 0.58976457 0.53231524
0.43996 0.3956004 0.32069812 0.27706572 0.22470684 0.16653032
0.07272066 -0.00218162 -0.05817653 -0.06253977 -0.15853104 -0.25015908
-0.28506499 -0.34251432 -0.44359604 -0.44432324 -0.53158804 -0.60285429
-0.637033 -0.67630215 -0.71266249 -0.76793019 -0.81519862 -0.86464867
-0.90173621 -0.93155168 -0.9337333 -0.98245614 -0.99627307 -1.01518044
-1.01590764 -1.04863194 -1.00499955 -1.02827016 -1.01663485 -1.0108172
-1.02317971 -0.97518407 -0.96500318 -0.94682302 -0.901009 -0.87846559
-0.79556404 -0.84937733 -0.78101991 -0.73811472 -0.65521316 -0.57667485
-0.59921825 -0.49813653 -0.44577766 -0.36505772 -0.33524225 -0.25888556
-0.21161713 -0.12289792 -0.03781474 0.00654486]
[ 0.01315429 0.18799671 0.42203343 0.603453 0.67799397 0.75253494
0.76185256 0.72567827 0.65661825 0.49054535 0.3436558 0.16004385
0.01918334 -0.11235955 -0.26473006 -0.33817484 -0.36941628 -0.39188819
-0.35681008 -0.29323102 -0.22636339 -0.13812003 -0.08057002 -0.01534667
0.06906002 0.07234859 0.03398191 0.01644286 -0.06412716 -0.15127432
-0.24609482 -0.28829816 -0.32063579 -0.3672239 -0.32940532 -0.28939435
-0.20389148 -0.00876953 0.11345574 0.24280625 0.43080296 0.5683749
0.67963826 0.74760208 0.76185256 0.71800493 0.63414634 0.48451631
0.3315977 0.08824335 -0.10413812 -0.30693341 -0.52178679 -0.6396273
-0.69717731 -0.74924637 -0.76842971 -0.67306111 -0.53548918 -0.42970677
-0.26253768 -0.08550288 0.06303097 0.19128528 0.27404768 0.33379008
0.36064675 0.34420389 0.30309674 0.2132091 0.19073719 0.07180049
0.04494382 -0.02795286 -0.04932858 -0.03727049 0.00109619 0.04055906
0.13647575 0.20005481 0.27624007 0.36283913 0.3551658 0.38640723
0.32502055 0.24554673 0.07782954 -0.02795286 -0.19347767 -0.3781858
-0.49383393 -0.67744588 -0.73773637 -0.78268019 -0.793094 -0.70156207
-0.55905728 -0.40504248 -0.20279529 0.0350781 ]]
Cara Estimator mengira ralat​
Selain anggaran min bagi boleh cerap yang dimasukkan dalam PUB input (medan evs dalam DataBin), Estimator juga cuba memberikan anggaran ralat yang berkaitan dengan nilai jangkaan tersebut. Semua pertanyaan estimator akan mengisi medan stds dengan kuantiti seperti ralat piawai min bagi setiap nilai jangkaan, tetapi sesetengah pilihan pengurangan ralat menghasilkan maklumat tambahan, seperti ensemble_standard_error.
Pertimbangkan satu boleh cerap tunggal . Tanpa ZNE, anda boleh menganggap setiap tembakan pelaksanaan Estimator sebagai memberikan anggaran titik bagi nilai jangkaan . Jika anggaran titik ada dalam vektor Os, maka nilai yang dikembalikan dalam ensemble_standard_error adalah setara dengan berikut (di mana ialah sisihan piawai anggaran nilai jangkaan dan ialah bilangan tembakan):
yang menganggap semua tembakan sebagai sebahagian daripada satu ensemble. Jika anda meminta twirling Gate (twirling.enable_gates = True), anda boleh menyusun anggaran titik ke dalam set yang berkongsi twirl yang sama. Panggil set anggaran ini O_twirls, dan terdapat num_randomizations (bilangan twirl) daripadanya. Maka stds ialah ralat piawai min bagi O_twirls, seperti dalam
di mana ialah sisihan piawai O_twirls dan ialah bilangan twirl. Apabila anda tidak mengaktifkan twirling, stds dan ensemble_standard_error adalah sama.
Jika anda mengaktifkan ZNE, maka stds yang diterangkan di atas menjadi pemberat dalam regresi tak linear kepada model extrapolator. Apa yang akhirnya dikembalikan dalam stds dalam kes ini ialah ketidakpastian model padanan yang dinilai pada faktor hingar sifar. Apabila terdapat padanan yang lemah, atau ketidakpastian padanan yang besar, stds yang dilaporkan boleh menjadi sangat besar. Apabila ZNE diaktifkan, pub_result.data.evs_noise_factors dan pub_result.data.stds_noise_factors juga diisi, supaya anda boleh melakukan ekstrapolasi sendiri.
Output Sampler​
Apabila tugas Sampler berjaya diselesaikan, objek PrimitiveResult yang dikembalikan mengandungi senarai SamplerPubResult, satu bagi setiap PUB. Tong data objek SamplerPubResult ini adalah objek seperti kamus yang mengandungi satu BitArray bagi setiap ClassicalRegister dalam Circuit.
Kelas BitArray adalah kontena untuk data tembakan yang tersusun. Lebih terperinci, ia menyimpan rentetan bit yang disamplkan sebagai bait dalam tatasusunan dua dimensi. Paksi paling kiri tatasusunan ini berjalan melalui tembakan yang tersusun, manakala paksi paling kanan berjalan melalui bait.
Sebagai contoh pertama, mari kita lihat Circuit sepuluh Qubit berikut:
# generate a ten-qubit GHZ circuit
circuit = QuantumCircuit(10)
circuit.h(0)
circuit.cx(range(0, 9), range(1, 10))
# append measurements with the `measure_all` method
circuit.measure_all()
# transpile the circuit
transpiled_circuit = pm.run(circuit)
# run the Sampler job and retrieve the results
sampler = Sampler(mode=backend)
job = sampler.run([transpiled_circuit])
result = job.result()
# the data bin contains one BitArray
data = result[0].data
print(f"Databin: {data}\n")
# to access the BitArray, use the key "meas", which is the default name of
# the classical register when this is added by the `measure_all` method
array = data.meas
print(f"BitArray: {array}\n")
print(f"The shape of register `meas` is {data.meas.array.shape}.\n")
print(f"The bytes in register `alpha`, shot by shot:\n{data.meas.array}\n")
Databin: DataBin(meas=BitArray(<shape=(), num_shots=4096, num_bits=10>))
BitArray: BitArray(<shape=(), num_shots=4096, num_bits=10>)
The shape of register `meas` is (4096, 2).
The bytes in register `alpha`, shot by shot:
[[ 3 254]
[ 0 0]
[ 3 255]
...
[ 0 0]
[ 3 255]
[ 0 0]]
Kadang kala lebih mudah untuk menukar daripada format bait dalam BitArray kepada rentetan bit. Kaedah get_count mengembalikan kamus yang memetakan rentetan bit kepada bilangan kali ia muncul.
# optionally, convert away from the native BitArray format to a dictionary format
counts = data.meas.get_counts()
print(f"Counts: {counts}")
Counts: {'1111111110': 199, '0000000000': 1337, '1111111111': 1052, '1111111000': 33, '1110000000': 65, '1100100000': 2, '1100000000': 25, '0010001110': 1, '0000000011': 30, '1111111011': 58, '1111111010': 25, '0000000110': 7, '0010000001': 11, '0000000001': 179, '1110111110': 6, '1111110000': 33, '1111101111': 49, '1110111111': 40, '0000111010': 2, '0100000000': 35, '0000000010': 51, '0000100000': 31, '0110000000': 7, '0000001111': 22, '1111111100': 24, '1011111110': 5, '0001111111': 58, '0000111111': 24, '1111101110': 10, '0000010001': 5, '0000001001': 2, '0011111111': 38, '0000001000': 11, '1111100000': 34, '0111111111': 45, '0000000100': 18, '0000000101': 2, '1011111111': 11, '1110000001': 13, '1101111000': 1, '0010000000': 52, '0000010000': 17, '0000011111': 15, '1110100001': 1, '0111111110': 9, '0000000111': 19, '1101111111': 15, '1111110111': 17, '0011111110': 5, '0001101110': 1, '0111111011': 6, '0100001000': 2, '0010001111': 1, '1111011000': 1, '0000111110': 4, '0011110010': 1, '1110111100': 2, '1111000000': 8, '1111111101': 27, '0000011110': 6, '0001000000': 5, '1111010000': 3, '0000011011': 4, '0001111110': 9, '1111011110': 6, '1110001111': 2, '0100000001': 7, '1110111011': 3, '1111101101': 2, '1101111110': 5, '1110000010': 7, '0111111000': 1, '1110111000': 1, '0000100001': 2, '1110100000': 6, '1000000001': 2, '0001011111': 1, '0000010111': 1, '1011111100': 1, '0111110000': 5, '0110111111': 2, '0010000010': 1, '0001111100': 4, '0011111001': 2, '1111110011': 1, '1110000011': 5, '0000001011': 8, '0100000010': 3, '1111011111': 13, '0010111000': 2, '0100111110': 1, '1111101000': 2, '1110110000': 2, '1100000001': 1, '0001110000': 3, '1011101111': 2, '1111000001': 2, '1111110001': 8, '1111110110': 4, '1100000010': 3, '0011000000': 2, '1110011111': 3, '0011101111': 3, '0010010000': 2, '0000100010': 1, '1100001110': 1, '0001111011': 4, '1010000000': 3, '0000001110': 5, '0000001010': 2, '0011111011': 4, '0100100000': 2, '1111110100': 1, '1111100011': 3, '0000110110': 1, '0001111101': 2, '1111100001': 2, '1000000000': 5, '0010000011': 3, '0010011111': 3, '0100001111': 1, '0100000111': 1, '1011101110': 1, '0011110111': 1, '1100000111': 1, '1100111111': 3, '0001111010': 1, '1101111011': 1, '0111111100': 2, '0100000110': 2, '0100000011': 2, '0001101111': 3, '0001000001': 1, '1111110010': 1, '0010100000': 1, '0011100000': 4, '1010001111': 1, '0101111111': 2, '1111101001': 1, '1110111101': 1, '0000011101': 1, '1110001000': 2, '0001111001': 1, '0101000000': 1, '1111111001': 5, '0001110111': 2, '0000111001': 1, '0100001011': 1, '0000010011': 1, '1011110111': 1, '0011110001': 1, '0000001100': 2, '0111010111': 1, '0001101011': 1, '1110010000': 2, '1110000100': 1, '0010111111': 3, '0111011100': 1, '1010001000': 1, '0000101110': 1, '0011111100': 2, '0000111100': 2, '1110011110': 1, '0011111000': 2, '0110100000': 1, '1001101111': 1, '1011000000': 1, '1101000000': 1, '1110001011': 1, '1110110111': 1, '0110111110': 1, '0011011111': 1, '0111100000': 1, '0000110111': 1, '0000010010': 2, '1111101100': 2, '1111011101': 1, '1101100000': 1, '0010111110': 1, '1101101110': 1, '1111001111': 1, '1101111100': 1, '1011111010': 1, '0001100000': 1, '1101110111': 1, '1100001011': 1}
Apabila Circuit mengandungi lebih daripada satu daftar klasikal, hasilnya disimpan dalam objek BitArray yang berbeza. Contoh berikut mengubah suai petikan sebelumnya dengan membahagikan daftar klasikal kepada dua daftar yang berbeza:
# generate a ten-qubit GHZ circuit with two classical registers
circuit = QuantumCircuit(
qreg := QuantumRegister(10),
alpha := ClassicalRegister(1, "alpha"),
beta := ClassicalRegister(9, "beta"),
)
circuit.h(0)
circuit.cx(range(0, 9), range(1, 10))
# append measurements with the `measure_all` method
circuit.measure([0], alpha)
circuit.measure(range(1, 10), beta)
# transpile the circuit
transpiled_circuit = pm.run(circuit)
# run the Sampler job and retrieve the results
sampler = Sampler(mode=backend)
job = sampler.run([transpiled_circuit])
result = job.result()
# the data bin contains two BitArrays, one per register, and can be accessed
# as attributes using the registers' names
data = result[0].data
print(f"BitArray for register 'alpha': {data.alpha}")
print(f"BitArray for register 'beta': {data.beta}")
BitArray for register 'alpha': BitArray(<shape=(), num_shots=4096, num_bits=1>)
BitArray for register 'beta': BitArray(<shape=(), num_shots=4096, num_bits=9>)
Memanfaatkan objek BitArray untuk pemprosesan pasca yang berprestasi​
Memandangkan tatasusunan umumnya menawarkan prestasi yang lebih baik berbanding kamus, adalah disyorkan untuk melakukan sebarang pemprosesan pasca terus pada objek BitArray dan bukannya pada kamus kiraan. Kelas BitArray menawarkan pelbagai kaedah untuk melakukan beberapa operasi pemprosesan pasca yang biasa:
print(f"The shape of register `alpha` is {data.alpha.array.shape}.")
print(f"The bytes in register `alpha`, shot by shot:\n{data.alpha.array}\n")
print(f"The shape of register `beta` is {data.beta.array.shape}.")
print(f"The bytes in register `beta`, shot by shot:\n{data.beta.array}\n")
# post-select the bitstrings of `beta` based on having sampled "1" in `alpha`
mask = data.alpha.array == "0b1"
ps_beta = data.beta[mask[:, 0]]
print(f"The shape of `beta` after post-selection is {ps_beta.array.shape}.")
print(f"The bytes in `beta` after post-selection:\n{ps_beta.array}")
# get a slice of `beta` to retrieve the first three bits
beta_sl_bits = data.beta.slice_bits([0, 1, 2])
print(
f"The shape of `beta` after bit-wise slicing is {beta_sl_bits.array.shape}."
)
print(f"The bytes in `beta` after bit-wise slicing:\n{beta_sl_bits.array}\n")
# get a slice of `beta` to retrieve the bytes of the first five shots
beta_sl_shots = data.beta.slice_shots([0, 1, 2, 3, 4])
print(
f"The shape of `beta` after shot-wise slicing is {beta_sl_shots.array.shape}."
)
print(
f"The bytes in `beta` after shot-wise slicing:\n{beta_sl_shots.array}\n"
)
# calculate the expectation value of diagonal operators on `beta`
ops = [SparsePauliOp("ZZZZZZZZZ"), SparsePauliOp("IIIIIIIIZ")]
exp_vals = data.beta.expectation_values(ops)
for o, e in zip(ops, exp_vals):
print(f"Exp. val. for observable `{o}` is: {e}")
# concatenate the bitstrings in `alpha` and `beta` to "merge" the results of the two
# registers
merged_results = BitArray.concatenate_bits([data.alpha, data.beta])
print(f"\nThe shape of the merged results is {merged_results.array.shape}.")
print(f"The bytes of the merged results:\n{merged_results.array}\n")
The shape of register `alpha` is (4096, 1).
The bytes in register `alpha`, shot by shot:
[[1]
[1]
[1]
...
[0]
[0]
[1]]
The shape of register `beta` is (4096, 2).
The bytes in register `beta`, shot by shot:
[[ 0 135]
[ 0 247]
[ 1 247]
...
[ 0 0]
[ 1 224]
[ 1 255]]
The shape of `beta` after post-selection is (0, 2).
The bytes in `beta` after post-selection:
[]
The shape of `beta` after bit-wise slicing is (4096, 1).
The bytes in `beta` after bit-wise slicing:
[[7]
[7]
[7]
...
[0]
[0]
[7]]
The shape of `beta` after shot-wise slicing is (5, 2).
The bytes in `beta` after shot-wise slicing:
[[ 0 135]
[ 0 247]
[ 1 247]
[ 1 128]
[ 1 255]]
Exp. val. for observable `SparsePauliOp(['ZZZZZZZZZ'],
coeffs=[1.+0.j])` is: 0.068359375
Exp. val. for observable `SparsePauliOp(['IIIIIIIIZ'],
coeffs=[1.+0.j])` is: 0.06396484375
The shape of the merged results is (4096, 2).
The bytes of the merged results:
[[ 1 15]
[ 1 239]
[ 3 239]
...
[ 0 0]
[ 3 192]
[ 3 255]]
Metadata hasil​
Selain hasil pelaksanaan, kedua-dua objek PrimitiveResult dan PubResult mengandungi atribut metadata tentang tugas yang diserahkan. Metadata yang mengandungi maklumat untuk semua PUB yang diserahkan (seperti pelbagai pilihan masa jalan yang tersedia) boleh didapati dalam PrimitiveResult.metatada, manakala metadata khusus bagi setiap PUB terdapat dalam PubResult.metadata.
Dalam medan metadata, pelaksanaan primitif boleh mengembalikan sebarang maklumat tentang pelaksanaan yang berkaitan dengannya, dan tiada pasangan nilai-kunci yang dijamin oleh primitif asas. Oleh itu, metadata yang dikembalikan mungkin berbeza dalam pelaksanaan primitif yang berbeza.
# 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:
'execution' : {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-01-15 08:07:33', stop='2026-01-15 08:07:36', size=4096>)])},
'version' : 2,
The metadata of the PubResult result is:
'circuit_metadata' : {},
Untuk tugas Sampler, anda juga boleh menyemak metadata hasil untuk memahami bila data tertentu dijalankan; ini dipanggil rentang pelaksanaan.