דוגמאות Estimator
Package versions
הקוד בעמוד זה פותח באמצעות הדרישות הבאות. אנחנו ממליצים להשתמש בגרסאות אלה או חדשות יותר.
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
הדוגמאות בחלק זה ממחישות כמה דרכים נפוצות להשתמש ב-Estimator. לפני הרצת הדוגמאות הללו, בצעו את ההוראות בהתקנת Qiskit.
כל הדוגמאות הללו משתמשות ב-primitives של IBM Quantum, אך ניתן להשתמש ב-primitives הבסיסיים במקום זאת.
חשב ופרש ערכי ציפייה של אופרטורים קוונטיים הנדרשים לאלגוריתמים רבים בצורה יעילה עם Estimator. חקור שימושים במידול מולקולרי, למידת מכונה ובעיות אופטימיזציה מורכבות.
הרצת ניסוי בודד
השתמש ב-Estimator כדי לקבוע את ערך הציפייה של זוג מעגל-observable בודד.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
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}")
> Expectation value: 0.012658227848101266
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
הרצת ניסויים מרובים בעבודה בודדת
השתמש ב-Estimator כדי לקבוע את ערכי הציפייה של זוגות מרובים של מעגל-observable.
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}")
>>> Expectation values for PUB 0: -0.2650103519668737
>>> Standard errors for PUB 0: 0.49439861538856356
>>> Expectation values for PUB 1: -0.02099609375
>>> Standard errors for PUB 1: 0.013489459956524228
>>> Expectation values for PUB 2: 0.2788671023965142
>>> Standard errors for PUB 2: 0.4836236522960098
הרצת מעגלים פרמטריים
השתמש ב-Estimator להרצת שלושה ניסויים בעבודה בודדת, ממנף ערכי פרמטרים כדי להגדיל את שימוש חוזר במעגלים.
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 IBM Quantum 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}")
>>> Expectation values: [[ 0.9665404 0.90476418 0.77027221 0.53367788 0.27327396 -0.04118414
-0.32496864 -0.5686415 -0.78657426 -0.91870673 -0.95667336 -0.91656172
-0.78249875 -0.55877446 -0.2855005 0.0278851 0.31638861 0.58322755
0.78829027 0.92428375 0.96267938]
[ 0.01930507 0.31831912 0.5969556 0.80630833 0.92535625 0.96525339
0.91312971 0.7689852 0.55062343 0.27992348 -0.01158304 -0.30287506
-0.57679253 -0.80158932 -0.90562218 -0.96246488 -0.90669469 -0.77606373
-0.55641496 -0.29193553 0.01630206]
[-0.04719017 -0.35950326 -0.63599473 -0.84427497 -0.9669694 -1.00193302
-0.93565229 -0.77992474 -0.53861139 -0.25782991 0.05898771 0.34834922
0.62998871 0.83655294 0.95817487 1.00021701 0.93307828 0.77606373
0.54547542 0.26662444 -0.06670973]
[ 0.9969995 0.93543779 0.76426619 0.55963247 0.24967888 -0.06241972
-0.35221024 -0.63620924 -0.83440793 -0.96568239 -1.00536503 -0.93415078
-0.77949574 -0.56284998 -0.26855494 0.05362519 0.35070873 0.61797667
0.84212996 0.97104491 0.99850101]]
>>> Standard errors: [[0.00518482 0.00616652 0.00723301 0.01064988 0.01139583 0.01174119
0.01301757 0.01155567 0.00848267 0.00690879 0.00492396 0.00613768
0.00678488 0.00840832 0.01404782 0.01184222 0.00982484 0.00854968
0.00764619 0.00774419 0.00621175]
[0.01590044 0.01095813 0.01205478 0.00872719 0.00609088 0.0043678
0.00579195 0.00857024 0.01184119 0.01191681 0.01262258 0.01090978
0.01346398 0.00940893 0.00709353 0.00454548 0.00795003 0.00900232
0.00768466 0.01225787 0.01271092]
[0.01265687 0.01230849 0.00961079 0.00725756 0.00469446 0.00444008
0.00683132 0.00804195 0.01140408 0.01165563 0.01001761 0.01300941
0.01014068 0.00822676 0.00511424 0.00465829 0.00659315 0.00633185
0.00865837 0.0101667 0.01090357]
[0.00399857 0.0064308 0.0071202 0.00974728 0.01066452 0.01082351
0.01311009 0.01053503 0.00801145 0.00501261 0.00499458 0.00673144
0.00871285 0.00998373 0.01241673 0.01345925 0.00835253 0.00686725
0.00814337 0.00466632 0.00432618]]
>>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
שימוש ב-batches ואפשרויות מתקדמות
חקור את מצב ההרצה batch ואפשרויות מתקדמות לאופטימיזציה של ביצועי מעגלים על 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}")
> Expectation value: 0.026385707741639945
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
> Another Expectation value: 0.0134052163776774
> More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
השלבים הבאים
- ציין אפשרויות runtime מתקדמות.
- תרגל עם primitives באמצעות עבודה על שיעור פונקציית עלות בלימוד IBM Quantum®.
- למד כיצד לבצע transpile מקומית בחלק Transpile.
- נסה את מדריך השוואת הגדרות Transpiler.
- הבן את מגבלות העבודה בעת שליחת עבודה ל-IBM® QPU.