Backends¶
qufin uses a pluggable backend system. All quantum algorithms accept a Backend object, allowing you to switch between simulators and real hardware with a single line change.
Available Backends¶
| Backend | Module | Use Case |
|---|---|---|
MockBackend |
qufin.backends.mock |
Unit testing, deterministic |
QiskitAerBackend |
qufin.backends.qiskit_backend |
Local simulation |
NoisyAerBackend |
qufin.backends.noise_models |
Noise-aware simulation |
IBMRuntimeBackend |
qufin.backends.ibm_runtime |
IBM Quantum hardware |
Quick Usage¶
from qufin.backends.qiskit_backend import QiskitAerBackend
backend = QiskitAerBackend(seed=42)
result = backend.run(circuit, shots=4096)
print(result.counts) # {'00': 2048, '11': 2048}
print(result.most_frequent) # '00'
print(result.probabilities) # {'00': 0.5, '11': 0.5}
Noise Models¶
Simulate realistic hardware noise:
from qufin.backends.noise_models import NoisyAerBackend, IBM_HERON_R2, NOISY_NEAR_TERM
# Use a device-calibrated noise profile
backend = NoisyAerBackend(profile=IBM_HERON_R2, seed=42)
# Or use a generic noisy profile
backend = NoisyAerBackend(profile=NOISY_NEAR_TERM)
Device Profiles¶
| Profile | 1Q Error | 2Q Error | Readout Error | T1 (us) |
|---|---|---|---|---|
IDEAL |
0 | 0 | 0 | inf |
IBM_EAGLE_R3 |
2.4e-4 | 7.5e-3 | 1.1e-2 | 290 |
IBM_HERON_R2 |
1.5e-4 | 3.5e-3 | 6e-3 | 350 |
NOISY_NEAR_TERM |
1e-3 | 1e-2 | 3e-2 | 50 |
Custom Noise Profile¶
from qufin.backends.noise_models import NoiseProfile, NoisyAerBackend
profile = NoiseProfile(
single_gate_error=5e-4,
two_gate_error=5e-3,
readout_error=1e-2,
t1_us=200.0,
t2_us=100.0,
name="my_device",
)
backend = NoisyAerBackend(profile=profile)
Noise Sweep¶
Analyze algorithm sensitivity to noise:
from qufin.backends.noise_models import sweep_noise
results = sweep_noise(
circuit,
error_rates=[0, 0.001, 0.005, 0.01, 0.05],
shots=4096,
)
for r in results:
print(f"Error rate: {r['error_rate']}, Entropy: {r['entropy']:.2f}")
Error Mitigation¶
Zero-Noise Extrapolation (ZNE)¶
from qufin.backends.error_mitigation import zne_extrapolate
mitigated = zne_extrapolate(
circuit, backend,
scale_factors=[1, 3, 5],
shots=8192,
)
print(f"Mitigated counts: {mitigated.mitigated_counts}")
Readout Error Mitigation¶
from qufin.backends.error_mitigation import calibrate_readout, mitigate_readout
# Calibrate (run 2^n basis states)
cal_matrix = calibrate_readout(backend, n_qubits=4, shots=8192)
# Apply correction
corrected = mitigate_readout(raw_counts, cal_matrix)
TREX (Twirled Readout Error eXtinction)¶
from qufin.backends.error_mitigation import trex_mitigate
result = trex_mitigate(circuit, backend, shots=8192, n_randomizations=10)
Backend Interface¶
All backends implement:
class Backend:
def run(self, circuit, shots=1024) -> CircuitResult: ...
def statevector(self, circuit) -> NDArray: ...
def backend_id(self) -> str: ...
def is_simulator(self) -> bool: ...
CircuitResult provides:
.counts— Dict of bitstring -> count.probabilities— Dict of bitstring -> probability.most_frequent— Most common bitstring.shots— Total number of shots.backend_id— Backend identifier
Advanced Backend Features (v0.3.0)¶
Auto-Selecting a Backend¶
The auto_select_backend function analyzes your circuit and picks the best
available backend based on qubit count, gate depth, and installed packages.
from qufin.backends.auto_select import auto_select_backend
backend = auto_select_backend(circuit)
result = backend.run(circuit, shots=4096)
Using the Finance Transpiler to Optimize QAOA Circuits¶
FinanceTranspiler exploits the structure of financial QUBO problems to
produce better qubit layouts and commuting-gate groupings.
from qufin.backends.transpiler import FinanceTranspiler
transpiler = FinanceTranspiler()
result = transpiler.transpile(circuit, qubo_matrix=Q)
print(f"Depth reduction: {result.original_depth} -> {result.transpiled_depth}")
optimized_circuit = result.circuit
Applying Dynamical Decoupling¶
Insert DD sequences into idle periods to suppress decoherence on real hardware.
from qufin.backends.dynamical_decoupling import insert_dd_sequences, DDConfig
config = DDConfig(sequence_type="XY4", t2_us=100.0)
protected_circuit = insert_dd_sequences(circuit, config)
Using M3 Measurement Mitigation¶
M3 (Matrix-free Measurement Mitigation) scales to large qubit counts by using tensored calibration instead of full calibration matrices.
from qufin.backends.m3_mitigation import M3Mitigator, M3Config
mitigator = M3Mitigator(backend, config=M3Config(shots=8192))
mitigator.calibrate(qubits=[0, 1, 2, 3])
corrected_counts = mitigator.apply(raw_counts)
Noise-Aware Optimization¶
Incorporate estimated noise channels directly into the optimizer cost function so the variational loop learns to avoid noisy gates.
from qufin.backends.noise_aware_optimizer import NoiseAwareOptimizer, NoiseAwareConfig
config = NoiseAwareConfig(noise_weight=0.1, max_iterations=200)
optimizer = NoiseAwareOptimizer(backend, config)
opt_result = optimizer.minimize(cost_fn, initial_params)
Cost Estimation for Cloud QPU¶
Estimate the dollar cost of running a circuit on Amazon Braket or IonQ before submitting the job.