Sampler & Estimator¶
The Qiskit plugin provides OQSampler (SamplerV2) and OQEstimator (EstimatorV2) primitives that submit circuits to Open Quantum for execution.
OQSampler (SamplerV2)¶
OQSampler implements Qiskit's BaseSamplerV2 interface. It submits circuits to Open Quantum and returns measurement results as BitArray objects.
Creating a Sampler¶
Use service.create_sampler():
from openquantum_sdk.auth import ClientCredentials
from openquantum_sdk_qiskit import OpenQuantumService
service = OpenQuantumService(
creds=ClientCredentials(
client_id="s_your_client_id",
client_secret="your_client_secret",
),
)
backend = service.return_backend("ionq:forte-1")
sampler = service.create_sampler(
backend=backend,
job_subcategory_id="phys:oth", # Physics
)
Running the Sampler¶
from qiskit.circuit import QuantumCircuit
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
job = sampler.run([qc], shots=1024)
result = job.result()
# Access the first pub result
pub_result = result[0]
bit_array = pub_result.data.meas
counts = bit_array.get_counts()
print(counts)
Expected output:
Shots Configuration¶
Specify shots per run:
If shots is not specified, it defaults to 100.
Parameter Binding¶
The sampler supports parameterized circuits with automatic binding:
from qiskit.circuit import QuantumCircuit, Parameter
theta = Parameter("theta")
qc = QuantumCircuit(1, 1)
qc.rx(theta, 0)
qc.measure(0, 0)
# Single parameter value
job = sampler.run([(qc, [0.5])], shots=1024)
# Multiple parameter values
import numpy as np
values = np.linspace(0, np.pi, 5)
job = sampler.run([(qc, values.reshape(-1, 1))], shots=1024)
Export Format¶
Control the QASM export format:
# Use OpenQASM 2 instead of the default OpenQASM 3
job = sampler.run([qc], shots=1024, export_format="qasm2")
OQEstimator (EstimatorV2)¶
OQEstimator implements Qiskit's BaseEstimatorV2 interface. It computes expectation values of observables by delegating to Qiskit's BackendEstimatorV2 with an Open Quantum backend.
Creating an Estimator¶
Running the Estimator¶
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
observable = SparsePauliOp("ZZ")
job = estimator.run([(qc, observable)], precision=0.01)
result = job.result()
print(f"Expectation value: {result[0].data.evs}")
Precision¶
The precision parameter controls the target precision for the expectation value estimate:
# Higher precision (more shots internally)
job = estimator.run([(qc, observable)], precision=0.001)
# Lower precision (fewer shots, faster)
job = estimator.run([(qc, observable)], precision=0.1)
Multiple Observables¶
obs_zz = SparsePauliOp("ZZ")
obs_xx = SparsePauliOp("XX")
job = estimator.run([
(qc, obs_zz),
(qc, obs_xx),
])
result = job.result()
print(f"<ZZ> = {result[0].data.evs}")
print(f"<XX> = {result[1].data.evs}")
Direct Construction¶
You can also construct the primitives directly without service.create_sampler() or service.create_estimator():
from openquantum_sdk_qiskit import OQSampler, OQEstimator
sampler = OQSampler(
backend=backend,
scheduler=service.scheduler,
config={
"backend_class_id": "ionq:forte-1",
"job_subcategory_id": "phys:oth", # Physics
},
export_format="qasm3",
)
estimator = OQEstimator(
backend=backend,
scheduler=service.scheduler,
config={
"backend_class_id": "ionq:forte-1",
"job_subcategory_id": "phys:oth", # Physics
},
export_format="qasm3",
)
Related Pages¶
- Getting Started -- Install and first circuit.
- Backends & Targets -- Backend capabilities.
- Examples -- Complete Qiskit workflows.