qarp¶
OpenQARP — quantum algorithm research platform.
Cross-cutting names only: config, EXACT / Shots, the result types
and post-selection. Public depth: every subpackage is a namespace
(absorb, algorithms, blocks, cutting, devices, emit,
engines, factories, graphs, operators, optimizers,
plotting, resources, utils), plus two modules — errors (the
exception surface, imported qualified: qarp.errors.CapabilityError) and
endianness (the MSB-boundary conversions, §1 of the conventions). None
of them is imported here, so import qarp stays thin; from qarp import *
pulls them all.
- class qarp.Consumes(*values)[source]¶
Bases:
EnumWhat raw engine output a primitive’s estimator consumes.
Declared class-level on each primitive; engines dispatch on it. Lives here, below both layers, so engines can read it without importing from
qarp.algorithms.- Variables:
COUNTS – Measurement statistics from sampled circuits (protocol primitives: Sampler, HadamardTest, PauliAveraging, …).
AMPLITUDES – Simulator statevectors, contracted directly (StateVector). Requires an engine with amplitude access — noiseless simulation.
- AMPLITUDES = 1¶
- COUNTS = 0¶
- class qarp.ExactResult(n_qubits: int, keys: ndarray, probs: ndarray, n_shots: int = 1)[source]¶
Bases:
objectExact Born distribution duck-typing
qx.SamplingResult.keys(sorted int64 outcome bitmasks) andprobscarry the distribution, pruned below ~1e-12 so it sums to 1 − O(pruned) — compare distributions at ~1e-10, never exactly.countsis the same data as a dict, built on first access: estimators that can consume the arrays (outcome_arrays()) never pay for a 2^n-entry dict.n_shots = 1is a normalization trick so every estimator’scount / n_shotsyields the probability unchanged — it is NOT a statistical claim: never infer shot-noise error bars or adaptive shot budgets from it (the variance of these numbers is exactly 0). Checkis_exactto discriminate from a sampled result.- keys: ndarray¶
- probs: ndarray¶
- class qarp.MPIConfig[source]¶
Bases:
objectMPI launcher detection — nothing more.
OpenQARP does not implement MPI parallelism: a composite algorithm constructed under a multi-rank launcher raises
CapabilityErrorrather than running the same serial work on every rank. Detection is environment-only so nompi4pyimport (and noMPI_Init_thread) ever happens inside OpenQARP.Set QARP_DISABLE_MPI=1 to silence the detection (e.g. one rank of a job that drives OpenQARP serially on purpose).
- class qarp.PostSelected(distribution: SamplingDistribution, success_rate: float)[source]¶
Bases:
objectConditioned distribution plus the probability mass that survived.
- distribution: SamplingDistribution¶
- class qarp.PostSelection(conditions: Mapping[int, int])[source]¶
Bases:
objectImmutable post-selection condition on a subset of qubits.
Construct with a
{qubit index: required bit}mapping for fixed-bit conditions, or via the sector constructorshamming_weight()/parity(). Hashable: fixed-bit specs compare by their conditions, sector specs by predicate identity — either way a spec can key a cache across a parameter sweep.- apply(distribution: Mapping[tuple[int, ...], float]) PostSelected[source]¶
Condition a distribution keyed by LSB-first bit tuples.
Keys must share one width covering every selected qubit. Fixed-bit specs drop the (now-constant) selected positions from the output keys; sector specs keep full-width keys. Zero surviving mass yields an empty distribution and a success rate of 0 — no raise, so parameter sweeps survive nodes with vanishing support.
- apply_statevector(statevector, n_qubits: int) Tuple[ndarray, float][source]¶
Project a statevector onto the condition; renormalise.
Returns
(conditional_state, success_probability)withsuccess = ‖P|ψ⟩‖². Fixed-bit specs return the state of the surviving qubits (ascending order,2^(n-k)amplitudes — the selected qubits collapsed to a product basis state and factor out). Sector specs return the projected state on the FULL register (2^n): a subspace projection leaves the selected qubits entangled with the rest, so no reduction exists. Zero success returns the zero vector of the appropriate size withp = 0.0.
- classmethod hamming_weight(qubits: Sequence[int], k: int) PostSelection[source]¶
Keep outcomes with exactly
kones acrossqubits(particle-number sector under Jordan-Wigner).
- property is_fixed: bool¶
True for fixed-bit conditions (selected qubits are removed from the output); False for sector conditions (full width preserved).
- class qarp.SamplingDistribution(outcomes, probabilities, n_bits_measured: int, *, n_shots: int | None = None)[source]¶
Bases:
Mapping[tuple[int, …],float]Read-only sampling distribution over LSB-first bit tuples.
Reads like a
{bits-tuple: probability}dict, iterating in ascending order of the packed integer.outcomesandprobabilitiesgive the same data as aligned read-only arrays;probability_of(k)looks one up by its packed integer;to_dict()makes a plain dict, faster thandict(d), which looks each key up again. Positions passed to the analysis methods index the key tuple, not physical qubits.- Parameters:
outcomes – Packed integers
Σ_i b_i · 2**iof the keys, strictly ascending, each below2**n_bits_measured.probabilities – One probability per outcome.
n_bits_measured – Bits per key — the number of measured qubits.
n_shots – Shots behind a sampled distribution;
Nonefor an exact one. Equality and iteration ignore it.
- classmethod from_dict(mapping: Mapping, *, n_bits_measured: int | None = None, n_shots: int | None = None) SamplingDistribution[source]¶
A distribution from a
{bits-tuple: probability}mapping.Keys must be 0/1 tuples of one width.
n_bits_measuredgives the width of an empty mapping and must match the keys otherwise. ASamplingDistributioncomes back as it is unlessn_shotsis given.
- hellinger_fidelity(other: Mapping) float[source]¶
(Σ √(p q))², qiskit’s definition, probabilities as given.
- marginal(positions) SamplingDistribution[source]¶
The distribution over
positions: bitiof a new key is key positionpositions[i]. Keepsn_shots.
- most_likely() tuple[tuple[int, ...], float][source]¶
The most probable
(bits, probability); the smaller packed outcome wins a tie.ValueErrorwhen empty.
- property outcomes: ndarray¶
Packed keys
Σ_i b_i · 2**i, strictly ascending, read-only.
- parity_expectation(positions) float[source]¶
Σ p · (−1)^(parity of the bits at positions): the expectation of the product ofZoverpositions, probabilities as given. Emptypositionsgive the total probability.
- probability_of(outcome: int) float[source]¶
Probability of the outcome whose packed integer is
outcome.outcomeisΣ_i b_i · 2**iof the key tuple; an outcome that never occurred has probability 0.0. RaisesValueErroroutside[0, 2**n_bits_measured).
- sample(n_shots: int, seed: int | Generator | None = None) SamplingDistribution[source]¶
A multinomial draw of
n_shotsfrom the probabilities renormalised to sum to 1 (exact results prune below 1e-12). Outcomes drawn zero times are dropped.
- standard_errors() ndarray[source]¶
Binomial standard error
sqrt(p(1 - p) / n_shots)per outcome; zeros for an exact distribution, whose values carry no shot noise.
- to_dense(max_bits: int = 28) ndarray[source]¶
The length
2**n_bits_measuredprobability vector, indexed by packed outcome.ValueErrorpastmax_bits, which bounds the allocation (2**28doubles are 2 GiB).
- to_dict() dict[tuple[int, ...], float][source]¶
A plain
{bits-tuple: probability}dict, in the same order.
- top(k: int) list[tuple[tuple[int, ...], float]][source]¶
The
kmost probable(bits, probability)pairs, most probable first; ties go to the smaller packed outcome.
- class qarp.Shots(*values)[source]¶
Bases:
EnumNon-integer shot-count sentinels for the
n_shotsknob.Shots.EXACT(re-exported asqarp.EXACT) requests the ∞-shot limit of a sampling primitive: the engine computes the exact Born distribution |ψ|² instead of drawing samples. Deliberately a plainEnum, neverIntEnum: arithmetic or ordering on a leaked sentinel must fail loudly withTypeError, not compute garbage. Enum members survivedeepcopywith identity intact (copy.n_shots is EXACTkeeps working through the QSE/MonteCarlo/QMEGS deepcopy paths — a plainobject()sentinel would not).- EXACT = 'exact'¶
- qarp.EXACT = Shots.EXACT¶
Non-integer shot-count sentinels for the
n_shotsknob.Shots.EXACT(re-exported asqarp.EXACT) requests the ∞-shot limit of a sampling primitive: the engine computes the exact Born distribution |ψ|² instead of drawing samples. Deliberately a plainEnum, neverIntEnum: arithmetic or ordering on a leaked sentinel must fail loudly withTypeError, not compute garbage. Enum members survivedeepcopywith identity intact (copy.n_shots is EXACTkeeps working through the QSE/MonteCarlo/QMEGS deepcopy paths — a plainobject()sentinel would not).
- qarp.SamplingDictionary¶
A Mapping is a generic container for associating key/value pairs.
This class provides concrete generic implementations of all methods except for __getitem__, __iter__, and __len__.
- class qarp.SamplingDistribution(outcomes, probabilities, n_bits_measured: int, *, n_shots: int | None = None)[source]¶
Read-only sampling distribution over LSB-first bit tuples.
Reads like a
{bits-tuple: probability}dict, iterating in ascending order of the packed integer.outcomesandprobabilitiesgive the same data as aligned read-only arrays;probability_of(k)looks one up by its packed integer;to_dict()makes a plain dict, faster thandict(d), which looks each key up again. Positions passed to the analysis methods index the key tuple, not physical qubits.- Parameters:
outcomes – Packed integers
Σ_i b_i · 2**iof the keys, strictly ascending, each below2**n_bits_measured.probabilities – One probability per outcome.
n_bits_measured – Bits per key — the number of measured qubits.
n_shots – Shots behind a sampled distribution;
Nonefor an exact one. Equality and iteration ignore it.
- classmethod from_dict(mapping: Mapping, *, n_bits_measured: int | None = None, n_shots: int | None = None) SamplingDistribution[source]¶
A distribution from a
{bits-tuple: probability}mapping.Keys must be 0/1 tuples of one width.
n_bits_measuredgives the width of an empty mapping and must match the keys otherwise. ASamplingDistributioncomes back as it is unlessn_shotsis given.
- hellinger_fidelity(other: Mapping) float[source]¶
(Σ √(p q))², qiskit’s definition, probabilities as given.
- marginal(positions) SamplingDistribution[source]¶
The distribution over
positions: bitiof a new key is key positionpositions[i]. Keepsn_shots.
- most_likely() tuple[tuple[int, ...], float][source]¶
The most probable
(bits, probability); the smaller packed outcome wins a tie.ValueErrorwhen empty.
- property outcomes: ndarray¶
Packed keys
Σ_i b_i · 2**i, strictly ascending, read-only.
- parity_expectation(positions) float[source]¶
Σ p · (−1)^(parity of the bits at positions): the expectation of the product ofZoverpositions, probabilities as given. Emptypositionsgive the total probability.
- probability_of(outcome: int) float[source]¶
Probability of the outcome whose packed integer is
outcome.outcomeisΣ_i b_i · 2**iof the key tuple; an outcome that never occurred has probability 0.0. RaisesValueErroroutside[0, 2**n_bits_measured).
- sample(n_shots: int, seed: int | Generator | None = None) SamplingDistribution[source]¶
A multinomial draw of
n_shotsfrom the probabilities renormalised to sum to 1 (exact results prune below 1e-12). Outcomes drawn zero times are dropped.
- standard_errors() ndarray[source]¶
Binomial standard error
sqrt(p(1 - p) / n_shots)per outcome; zeros for an exact distribution, whose values carry no shot noise.
- to_dense(max_bits: int = 28) ndarray[source]¶
The length
2**n_bits_measuredprobability vector, indexed by packed outcome.ValueErrorpastmax_bits, which bounds the allocation (2**28doubles are 2 GiB).
- to_dict() dict[tuple[int, ...], float][source]¶
A plain
{bits-tuple: probability}dict, in the same order.
- qarp.config = <qarp._config.__ConfigObject__ object>¶