qarp.algorithms¶
Algorithms. Public depth: flat — every primitive and composite algorithm is
qarp.algorithms.<Name>, together with the eigenspectrum helpers.
Submodules are private implementation and may be reorganised without notice.
- class qarp.algorithms.AdaptVQD(reference_block: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, hamiltonian: QubitOperator, excitation_pool: List[QubitOperator], orthogonal_states: Sequence[Block], betas: List[float], gradient: bool | str = False, optimizer: Optimizer | None = None, diminishing: bool = False, exc_per_iter: int = 1, verbose: bool = True, term_gradient: str = 'ADAPT-VQD', convergence_thresh=1e-07, gradient_thresh=1e-07, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
AdaptAnsatzMixin,CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block() SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
Use the current object reference, ansatz excitations and symbols to construct a wavefunction object.
- Returns:
A wavefunction object constructed with the current AdaptVQE attributes.
- class qarp.algorithms.AdaptVQE(reference_block: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, system_hamiltonian: QubitOperator, excitation_pool: List[QubitOperator], optimizer: Optimizer | None = None, gradient: bool | str = False, verbose: bool = True, diminishing: bool = False, exc_per_iter: int = 1, qubit_adapt: bool = False, gradient_thresh: float = 1e-05, convergence_thresh: float = 1e-06, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
AdaptAnsatzMixin,CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block() SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
Use the current object reference, ansatz excitations and symbols to construct a wavefunction object.
- Returns:
A wavefunction object constructed with the current AdaptVQE attributes.
- class qarp.algorithms.AmplitudeAmplification(state_preparation: Block, oracle: Block, n_iterations: int, *, good_states: Sequence[int] | None = None, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmPrepare a state and apply a fixed number of amplification iterates.
The built circuit is
Afollowed byn_iterationsapplications ofAmplitudeAmplificationBlock. The suppliedoraclemust implement exactlyI - 2 Pi_good; see the block documentation for the phase convention.good_statesis optional classical reporting metadata. It contains full-register integer labels and is used only to sum the returned sampling probabilities. It neither defines nor modifies the quantum oracle.The iterate and the probability law
sin((2 * n_iterations + 1) * theta)**2follow Brassard, Hoyer, Mosca, and Tapp, Quantum Amplitude Amplification and Estimation, arXiv:quant-ph/0005055, Eqs. (1), (5), and (8).- Parameters:
state_preparation – Unitary
Apreparing the initial state.oracle – Good-state phase oracle on the same positive-width register.
n_iterations – Explicit non-negative number of amplification iterates.
good_states – Optional unique full-register integer labels whose returned probabilities are summed into
success_probability.primitive – Sampling primitive. Defaults to a private
Sampler. A sampler carryinginitial_stateis rejected: the amplification law assumes the circuit starts in|0...0>, soAmust act on that state and not on a seeded one.engine – Execution engine. Defaults to
QarpEnginethrough the composite-algorithm base class.
- class qarp.algorithms.AmplitudeEstimation(state_preparation: Block, oracle: Block, n_ancilla: int, *, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmEstimate the initial good-state probability with canonical QAE.
The supplied oracle must implement exactly
I - 2 Pi_good. WithM = 2**n_ancilla, a sampled QPE labelymaps tosin(pi*y/M)**2. The conjugate phase branches are folded together atz = min(y, M-y)before selecting the most probable estimate.This is the canonical estimator of Brassard, Hoyer, Mosca, and Tapp, arXiv:quant-ph/0005055.
- Parameters:
state_preparation – Unitary preparing the state whose amplitude is estimated.
oracle – Phase-exact good-state oracle on the same register.
n_ancilla – Positive number of estimation qubits.
primitive – Sampling primitive. Defaults to a private
Sampler.engine – Execution engine.
- class qarp.algorithms.BasisRotationAveraging(ket: Block | None = None, integrals: tuple | None = None, constant: float = 0.0, tolerance: float = 1e-08, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- class qarp.algorithms.CompositeAlgorithm(primitive: PrimitiveAlgorithm, engine: Engine | None = None)[source]¶
Bases:
ABC
- class qarp.algorithms.CuttingPrimitive(ket: Block | None = None, operator: QubitOperator | None = None, max_subcircuit_qubits: int | None = None, n_shots: int = 5000, force_max_number_cuts: bool = False, experiment_fraction: float | None = None, rng_seed: int | None = None)[source]¶
Bases:
PrimitiveAlgorithmPrimitiveAlgorithm that evaluates expectation values via QPD circuit cutting.
Works with any OpenQARP engine without modification.
- circuits() list[source]¶
Partition the circuit and build all measurement sub-blocks.
The cut reads the ket’s gate stream, so the ket is built here, one of two primitives (with
PauliShadow) whose circuits cannot be derived from an unbuilt input. Uses streaming experiment generation and QWC grouping so that the circuits number n_experiments × n_subcircuits × n_qwc_groups (instead of × n_obs_terms).
- class qarp.algorithms.DOSQPE(unitary: Block, n_ancilla: int, hamming_weight: int | None = None, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the DOS Phase Estimation circuit through the engine.
DOSQPEBlockdeclares its controlled-U ladder (structure()), so an engine that plans declarations (§14 Structured execution) never builds the ladder andblockstays unbuilt; any other engine builds and compiles it.- Returns:
The instance of the class.
- Return type:
self
- property freqs¶
Get the frequency grid for the ancilla register.
- plot(figsize=None, return_fig=False, max_xticks=11)[source]¶
Plot the results of the DOS Phase Estimation algorithm.
- plot_against_spectrum(unique_eigs, normalized_degeneracy, unique_occ_numbers, figsize=None, return_fig=False, max_xticks=11)[source]¶
Plot the results of the DOS Phase Estimation algorithm against the spectrum.
- Parameters:
unique_eigs (list) – Unique eigenvalues.
normalized_degeneracy (list) – Normalized degeneracy.
unique_occ_numbers (list) – Unique occupation numbers.
figsize (tuple) – Size of the figure. If None, scales with n_ancilla.
return_fig (bool) – If True, return (fig, ax) for external saving/customization.
max_xticks (int) – Upper bound on the number of x-axis ticks.
- Returns:
(fig, ax) if return_fig is True, otherwise None.
- class qarp.algorithms.GroupedTransitionHadamardTest(bra: Block | None = None, operator: QubitOperator | None = None, ket: Block | None = None, real: bool = True, imaginary: bool = True, n_shots: int | Shots | None = None, grouping: GroupingStrategy | None = None)[source]¶
Bases:
PrimitiveAlgorithmEstimate a full-operator transition amplitude by QWC grouping.
The circuit for a group samples the correlation between the ancilla quadrature and every Pauli parity in that group. The primitive returns
<bra|H|ket>directly; it does not expose or run one sub-primitive per Pauli term.- Parameters:
bra – State-preparation block for
<bra|.operator – Real-coefficient
QubitOperatorto measure.ket – State-preparation block for
|ket>.real – Include real-quadrature circuits.
imaginary – Include imaginary-quadrature circuits.
n_shots – Shots per group/quadrature;
Nonedefers to the engine.grouping – Term grouping strategy. The initial circuit primitive supports strategies with
qubit_wise=True; default isQubitWiseCommuting.
General (non-QWC) commuting groups require an entangling diagonalisation and are intentionally rejected until a transition-aware Clifford path is added. This keeps the first implementation exact and easy to validate.
- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) float | complex[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.Grover(oracle: Block, n_marked: int = 1, *, good_states: Sequence[int] | None = None, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmSearch a uniform basis-state space with a known marked-state count.
good_statesis optional reporting metadata. It is never used to build or modify the oracle; when supplied, its returned probability mass is exposed assuccess_probability. It is not cross-checked against the oracle (an opaque unitary cannot be inspected without an exponential dense matrix), so declaring labels the oracle does not actually mark yields a misleadingsuccess_probability— the labels are the caller’s promise.most_likely_statesis only meaningful once amplification has concentrated the distribution. When the optimal iteration count is zero (n_marked >= N/2, so the uniform state is already at or past the amplification optimum) the distribution stays (near-)uniform andmost_likely_statesis the entire register; readpredicted_success_probabilityto see that no concentration occurred.The algorithm follows Grover, arXiv:quant-ph/9605043, with the known-count analysis of Boyer, Brassard, Hoyer, and Tapp, arXiv:quant-ph/9605034.
- Parameters:
oracle – Phase oracle implementing exactly
I - 2 Pi_good.n_marked – Number of basis states marked by the oracle.
good_states – Optional explicit marked integer labels for reporting only.
primitive – Sampling primitive. Defaults to a private
Sampler.engine – Execution engine.
- class qarp.algorithms.HadamardTest(bra: Block | None = None, operator: Block | None = None, ket: Block | None = None, real: bool = True, imaginary: bool = True, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) complex[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.InterferometricTest(bra: ComputationalBasisStateBlock | None = None, operator: Block | None = None, ket: ComputationalBasisStateBlock | None = None, real: bool = True, imaginary: bool = True, sampling_algorithm: PrimitiveAlgorithm | None = None, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) complex[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.MMQCELS(operator: QubitOperator | ndarray | TrotterBlock, state: ndarray | Block, *, execution_mode: Literal['classical', 'statevector', 'hadamard'], T0: float, parameter_mode: Literal['standard', 'error_rate'] = 'standard', N0: int | None = None, Nj: int | Sequence[int] | None = None, n_dominant_eigenvalues: int = 1, error_rate: float = 0.001, n_levels: int | None = None, q: float | None = None, gamma: float = 1.0, initial_eigenvalues: Sequence[float] | None = None, n_initial_guesses: int = 10, n_shots: int | Shots | None = None, lam_min: float = -3.141592653589793, lam_max: float = 3.141592653589793, optimizer: Optimizer | None = None, seed: int | None = None, verbose: bool = True, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmEstimate several dominant eigenvalues with MM-QCELS.
The implementation follows Algorithm 2 and Eq. (13) of Ding and Lin, Quantum 7, 1136 (2023): times are independent truncated-Gaussian draws, observations are complex, and the time scale doubles between levels.
parameter_mode="standard"is the recommended default. It requiresT0,N0,Nj, and exactly one ofqorn_levels.parameter_mode="error_rate"retains OpenQARP’s historical epsilon-derived level and sample-count helpers as an explicitly opt-in convenience. It is not a theorem-backed MM-QCELS parameter calibration.- Parameters:
operator – Hamiltonian in classical mode, or a symbolic-time
TrotterBlockin circuit modes.state – Statevector/block in classical mode, or a built block in circuit modes.
execution_mode – Required data-generation strategy:
"classical","statevector", or"hadamard".T0 – Positive initial Gaussian time scale.
parameter_mode –
"standard"or the opt-in"error_rate"compatibility preset.N0 – Number of samples at level zero. Required in standard mode.
Nj – Positive sample count reused after level zero, or one count per subsequent level. Required in standard mode, even though a scalar value is unused when
n_levels=1.n_dominant_eigenvalues – Number of dominant modes
K.error_rate – Accuracy
epsilonused byparameter_mode="error_rate"and by standard mode’sqschedule. It does not affect a standard schedule with an explicitn_levels.n_levels – Explicit number of evaluated levels. Mutually exclusive with
qin standard mode.q – Theorem-1 schedule parameter. Standard mode derives
l=max(ceil(log2(q/(epsilon*T0))), 1)and evaluatesl+1levels.gamma – Truncation radius in standard deviations. Sampled times lie in
[-gamma*T_j, gamma*T_j].initial_eigenvalues – Optional length-
Kfirst-level phase guess.n_initial_guesses – Total number of first-level optimization starts, including
initial_eigenvalueswhen supplied.n_shots – Hadamard shots per quadrature.
Nonemeans one shot, as in the paper;qarp.EXACTevaluates the exact protocol.lam_min – Initial lower eigenvalue bound.
lam_max – Initial upper eigenvalue bound.
optimizer – SciPy-compatible bounded optimizer.
seed – Seed for time sampling and generated optimizer starts. When no engine is supplied, it also seeds the default QarpEngine.
verbose – Print per-level progress.
engine – Optional configured execution engine.
- Variables:
result – Eigenvalues returned by the latest successful
run().eigenvalues – Alias of
result, following the QPE output style.amplitudes – Complex amplitudes fitted alongside the eigenvalues.
level_losses – Final complex least-squares loss at every level.
sample_counts – Number of observations used at every level.
sampled_max_times – Largest absolute sampled time at every level.
sampled_total_times – Sum of absolute sampled times at every level.
optimizer_failed_starts – Number of discarded optimizer starts at every level. A level for which every start fails raises instead.
Every evaluated level must contain more observations than dominant modes; otherwise the variable-projection residual cannot identify the frequencies.
- generate_dataset(T: float, n: int | None = None) list[tuple[float, complex]][source]¶
Generate one independent MM-QCELS dataset at scale
T.
- generate_times(T: float, n: int) NDArray[float64][source]¶
Draw
nindependent samples from Eq. (3)’s distribution.
- objective(eigenvalues: ArrayLike, dataset: Sequence[tuple[float, complex]]) float[source]¶
Evaluate the full complex Eq. (13) loss after eliminating amplitudes.
- optimal_dataset_length() int[source]¶
Return OpenQARP’s historical epsilon-only sample-count heuristic.
- optimal_number_of_iterations() int[source]¶
Return the predecessor-QCELS epsilon-only level heuristic.
- class qarp.algorithms.MirrorTest(bra: Block | None = None, operator: Block | None = None, ket: Block | None = None, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- class qarp.algorithms.MonteCarlo(hamiltonian: QubitOperator | ndarray, approx_ground_state_energy: float | List[float], total_time: float, time_step: float, reference_walker_label: int | List[int], unitary_block: Block, num_target_states: int = 1, initial_walker_count: int | List[int] = 200, walker_basis: List[WalkerState] | None = None, shift_damping: float | List[float] = 0.1, population_threshold: int = 350, mode: str = 'Semiclassical', primitive: PrimitiveAlgorithm | None = None, n_shots: int = 1000, num_trajectories: int = 10, ham_cache: Dict[Tuple[int, int], Tuple[complex, float]] | None = None, save_walker_history: bool = False, history_save_interval: int = 1, qdrift: bool = False, qdrift_samples: int = 100, qdrift_ratio: float | None = None, verbose: bool = False, engine: Engine | None = None, seed: int | None = None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the simulator by setting up walker states and caches.
- Returns:
Self for method chaining
- estimate_ground_state_energy(walkers_by_label: Dict[str, List[WalkerState]], initial_energy: float, visited_states: Set[int]) float[source]¶
Calculate energy using pre-grouped walkers (semiclassical mode).
- estimate_ground_state_energy_quantum(walkers: List[WalkerState], initial_energy: float, visited_states: Set[int]) float[source]¶
Calculate ground state energy from walker list (quantum mode).
- prepare_vector_and_projector(walkers) Tuple[ndarray, ndarray][source]¶
From list of walkers, return vector in walker basis and projector of that vector
- project_for_orthogonalization(current_excitation, projectors) Tuple[List[WalkerState], float][source]¶
Apply projectors onto current ES walker vector to ensure orthogonalisation with lower energy states
- remove_opposite_sign_pairs(walkers: List[WalkerState]) List[WalkerState][source]¶
Remove walkers with opposite signs in the same state (annihilation).
- Parameters:
walkers – List of walker states
- Returns:
Walkers after annihilation
- class qarp.algorithms.PCE(graph: Graph, order: int, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, merging: bool = False, classical_function: Callable = <function classical_function_max_cut>, quantum_function: Callable = <function quantum_function_max_cut>, initial_parameters: Iterable[float] | None = None, optimizer: Optimizer | None = None, verbose: bool = True, gradient: bool | str = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the PCE object with UCC ansatz
If not all attributes are set, some defaults are loaded. These are: - COBYLA as optimizer - No gradients used - StateVector for all measurement strategies - QarpEngine() for all backends
- Returns:
self
- get_final_state_block() SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
The ket bound at the optimal parameters (set by
run()).
- get_gradient_function()[source]¶
Builds a gradient function as an option for certain optimizers to minimize
- Returns:
The gradient function assisting the optimizer
- class qarp.algorithms.PauliAveraging(bra: Block | None = None, operator: QubitOperator | None = None, ket: Block | None = None, n_shots: int | Shots | None = None, grouping: GroupingStrategy | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) float[source]¶
Per-group expectation, weighted sum, plus the constant term.
After the group’s diagonalising Clifford, term
iequalss_i · Z^{mask_i}(s_i = ±1), so from the measurement counts:E[term_i] = s_i · (1/n_shots) Σ_outcome counts[outcome] · (-1)^popcount(outcome & mask_i)
⟨H⟩ = constant + Σ_groups Σ_terms c_i · E[term_i].
- class qarp.algorithms.PauliKernel(n_qubits: int)[source]¶
Bases:
ShadowKernelRandom-Pauli (local-Clifford) inverse channel.
A setting is one axis per qubit (
0/1/2=X/Y/Z). The inverse channel factorizes per qubit: for a Pauli termPa snapshot contributesprod_{q in supp(P)} 3 * (-1)^{b_q}iff the measured axis on every qubit ofsupp(P)matchesP’s axis there, and0otherwise.
- class qarp.algorithms.PauliShadow(operator: str | QubitOperator, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock | None = None, *, dataset: ShadowDataset | None = None, n_settings: int = 1000, n_shots: int = 1, seed: int | None = None)[source]¶
Bases:
ShadowProtocolRandom-Pauli classical shadows (Huang–Kueng–Preskill, 2020).
- class qarp.algorithms.PrimitiveAlgorithm(ket: Any = None, bra: Any = None, operator: Any = None, n_shots: int | Shots | None = None, target: Target = Target.SAMPLING)[source]¶
Bases:
ABCPure Python base class for qarpx-backed primitive algorithms.
Uses the C++ kernel (qarpx) for compilation and simulation. All algorithm logic — circuit construction and result post-processing — lives in Python, keeping the boundary simple.
Subclasses must implement:
circuits()— the circuits to run, as block trees over the inputs as given; the engine plans a declared structure before building (§14) and builds only what planning refusesrun(results)— post-process the engine’s per-circuit results (qx.SamplingResult, or ExactResult under n_shots=qarp.EXACT) → scalar
- Variables:
sub_blocks – Set by build() from circuits(); block trees, built by the engine where planning refuses.
compiled – Set by Engine.build(); one
CompiledCircuitper circuit.compiled_circuits – Each circuit’s command list, read from
compiled; empty for one lowered from a declaration._n_qubits_list – Each circuit’s simulator width, read from
compiled.
Class capability metadata (override on the subclass; class-level so it survives the
deepcopy-then-mutate pattern QSE/MonteCarlo/QMEGS use):supported_targets: TheTargetvalues this primitive can estimate.consumes:Consumes.COUNTS— estimator reads sampled measurement statistics (the default);Consumes.AMPLITUDES— estimator contracts simulator statevectors directly, and engines dispatch torun_from_amplitudes(compiled_circuits)instead of sampling.supports_exact:Trueiff the protocol has a meaningful ∞-shot limit. Consulted only for COUNTS consumers (an AMPLITUDES primitive is always exact);Falsefor inherently stochastic protocols (CuttingPrimitive).supports_backprop_gradient:Trueiff the primitive is eligible for the engine’s adjoint backprop gradient path (Engine.run_gradient). DefaultFalse— sampling primitives use the parameter-shift fallback instead.gradient_kind: what a shift rule may assume aboutrun()as a function of each compiled circuit’s state, separately:"expectation"(bilinear — every sampled estimator),"amplitude"(linear or antilinear in one circuit’s amplitudes),"squared_overlap"(run()returns ⟨bra|ket⟩, the gradient is of |·|²), or"none"(non-linear, e.g. a median-of-means or a ratio: parameter shift refuses, finite differences still apply). Default"none"— a new primitive loses speed, never correctness, until it declares its class.requires_noiseless:Trueiff the estimator’s post-processing is only valid under ideal (noiseless) measurement. Enforced inEngine._validate_primitive: a primitive with this flag is rejected on an engine whose noise model is active. DefaultFalse(noise is fine).PauliShadowsets it — the shadow inverse channel assumes ideal readout, so a noisy campaign fed through it is silently biased.returns_probability:Trueiff anOVERLAPestimator’srun()already returns|⟨bra|ket⟩|²rather than the amplitude⟨bra|ket⟩. Consumers that need the squared overlap (VQD/ADAPT-VQD deflation) must not square such a value again. DefaultFalse(amplitude-returning).
- build() PrimitiveAlgorithm[source]¶
Derive the circuits into
sub_blockswithout building a block.Returns
selfso callers can chainprimitive.build().
- abstractmethod circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- infer_target() Target[source]¶
Detect which quantity to compute from the
{ket, bra, operator}inputs.Single source of truth for input-driven target detection, shared by the primitives that vary their operation with their inputs (
HadamardTest,StateVector). Sets and returnsself.target, and defaultsbratoketfor the expectation-value case. Fixed-purpose primitives (Sampler,SWAPTest,MirrorTest, …) pass an explicittargetto__init__and never call this.- Rules:
ketonly →SAMPLINGket+operator→EXPECTATION_VALUE(bra≔ket)bra≠ket+operator→TRANSITION_AMPLITUDEbra≠ket, no operator →OVERLAP
The
bra ≔ ketdefault is live: whilebrahas never been explicitly assigned, every call re-derives it from the current{ket, operator}, so rebinding onlyket(e.g. on a deepcopy) keeps an EXPECTATION_VALUE primitive an expectation value. Any explicit assignment takes ownership;bra = Nonehands it back.- Raises:
RuntimeError – if
ketis missing, orbrawas explicitly set to the same object asketwith no operator (a degenerate ⟨ψ|ψ⟩ request).
- abstractmethod run(results: list) float | complex | SamplingDistribution[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- run_from_amplitudes(compiled_circuits: list, simulator=None) float | complex[source]¶
Evaluate the target directly from simulator amplitudes.
Only called by engines when
self.consumesisConsumes.AMPLITUDES. Default raises — sampling primitives don’t override this.- Parameters:
compiled_circuits – One command stream per
sub_blocksentry, already parameter-substituted.simulator – Optional statevector backend (anything implementing
statevector(commands, n_qubits)). Engines pass their own simulator so amplitude primitives run on the same backend — e.g.CudaqEnginepasses its GPUqx.CudaqSimulator. Defaults to a CPUqx.QarpSimulatorwhen None.
- class qarp.algorithms.ProjectedVQE(operator: QubitOperator, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, projector: Block | Sequence[Block] | None = None, projector_matrix: ndarray | None = None, initial_parameters: Sequence[float] | NDArray[float64] | None = None, optimizer: Optimizer | None = None, verbose: bool = False, engine: Engine | None = None, postselection_tol: float = 1e-14, save_energy_history: bool = False)[source]¶
Bases:
VQEVariation-after-projection VQE using a fast StateVector objective.
- Parameters:
operator – Hamiltonian as a qarp
QubitOperatoron the system register, with no ancilla shift.ket – Parameterized ansatz block on the system register.
projector – One symmetry-projector block, or a sequence of them (applied as a product). Known projector blocks are converted to dense system-register projector matrices and are not simulated as circuits during optimization.
projector_matrix – Dense projector matrix in qarpx LSB ordering, for custom projectors. Mutually exclusive with
projector.postselection_tol – Squared-norm threshold below which the projected state counts as annihilated; the objective returns
+infthere.
- class qarp.algorithms.QAOA(problem: Graph | QubitOperator, n_layers: int = 1, use_rzz: bool = True, initial_parameters: Sequence[float] | NDArray[float64] | None = None, gradient: bool | str = False, optimizer: Optimizer | None = None, verbose: bool = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None, save_energy_history: bool = False)[source]¶
Bases:
VQA
- class qarp.algorithms.QITE(hamiltonian: QubitOperator, initial_block: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, dtau: float, n_steps: int, *, pool: List[QubitOperator] | None = None, regularization: float = 1e-06, trotter_steps: int = 1, trotter_order: int = 2, engine: Engine | None = None, verbose: bool = False)[source]¶
Bases:
CompositeAlgorithm- build() QITE[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block() SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
The accumulated
initial_block ∘ layer₁ ∘ … ∘ layerₙ(afterrun).
- class qarp.algorithms.QMEGS(unitary: TrotterBlock | SynthesizedTimeEvolutionBlock, state: Block, n_shots: int | Shots | None, target_indices: List[int], sigma: float = 1.0, eta: float = 0.01, T: int = 100, filtering_function: Callable | None = None, mode_dataset: Literal['analytical', 'sampling'] = 'analytical', mode_time: Literal['rvs', 'rejection_sampling'] = 'rvs', overlaps: Literal['classical'] | Tuple[float, float] = 'classical', verbose: bool = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmQuantum Multiple Eigenvalue Gaussian filtered Search (QMEGS) algorithm.
Implementation based on arxiv2402.01013. This algorithm finds multiple eigenphases of a unitary operator using Hadamard tests with Gaussian filtered time sampling.
- Parameters:
unitary – Block representing the time-evolution unitary.
state – Block representing the trial state.
n_shots – Number of measurement shots — same meaning in both modes: an int adds shot noise (synthetic in “analytical” mode, sampled in “sampling” mode with a sampling primitive);
qarp.EXACTmeans no shot noise;Nonemeans the default shot count (10_000 / engine default). The default exact primitive ignores it in “sampling” mode.target_indices – List of indices of target eigenvalues to find (Dset in the paper).
sigma – Truncation level for time sampling.
eta – Error tolerance for the algorithm.
T – Time window for time sampling.
filtering_function – Custom filtering function for time sampling. Defaults to truncated_gaussian_density.
mode_dataset – Dataset generation mode. - “analytical”: Generate data using classical simulation (faster, for testing). - “sampling”: Generate data using actual sampling execution.
mode_time – Time sampling mode. - “rvs”: Use scipy’s truncnorm.rvs for fast sampling. - “rejection_sampling”: Use rejection sampling (enables arbitrary filtering functions).
overlaps –
Where the algorithm’s a-priori inputs
p_min/p_tail(Theorem 1 of arXiv:2402.01013) come from. -"classical"(default):build()dense-diagonalises theHamiltonian (O(4^n)) and reads the trial statevector through the engine’s simulator — a validation harness, refused on a noisy or routed engine. Required by
mode_dataset="analytical".(pmin, ptail): the two overlaps supplied by the user; no diagonalisation, no statevector. Onlylen(target_indices)is consulted (the number of eigenvalues to extract) — the index values themselves are not used.
verbose – Whether to print progress information.
primitive – Primitive used to evaluate ⟨ψ|U(t)|ψ⟩ in “sampling” mode. Defaults to
StateVector()— exact, noise-free amplitudes. PassHadamardTest()for finite-shot protocol realism.engine – Quantum engine for circuit execution.
- build()[source]¶
Build the algorithm by computing necessary parameters.
Calculates overlaps, probabilities, and algorithm parameters based on the input unitary and trial state.
- Returns:
Self for method chaining.
- Raises:
ValueError – If the algorithm’s assumptions are not satisfied (pmin must be greater than ptail).
- filtered_density_function(dataset: List[tuple], theta_js: ndarray, n_samples: int) ndarray[source]¶
Compute the filtered density function G_j for given theta values.
- Parameters:
dataset – List of (time, measurement) tuples from quantum measurements.
theta_js – Array of theta values to evaluate.
n_samples – Number of samples for normalization.
- Returns:
filtered density values for each theta.
- Return type:
G_js
- generate_data() List[tuple][source]¶
Generate the measurement dataset according to selected mode.
- Returns:
List of (time, measurement) tuples.
- run() List[float][source]¶
Run the QMEGS algorithm to find eigenphases.
Follows Algorithm 2 in arxiv2402.01013.
- Returns:
List of found eigenphases.
- validate_inputs()[source]¶
Validate input parameters for correctness.
- Raises:
ValueError – If any input parameter is invalid.
- class qarp.algorithms.QPE(state: Block, unitary: Block, n_ancilla: int, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the Canonical Phase Estimation circuit through the engine.
QPEBlockdeclares its controlled-U ladder (structure()), so an engine that plans declarations (§14 Structured execution) never builds the ladder andblockstays unbuilt; any other engine builds and compiles it.- Returns:
The instance of the class.
- Return type:
self
- estimate_phase(fit_range=None, verbose=False)[source]¶
Estimation of the phase done by fitting the Dirichlet kernel squared to the distribution obtained from the run.
- class qarp.algorithms.QSE(hamiltonian: QubitOperator | Block, ground_state: Block, primitive: PrimitiveAlgorithm, overlap_primitive: PrimitiveAlgorithm, excitation_operators: List[QubitOperator], engine: Engine | None = None, real_symmetric: bool = False, verbose: bool = False)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- compute_hamiltonian()[source]¶
Constructs the Hamiltonian matrix H in HC = SCe from the primitives.
Note
It is assumed that the QSE Hamiltonian is symmetric or Hermitian.
- Returns:
A numpy array representing the Hamiltonian matrix H.
- compute_overlap()[source]¶
Constructs the overlap matrix S from the primitives.
Note
Assumes that the QSE overlap matrix is real valued and symmetric or Hermitian.
- Returns:
A numpy array representing the overlap matrix S.
- property hamiltonian_primitives: List[PrimitiveAlgorithm]¶
- property overlap_primitives: List[PrimitiveAlgorithm]¶
- class qarp.algorithms.SSVQE(operator: QubitOperator | Block, basis_state_blocks: Sequence[Block], ansatz_block: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, weights: List[float], initial_parameters: Mapping | Sequence[float] | NDArray[float64] | None = None, optimizer: Optimizer | None = None, verbose: bool = True, gradient: bool | str = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block(index: int) SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
Built block for optimized state
index: basis state + ansatz bound at the optimal parameters. No symbol handling required — evaluate ⟨N⟩, ⟨S²⟩, etc. directly on the returned block.
- class qarp.algorithms.SWAPTest(bra: Block | None = None, operator: Block | None = None, ket: Block | None = None, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- class qarp.algorithms.Sampler(ket: Block | None = None, n_shots: int | Shots | None = None, measured_qubits: list[int] | None = None, initial_state=None)[source]¶
Bases:
PrimitiveAlgorithmqarpx-backed sampling primitive.
- Parameters:
ket – Block to execute.
n_shots – Number of measurement shots (default: use engine default).
qarp.EXACTreturns the exact Born distribution|ψ|²— note: probabilities, not amplitudes (phases are discarded; raw amplitudes are simulator internals,sim.statevector).measured_qubits – Qubit indices whose outcomes appear in the output tuple. Defaults to
range(ket.n_qubits). Non-measured qubits are marginalised out by summing probabilities over their bit values.initial_state – Optional LSB-indexed amplitudes seeding the register instead of
|0…0⟩(length2**n_qubits, unit norm within1e-10—ValueErrorat run otherwise). QarpEngine only; other engines raiseCapabilityErrorat build. Mutable between runs for step → snapshot → re-seed loops.
- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) SamplingDistribution[source]¶
Marginal of the first result (
qx.SamplingResult, or the duck-typedExactResultundern_shots=qarp.EXACT) onmeasured_qubits.
- class qarp.algorithms.ShadowDataset(kernel: ShadowKernel, n_qubits: int, records: list[tuple[ndarray, dict[int, float]]], shot_exact: bool = False)[source]¶
Bases:
objectA collected campaign: settings + outcomes + the ensemble kernel.
- estimator()[source]¶
Return a
ShadowEstimatorover this dataset.
- classmethod from_dict(d: dict) ShadowDataset[source]¶
- merge(other: ShadowDataset) ShadowDataset[source]¶
Concatenate two compatible campaigns (same ensemble,
n_qubits,shot_exact). Batching is round-robin by setting index, so the merged batches stay evenly mixed between the two campaigns.
- class qarp.algorithms.ShadowEstimate(value: float, error: float, delta: float, n_batches: int, ensemble_only: bool)[source]¶
Bases:
NamedTupleOne estimate with the HKP Theorem-1 accuracy half-width.
erroris theeps = sqrt(34 * V_hat / N)of arXiv:2002.08953 Theorem 1 (V_hatthe empirical single-setting variance,Nthe per-batch size) — the half-width for whichPr[|value - true| >= error] <= deltaat thedeltathat fixedn_batches. That promise holds for the true variancesigma^2;V_hatis a plug-in for it, so the reported bar inherits whatever error that estimate carries (and HKP’s own Remark that the constant 34 is a loose worst case).
- class qarp.algorithms.ShadowEstimator(dataset)[source]¶
Bases:
objectEstimate observables from a collected
ShadowDataset.- expval(observable: str | QubitOperator, *, delta: float = 0.05, n_batches: int | None = None) ShadowEstimate[source]¶
Median-of-means estimate of
<observable>(sum-inside for a multi-term operator).
- expval_many(observables: Sequence[str | QubitOperator], *, delta: float = 0.05, n_batches: int | None = None, marginal: bool = False) list[ShadowEstimate][source]¶
Estimate a family of observables from the one dataset.
By default this is exactly Theorem 1 of HKP applied to the family: the batch count uses the union bound
K = ~2 ln(2M/delta)over theMsupplied, so eacherroris the half-width for which allMestimates lie within their band jointly with probability at least1 - delta.marginal=Trueopts out to a per-observabledelta(K = ~2 ln(2/delta), no union correction).Looping
expval()yourself does not give the joint guarantee — use this method for a family. And choosing observables after seeing results from the same dataset voids it: collect fresh or split.An explicit
n_batchesoverrides the derived count for every estimate (power-user knob; it then defeats the union bound this method exists to apply, so the joint guarantee no longer holds atdelta).
- class qarp.algorithms.ShadowKernel(n_qubits: int)[source]¶
Bases:
ABCStateless inversion kernel for one measurement ensemble.
- Variables:
ensemble (str) – registry tag used by
ShadowDataset.from_dict().n_qubits – register width the kernel was built for.
capabilities (frozenset[str]) – estimator features this ensemble supports (e.g.
{"expval"}; matchgate would add"rdm"). The estimator raisesCapabilityErrorfor anything outside this set.
- classmethod from_params(n_qubits: int, params: dict) ShadowKernel[source]¶
- class qarp.algorithms.ShadowProtocol(operator: str | QubitOperator, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock | None = None, *, dataset: ShadowDataset | None = None, n_settings: int = 1000, n_shots: int = 1, seed: int | None = None)[source]¶
Bases:
PrimitiveAlgorithmBase collector for a randomized-measurement shadow ensemble.
- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- property dataset: ShadowDataset¶
The collected (or passed)
ShadowDataset. Raises if neither a dataset was passed nor a campaign collected yet.
- release() None[source]¶
Free the compiled circuits in place (the detached dataset stays valid).
run()never does this automatically — the engine reuses the compiled circuits underrebuild=Falseand acrossbatch_runparameter sets. Afterrelease(), a re-run needs a rebuild.
- run(results: list) float[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.Shor(number: int, *, base: int | None = None, n_counting_qubits: int | None = None, max_attempts: int = 8, base_seed: int | None = None, force_quantum: bool = False, primitive: Sampler | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithmExact small-integer/reference implementation of Shor factoring.
This implementation uses an exponentially synthesized basis permutation for modular arithmetic and supports at most
ModularMultiplicationBlock.MAX_REFERENCE_WORK_QUBITSwork qubits (number <= 64for the shipped value of six). It establishes a correct reference workflow for small examples; it does not claim cryptographic-scale performance or an asymptotic quantum speedup.build()prepares the order-finding samplers andrun()produces the factor pair, classical shortcuts included.run()executes the batch once; a repeated call returns the stored outcome,Noneincluded, so a finite-shot retry is a new instance. Bases are processed in attempt order, as in Shor’s sequential algorithm: every coprime base gets an order-finding circuit, and the first non-coprime base ends the attempt list withgcd(base, number)as a classical fallback thatrun()returns only if every quantum attempt was inconclusive. Even and perfect-power inputs are factored classically without any circuit.- Parameters:
number – Composite integer greater than one to factor.
base – Optional first modular-order-finding base. Must satisfy
1 < base < number. A non-coprime base is a valid classical gcd shortcut unlessforce_quantumis set.n_counting_qubits – Counting-register width. Defaults to twice the work width and must be at least that large.
max_attempts – Maximum number of distinct bases to try.
base_seed – Seed for the algorithm-local base-selection RNG.
force_quantum – Guarantee the quantum path. Disables the gcd shortcut (random bases are drawn coprime; a supplied non-coprime base is rejected) and rejects even or perfect-power inputs, which lie outside the preconditions of Shor’s order-finding theorem: for
N = 2pand oddN = p**kevery even order givesa**(r/2) == -1 (mod N), so no base can succeed.primitive – Sampling primitive. A private deep copy is used, and Shor owns its
ketandmeasured_qubits(the counting register); the caller’s sampler contributes shot settings only.engine – Execution engine. Defaults to
QarpEngine.
- class qarp.algorithms.StateVector(bra: Block | None = None, operator: QubitOperator | Block | None = None, ket: Block | None = None, initial_state: ndarray | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits: [ket] (or [bra, ket] for overlap-type), unbuilt.
Re-disambiguates
self.targetfrom the currentbra/operator/ketattributes so callers (VQA-family composites) that mutate the primitive after construction get the right target without having to re-instantiate.
- run(results: list) complex | float[source]¶
Convenience entry point: evaluate the build-time compiled circuits.
Engines dispatch directly to
run_from_amplitudes()(becauseconsumesisConsumes.AMPLITUDES), so this method exists mainly for callers driving the primitive without an engine. Symbolic parameters must be substituted intoself.compiled_circuitsbefore calling.
- run_from_amplitudes(compiled_circuits: list, simulator=None) complex | float[source]¶
Simulate the substituted commands and contract the statevectors.
- Parameters:
compiled_circuits – One command stream per entry in
self.sub_blocks, already parameter-substituted by the engine (or by the caller).simulator – Optional statevector backend implementing
statevector(commands, n_qubits). Defaults to a CPUqx.QarpSimulator;CudaqEngineinjects its GPU simulator so the statevectors are computed on-device. A simulator that also providestransition(bra, ket, n_qubits, observable)(QarpSimulatordoes) contracts the operator in C++; otherwise the numpy sweeppauli_expectation()is used.
- class qarp.algorithms.Target(*values)[source]¶
Bases:
EnumThe quantity a primitive computes.
Lives here, below both layers, so engines can dispatch on it without importing from
qarp.algorithms;qarp.algorithms.Targetis this class.- Variables:
SAMPLING – The measurement distribution of the circuit, keyed by LSB-first bit tuples.
EXPECTATION_VALUE –
⟨ket|operator|ket⟩.OVERLAP –
⟨bra|ket⟩.TRANSITION_AMPLITUDE –
⟨bra|operator|ket⟩.
- EXPECTATION_VALUE = 1¶
- OVERLAP = 2¶
- SAMPLING = 0¶
- TRANSITION_AMPLITUDE = 3¶
- class qarp.algorithms.TermwiseHadamardTest(bra: Block | None = None, operator: Block | Sequence[Block] | QubitOperator | None = None, ket: Block | None = None, coefficients: List[float] | None = None, real: bool = True, imaginary: bool = True, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- get_hadamard_test(index: int) HadamardTest[source]¶
- run(results: list) complex[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.TermwiseSWAPTest(bra: Block | Sequence[Block], ket: Block | None = None, coefficients: List[float] | None = None, n_shots: int | Shots | None = None)[source]¶
Bases:
PrimitiveAlgorithm- circuits() list[source]¶
The circuits this primitive runs, as block trees over its inputs as given. Nothing is built here: a block handed in unbuilt stays unbuilt until the engine, which plans a declared structure first (§14 Structured execution) and builds only what planning refuses.
- run(results: list) float[source]¶
Post-process the engine’s sampling output into a result.
Contract: a pure function of
results— no simulator or engine access. Keeps every estimator unit-testable with synthetic results (anything exposingcounts/n_shots/n_qubits).- Parameters:
results – One
qx.SamplingResultper entry inself.sub_blocks, as produced by the engine’s sampler.- Returns:
A scalar (float / complex) for expectation/overlap-style primitives, or a
SamplingDistributionforSampler.
- class qarp.algorithms.VFF(operator: QubitOperator | Block, ansatz_block: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, use_trotter: bool = False, t_time: float = 1.0, t_steps: int = 1, t_order: int = 1, initial_parameters: Sequence[float] | NDArray[float64] | None = None, optimizer: Optimizer | None = None, verbose: bool = True, primitive: PrimitiveAlgorithm | None = None, engine=None)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- property optimal_parameters¶
Optimized parameters keyed by symbol — the order-proof surface.
- class qarp.algorithms.VQA(operator: QubitOperator | Block, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, name: str, initial_parameters: Mapping | Sequence[float] | NDArray[float64] | None = None, gradient: bool | str = False, optimizer: Optimizer | None = None, verbose: bool = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None, save_energy_history: bool = False)[source]¶
Bases:
CompositeAlgorithm- build()[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block() SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
The ket bound at the optimal parameters (set by
run()).
- class qarp.algorithms.VQD(operator: QubitOperator | Block, kets: Sequence[SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock], weights: List[float], initial_parameters: Iterable[Iterable[float]] | None = None, verbose: bool = False, gradient: bool | str = False, optimizer: Optimizer | None = None, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
CompositeAlgorithm- build() Self[source]¶
Build the composite algorithm by constructing all sub-algorithms.
This method should: 1. Create and configure all necessary sub-algorithms 2. Build each sub-algorithm
- Returns:
Self for method chaining
- get_final_state_block(index: int) SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock[source]¶
Ket
indexbound at its optimal parameters.
- class qarp.algorithms.VQE(operator: QubitOperator | Block, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, initial_parameters: Sequence[float] | NDArray[float64] | None = None, gradient: bool | str = False, optimizer: Optimizer | None = None, verbose: bool = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None, save_energy_history: bool = False)[source]¶
Bases:
VQA
- class qarp.algorithms.WalkerState(state_data: ndarray | Block, sign: float, label: str)[source]¶
Bases:
NamedTupleRepresents a quantum walker state.
- Variables:
- state_data: ndarray | Block¶
Alias for field number 0
- class qarp.algorithms.cPCE(graph: Graph, order: int, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, merging: bool = False, classical_function: Callable = <function classical_function>, quantum_function: Callable = <function quantum_function>, coefficients: Iterable[float] | None = None, initial_parameters: Iterable[float] | None = None, optimizer: Optimizer | None = None, verbose: bool = True, gradient: bool | str = False, primitive: PrimitiveAlgorithm | None = None, engine: Engine | None = None)[source]¶
Bases:
PCEContinuous Pauli Correlation Encoding (cPCE).
cPCE reuses the same measurement and optimization machinery as PCE, but drops the tanh + sign thresholding step used to turn Pauli expectation values into a discrete bitstring. Instead, the expectation values are used directly (optionally rescaled by coefficients) as the solution to a real-valued optimization problem.
This implementation follows the approach described in https://arxiv.org/abs/2604.05637.
- qarp.algorithms.calculate_qubits(n_nodes: int, order: int, merging: bool = False) int[source]¶
Compute the needed number of qubits for a given number of graph nodes and order
- Parameters:
n_nodes – Number of nodes to map into the qubits.
order – Order to consider in the Pauli correlators.
merging – If True, considers merging of same Pauli terms of different correlators.
- Returns:
Number of qubits required.
- qarp.algorithms.classical_function_max_cut(graph: Graph, binary_string: list[int]) float[source]¶
Calculate the cut size of the given partitions of the graph.
- Parameters:
graph – Original graph over which to compute the cut size.
binary_string – Binary representation of solution, where each position represents a node, and it value (0 or 1) represents the subset location.
- Returns:
Sum of weighted edges cut due to the partitions.
- qarp.algorithms.dirichlet_kernel_squared(x, phi, N)[source]¶
Dirichlet kernel squared function. Used to reconstruct the phase information in the QPE algorithm.
- qarp.algorithms.find_eigenspectrum_degeneracy(eigs, tolerance=1e-15, verbose=False)[source]¶
Finds the degeneracy of the eigenvalues in the eigenspectrum.
- qarp.algorithms.find_occupation_numbers(hamiltonian, n_qubits, tolerance=1e-15, verbose=False)[source]¶
Finds the occupation numbers of the eigenstates of a Hamiltonian.
- Parameters:
hamiltonian (FermionOperator) – The Hamiltonian operator.
n_qubits (int) – The number of qubits.
tolerance (float) – The tolerance for determining occupation numbers.
verbose (bool) – If True, prints the eigenvalues and occupation numbers.
- Returns:
An array of occupation numbers for the eigenstates.
- Return type:
np.ndarray
- qarp.algorithms.find_unique_eigs_and_occupation_numbers(eigs, occ_numbers, select_occ=None, tolerance=1e-15, verbose=False)[source]¶
Finds unique eigenvalues and their corresponding occupation numbers.
- Parameters:
eigs (np.ndarray) – The eigenvalues of the Hamiltonian.
occ_numbers (np.ndarray) – The occupation numbers corresponding to the eigenvalues.
select_occ (int, optional) – If provided, filters the unique eigenvalues by this occupation number.
tolerance (float) – The tolerance for determining degeneracy.
verbose (bool) – If True, prints the unique eigenvalues and their occupation numbers.
- Returns:
- A tuple containing:
dict: A dictionary with unique eigenvalues as keys and their degeneracy as values.
list: A list of unique occupation numbers corresponding to the unique eigenvalues.
- Return type:
- qarp.algorithms.generate_states_new_basis(U: Block, hamming_weight: int | List[int] | None = None, get_statevector: bool = True) Tuple[List[ndarray], List[Block], List[int]][source]¶
Apply a unitary block
Uto every computational basis state and (optionally) compute the resulting statevectors.The new basis is \(\{ U |i\rangle : i \in \mathrm{indices} \}\).
WARNING: exponential scaling — the indices set is
2^n_qubitsunlesshamming_weightfilters it down.- Parameters:
U – A built
qarp.blocks.AnyBlockwhose unitary is the change of basis.hamming_weight – If int, restrict to computational basis states with exactly that Hamming weight. If list[int], restrict to the union of those weights. If None, use every basis state.
get_statevector – If True, compute each new basis state’s statevector via the qarpx simulator (still exponential). If False, return an empty statevector list.
- Returns:
new_basis_states— list of length-2^n_qubitsndarrays (only populated whenget_statevector=True).new_basis_blocks—Blockper basis state:ComputationalBasisStateBlock(bitstring) + U.basis_states_indices— the integer indices the basis was built from.
- Return type:
(new_basis_states, new_basis_blocks, basis_states_indices)where
- qarp.algorithms.get_overlaps(trial_state: Block, hamiltonian: QubitOperator, return_eigenvalues: bool = False) ndarray | Tuple[ndarray, ndarray][source]¶
Compute overlaps of trial state with eigenstates of the Hamiltonian.
- Parameters:
trial_state – Block representing the trial state.
hamiltonian – QubitOperator representing the Hamiltonian.
return_eigenvalues – If True, also return the eigenvalues.
- Returns:
Array of overlap probabilities with each eigenstate, sorted by ascending eigenvalue. If
return_eigenvaluesis True, returns a(overlaps, eigenvalues)tuple instead.
Note
Uses np.linalg.eigh which returns eigenvectors as COLUMNS of the matrix. The overlaps are computed correctly by iterating over columns.
- class qarp.algorithms.iterativePCE(graph: Graph, order: int, ket: SimpleBlock | CompositeBlockBase | ControlledBlock | MeasureBlock | ResetBlock | ConditionalBlock, pce_cls: type = <class 'qarp.algorithms._composite.pce.PCE'>, alpha0: float = 1.0, threshold: float = 0.9, max_outer_iterations: int = 50, stabilized_update: bool = False, verbose: bool = True, **pce_kwargs)[source]¶
Bases:
CompositeAlgorithmIterative-alpha Pauli Correlation Encoding.
Wraps a PCE-like algorithm (by default PCE, but compatible with any class sharing its constructor/build/run/get_objective_function surface) and repeatedly re-runs it, progressively increasing the sharpness parameter alpha used to binarize Pauli-correlator expectation values via tanh(alpha * <Pi>). At each round, only the least-binarized correlator is pushed just past the binarization threshold M, and the ansatz parameters are warm-started from the previous round’s optimum.
This avoids the tradeoff of a single fixed alpha: too small and the loss/constraint is evaluated on an under-binarized (and thus misleading) solution; too large and tanh’s vanishing derivative stalls the optimizer everywhere at once.
Implements Algorithm 1 (“Iterative-alpha PCE heuristic”) from https://arxiv.org/abs/2602.17479.
After run(), alpha_history, raw_expectations_history and solution_history hold, per round, the alpha used, the raw <Pi_i> expectation values obtained at convergence, and the rounded solution. There is exactly ONE inner algorithm — built once and re-run — so sub_algorithms has a single entry, not one per round.
- build()[source]¶
No-op: each round’s inner algorithm is built when it is constructed in run.
- Returns:
self
- run()[source]¶
Run the Iterative-alpha PCE heuristic.
At every round, runs pce_cls to convergence with the current alpha, then rescales alpha to push the least-binarized correlator just past threshold, warm-starting the next round from the converged ansatz parameters. Stops once every correlator is binarized or max_outer_iterations is reached.
- Returns:
The final energy, final parameters and solution, as returned by the last round’s pce_cls.run().