Skip to content
Back to skills

709 Primitives 6fea9e6a

ASecurity

Primitives are the fundamental building blocks for executing quantum circuits. Qiskit provides two main primitives: **Sampler** (for measuring bitstrings) and **Estimator** (for computing expectation values).

  • 9 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added October 11, 2026
developmentpythongoapibackendperformance

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 709-primitives_6fea9e6a --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 709 Primitives 6fea9e6a?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 709 Primitives 6fea9e6a
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-709-primitives-6fea9e6a/badge)](https://www.skillsdirectory.com/skills/tools-only-709-primitives-6fea9e6a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Qiskit Primitives

Primitives are the fundamental building blocks for executing quantum circuits. Qiskit provides two main primitives: **Sampler** (for measuring bitstrings) and **Estimator** (for computing expectation values).

## Primitive Types

### Sampler
Calculates probabilities or quasi-probabilities of bitstrings from quantum circuits. Use when you need:
- Measurement outcomes
- Output probability distributions
- Sampling from quantum states

### Estimator
Computes expectation values of observables for quantum circuits. Use when you need:
- Energy calculations
- Observable measurements
- Variational algorithm optimization

## V2 Interface (Current Standard)

Qiskit uses V2 primitives (BaseSamplerV2, BaseEstimatorV2) as the current standard. V1 primitives are legacy.

## Sampler Primitive

### StatevectorSampler (Local Simulation)

```python
from qiskit import QuantumCircuit
from qiskit.primitives import StatevectorSampler

# Create circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

# Run with Sampler
sampler = StatevectorSampler()
result = sampler.run([qc], shots=1024).result()

# Access results
counts = result[0].data.meas.get_counts()
print(counts)  # e.g., {'00': 523, '11': 501}
```

### Multiple Circuits

```python
qc1 = QuantumCircuit(2)
qc1.h(0)
qc1.measure_all()

qc2 = QuantumCircuit(2)
qc2.x(0)
qc2.measure_all()

# Run multiple circuits
sampler = StatevectorSampler()
job = sampler.run([qc1, qc2], shots=1000)
results = job.result()

# Access individual results
counts1 = results[0].data.meas.get_counts()
counts2 = results[1].data.meas.get_counts()
```

### Using Parameters

```python
from qiskit.circuit import Parameter

theta = Parameter('θ')
qc = QuantumCircuit(1)
qc.ry(theta, 0)
qc.measure_all()

# Run with parameter values
sampler = StatevectorSampler()
param_values = [[0], [np.pi/4], [np.pi/2]]
result = sampler.run([(qc, param_values)], shots=1024).result()
```

## Estimator Primitive

### StatevectorEstimator (Local Simulation)

```python
from qiskit import QuantumCircuit
from qiskit.primitives import StatevectorEstimator
from qiskit.quantum_info import SparsePauliOp

# Create circuit WITHOUT measurements
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

# Define observable
observable = SparsePauliOp(["ZZ", "XX"])

# Run Estimator
estimator = StatevectorEstimator()
result = estimator.run([(qc, observable)]).result()

# Access expectation values
exp_value = result[0].data.evs
print(f"Expectation value: {exp_value}")
```

### Multiple Observables

```python
from qiskit.quantum_info import SparsePauliOp

qc = QuantumCircuit(2)
qc.h(0)

obs1 = SparsePauliOp(["ZZ"])
obs2 = SparsePauliOp(["XX"])

estimator = StatevectorEstimator()
result = estimator.run([(qc, obs1), (qc, obs2)]).result()

ev1 = result[0].data.evs
ev2 = result[1].data.evs
```

### Parameterized Estimator

```python
from qiskit.circuit import Parameter
import numpy as np

theta = Parameter('θ')
qc = QuantumCircuit(1)
qc.ry(theta, 0)

observable = SparsePauliOp(["Z"])

# Run with multiple parameter values
estimator = StatevectorEstimator()
param_values = [[0], [np.pi/4], [np.pi/2], [np.pi]]
result = estimator.run([(qc, observable, param_values)]).result()
```

## IBM Quantum Runtime Primitives

For running on real hardware, use runtime primitives:

### Runtime Sampler

```python
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

service = QiskitRuntimeService()
backend = service.backend("ibm_brisbane")

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

# Run on real hardware
sampler = Sampler(backend)
job = sampler.run([qc], shots=1024)
result = job.result()
counts = result[0].data.meas.get_counts()
```

### Runtime Estimator

```python
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit.quantum_info import SparsePauliOp

service = QiskitRuntimeService()
backend = service.backend("ibm_brisbane")

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

observable = SparsePauliOp(["ZZ"])

# Run on real hardware
estimator = Estimator(backend)
job = estimator.run([(qc, observable)])
result = job.result()
exp_value = result[0].data.evs
```

## Sessions for Iterative Workloads

Sessions group multiple jobs to reduce queue wait times:

```python
from qiskit_ibm_runtime import Session

service = QiskitRuntimeService()
backend = service.backend("ibm_brisbane")

with Session(backend=backend) as session:
    sampler = Sampler(session=session)

    # Run multiple jobs in session
    job1 = sampler.run([qc1], shots=1024)
    result1 = job1.result()

    job2 = sampler.run([qc2], shots=1024)
    result2 = job2.result()
```

## Batch Mode for Parallel Jobs

Batch mode runs independent jobs in parallel:

```python
from qiskit_ibm_runtime import Batch

service = QiskitRuntimeService()
backend = service.backend("ibm_brisbane")

with Batch(backend=backend) as batch:
    sampler = Sampler(session=batch)

    # Submit multiple independent jobs
    job1 = sampler.run([qc1], shots=1024)
    job2 = sampler.run([qc2], shots=1024)

    # Retrieve results when ready
    result1 = job1.result()
    result2 = job2.result()
```

## Result Processing

### Sampler Results

```python
result = sampler.run([qc], shots=1024).result()

# Get counts
counts = result[0].data.meas.get_counts()

# Get probabilities
probs = {k: v/1024 for k, v in counts.items()}

# Get metadata
metadata = result[0].metadata
```

### Estimator Results

```python
result = estimator.run([(qc, observable)]).result()

# Expectation value
exp_val = result[0].data.evs

# Standard deviation (if available)
std_dev = result[0].data.stds

# Metadata
metadata = result[0].metadata
```

## Differences from V1 Primitives

**V2 Improvements:**
- More flexible parameter binding
- Better result structure
- Improved performance
- Cleaner API design

**Migration from V1:**
- Use `StatevectorSampler` instead of `Sampler`
- Use `StatevectorEstimator` instead of `Estimator`
- Result access changed from `.result().quasi_dists[0]` to `.result()[0].data.meas.get_counts()`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.