SolutionSamplingMixin

class SolutionSamplingMixin(*args, decode_solution_fn=None, **kwargs)[source]

Bases: object

Adds the discrete-solution-sampling capability to a quantum program.

Mix in before the host program (e.g. VQE/QAOA/PCE) for programs that extract a bitstring solution. It registers the "sample" pipeline and exposes the solution API (sample_solution(), get_top_solutions(), best_probs). Programs without it (e.g. data-bound QNN/CustomVQA) simply do not have these members — calling them raises AttributeError rather than silently returning nothing.

The mixin owns its result state (_best_probs) and decode hook (_decode_solution_fn); the host supplies _initial_spec and _resolve_sample_params (see the module docstring for the full contract).

Initialize the solution-sampling state.

Parameters:
  • decode_solution_fn (Callable[[str], Any] | None) – Function mapping a bitstring (e.g. "0101") to a problem-specific decoded representation (e.g. a list of indices, a numpy array, or a custom object). Called by get_top_solutions() when include_decoded=True and by subclass solution decoding. Defaults to the identity function.

  • *args – Forwarded to the next class in the MRO (the host program).

  • **kwargs – Forwarded to the next class in the MRO (the host program).

Attributes Summary

best_probs

Get normalized probabilities for the best parameters.

Methods Summary

get_top_solutions([n, min_prob, include_decoded])

Get the top-N solutions sorted by probability.

sample_solution([params])

Run the final measurement and decode the solution.

Attributes Documentation

best_probs

Get normalized probabilities for the best parameters.

This property provides access to the probability distribution computed by running measurement circuits with the best parameters found during optimization. It maps each parameter-set index to that set’s distribution over bitstrings (computational basis states).

The probabilities are normalized and iterate in a deterministic order.

Returns:

Dictionary mapping each parameter-set

index to a bitstring probability dictionary. Bitstrings are binary strings (e.g., “0101”), values are probabilities in range [0.0, 1.0]. Returns an empty dict if final computation has not been performed.

Return type:

dict[int, dict[str, float]]

Raises:

RuntimeError – If attempting to access probabilities before running the algorithm with final computation enabled.

Note

To populate this distribution, you must run the algorithm with perform_final_computation=True (the default):

>>> program.run(perform_final_computation=True)
>>> probs = program.best_probs

Example

>>> program.run()
>>> probs = program.best_probs
>>> for idx, distribution in probs.items():
...     print(f"parameter set {idx}:")
...     for bitstring, prob in distribution.items():
...         print(f"  {bitstring}: {prob:.2%}")
parameter set 0:
  0101: 42.50%
  1010: 31.20%
...

Methods Documentation

get_top_solutions(n=10, *, min_prob=0.0, include_decoded=False)[source]

Get the top-N solutions sorted by probability.

This method extracts the most probable solutions from the measured probability distribution. Solutions are sorted by probability (descending) with deterministic tie-breaking using lexicographic ordering of bitstrings.

Parameters:
  • n (int) – Maximum number of solutions to return. Must be non-negative. If n is 0 or negative, returns an empty list. If n exceeds the number of available solutions (after filtering), returns all available solutions. Defaults to 10.

  • min_prob (float) – Minimum probability threshold for including solutions. Only solutions with probability >= min_prob will be included. Must be in range [0.0, 1.0]. Defaults to 0.0 (no filtering).

  • include_decoded (bool) – Whether to populate the decoded field of each SolutionEntry by calling the decode_solution_fn provided in the constructor. If False, the decoded field will be None. Defaults to False.

Returns:

List of solution entries sorted by probability

(descending), then by bitstring (lexicographically ascending) for deterministic tie-breaking. Returns an empty list if no probability distribution is available or n <= 0.

Return type:

list[SolutionEntry]

Raises:
  • RuntimeError – If probability distribution is not available because optimization has not been run or final computation was not performed.

  • ValueError – If min_prob is not in range [0.0, 1.0] or n is negative.

Note

The probability distribution must be computed by running the algorithm with perform_final_computation=True (the default):

>>> program.run(perform_final_computation=True)
>>> top_10 = program.get_top_solutions(n=10)

If several parameter sets were sampled (an explicit multi-row sample_solution(params=...)), ranking uses only the first (lowest-index) set and emits a warning; use best_probs to access every set’s distribution.

Example

>>> # Get top 5 solutions with probability >= 5%
>>> program.run()
>>> solutions = program.get_top_solutions(n=5, min_prob=0.05)
>>> for sol in solutions:
...     print(f"{sol.bitstring}: {sol.prob:.2%}")
1010: 42.50%
0101: 31.20%
1100: 15.30%
0011: 8.50%
1111: 2.50%
>>> # Get solutions with decoding
>>> solutions = program.get_top_solutions(n=3, include_decoded=True)
>>> for sol in solutions:
...     print(f"{sol.bitstring} -> {sol.decoded}")
1010 -> [0, 2]
0101 -> [1, 3]
...
sample_solution(params=None, **kwargs)[source]

Run the final measurement and decode the solution.

Called by run() (with params=None, falling back to the host’s trained parameters) after optimization completes. It can also be called directly with externally-provided params when you already have trained parameters (e.g. from a prior run(), a checkpoint, or external training) and only need to sample the circuit — skipping the EXPECTATION jobs that run() would otherwise dispatch during optimization.

When called with explicit params, this method does NOT mutate the host’s optimizer state. Only the measurement-side attributes are updated: _best_probs, _total_circuit_count, _total_run_time, and subclass-specific solution fields (e.g. solution_bitstring for QAOA, _eigenstate for VQE).

Parameters:
Return type:

SolutionSamplingMixin

Returns:

The program itself, for method chaining.

Note

Subclasses override this method to add their algorithm-specific decoding step. They should call super().sample_solution(params) to perform the measurement-pipeline dispatch, then read from self._best_probs to extract algorithm-specific solution state.