qubrabench package¶
Subpackages¶
- qubrabench.algorithms package
- qubrabench.datastructures package
- qubrabench.utils package
- Submodules
- qubrabench.utils.plotting module
BasicPlottingStrategy
PlottingStrategy
PlottingStrategy.color_for_data_group()
PlottingStrategy.colors
PlottingStrategy.compute_aggregates()
PlottingStrategy.get_column_names_to_plot()
PlottingStrategy.get_data_group_column_names()
PlottingStrategy.get_plot_group_column_names()
PlottingStrategy.make_plot_label()
PlottingStrategy.make_plot_title()
PlottingStrategy.plot()
PlottingStrategy.serialize_value_tuple()
PlottingStrategy.x_axis_column()
PlottingStrategy.x_axis_label()
PlottingStrategy.y_axis_label()
- Module contents
Submodules¶
qubrabench.benchmark module¶
- exception qubrabench.benchmark.BenchmarkError¶
Bases:
Exception
Base class for raising benchmarking errors
- class qubrabench.benchmark.BlockEncoding(matrix: ndarray[Any, dtype[complex128]], subnormalization_factor: float, precision: float, uses: Iterable[tuple[Hashable, float]] = _Nothing.NOTHING)¶
Bases:
QObject
Unitary that block-encodes an approximation of a (subnormalized version of a) matrix.
Given a matrix $A$, subnormalization factor $alpha$ and precision $epsilon$, this object represents a unitary program $U$ (possibly using ancilla) satisfying
\[\| A - \alpha (\langle 0 | \otimes I) U (|0\rangle \otimes I) \|_2 \le \epsilon\]This can also be visualized as
\[\begin{split}U \approx \begin{pmatrix} A/\alpha & \cdot \\ \cdot & \cdot \end{pmatrix}\end{split}\]- access(*, n_times: int = 1)¶
Access the block-encoded matrix via the implementing unitary
- costs: dict[Hashable, qubrabench.benchmark.QueryStats]¶
- matrix: ndarray[Any, dtype[complex128]]¶
The block-encoded matrix A
- precision: float¶
The spectral norm of the difference between the expected and actual encoded matrices.
If the top-left block of the unitary is $B$, then the precision is given by $| A - alpha B |_2$.
- subnormalization_factor: float¶
Factor $alpha$ s.t. $A / alpha$ is block-encoded
- uses: Iterable[tuple[Hashable, float]]¶
BlockEncodings or data-structures used to implement the block-encoding unitary
- class qubrabench.benchmark.QObject¶
Bases:
ABC
,Hashable
A quantum data-structure object whose queries are tracked.
- property stats: QueryStats¶
- class qubrabench.benchmark.QueryStats(classical_actual_queries: int = 0, classical_expected_queries: float | NotComputed = 0.0, quantum_expected_classical_queries: float | NotComputed = 0.0, quantum_expected_quantum_queries: float | NotComputed = 0.0, quantum_worst_case_classical_queries: float | NotComputed = 0.0, quantum_worst_case_quantum_queries: float | NotComputed = 0.0)¶
Bases:
object
Dataclass providing fields for different quantum and classical query counts. This is the main data model of the framework, holding actual and statistically calculated values.
- classical_actual_queries: int = 0¶
- classical_expected_queries: float | NotComputed = 0.0¶
- quantum_expected_classical_queries: float | NotComputed = 0.0¶
- quantum_expected_quantum_queries: float | NotComputed = 0.0¶
- quantum_worst_case_classical_queries: float | NotComputed = 0.0¶
- quantum_worst_case_quantum_queries: float | NotComputed = 0.0¶
- property quantum_worst_case_total_queries: float | NotComputed¶
total number of queries in a unitary implementing the action, possibly using workspace (garbage) registers
- record_query(n: int = 1)¶
- qubrabench.benchmark.default_tracker()¶
- qubrabench.benchmark.oracle(func: Callable[[_P], _R]) Callable[[_P], _R] ¶
Wrapper to track queries for functions.
Usage:
@oracle def some_func(*args, **kwargs): ... with track_queries() as tracker: ... print(tracker.get_stats(some_func))
This can also be run with bound instance methods
class MyClass @oracle def some_method(self, *args, **kwargs): ... @classmethod @oracle def some_class_method(cls, *args, **kwargs): ... @staticmethod @oracle def some_static_method(*args, **kwargs): ... with track_queries() as tracker: obj = MyClass() ... print(tracker.get_stats(obj.some_method)) print(tracker.get_stats(obj.some_class_method)) print(tracker.get_stats(obj.some_static_method))
- qubrabench.benchmark.quantum_subroutine(func: Callable[[_P], BlockEncoding]) Callable[[_P], BlockEncoding] ¶
Wrapper to mark a function as a quantum subroutine.
A quantum subroutine must return a BlockEncoding as output.
The wrapper ensures that all oracle calls are accounted for in the costs of the block-encoding, instead of throwing them to higher level tracker. This way, we can ensure that the costs when using the block-encoding are correct.
- qubrabench.benchmark.track_queries() Iterator[BenchmarkFrame] ¶
Track queries counts through the execution.
Usage:
- with track_queries() as tracker:
# do some computation
print(tracker.get_stats(some_quantum_oracle)) print(tracker.get_stats(some_object_with_a_quantum_oracle_method))
Module contents¶
- qubrabench.estimate_amplitude(x: BlockEncoding, good_indices: _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], *, precision: float, max_fail_probability: float) float ¶
Given a block-encoding of a state $ketpsi$ and a good index or sequence of good indices, estimate the probability of measuring (in the standard basis) one of the good indices.
Algorithm analysis is described in Ref. [1], Theorem 12 (Amplitude Estimation).
When $ket{x} = sum_i alpha_i ket{i}$, then this method produces an estimate of $a$ s.t.
\[a = \sum_{i \in \text{good}} \abs{alpha_i}^2\]If the input block-encoding does not perfectly prepare the state, but with some probability, this is factored into the subroutine in the quantum part (i.e. “under-the-square-root”)
- Parameters:
x – block-encoded access to vector x, such as a unitary that prepares $ket{x}$ with some success probability
good_indices – index or sequence of indices for which to estimate the total squared amplitude
precision – upper bound on the difference between the estimate and true value
max_fail_probability – upper bound on the probability of failure of the quantum algorithm
References
- [1] Quantum Amplitude Amplification and Estimation
Brassard, Hoyer, Mosca, Tapp. 2000. https://doi.org/10.48550/arXiv.quant-ph/0005055
- qubrabench.max(iterable: ~typing.Iterable[~qubrabench.algorithms.max.E], *, max_fail_probability: float, default: ~qubrabench.algorithms.max.E | ~qubrabench._internals.AbsentParameter = <qubrabench._internals.AbsentParameter object>, key: ~typing.Callable[[~qubrabench.algorithms.max.E], ~typing.Any] | None = None) E ¶
Find the largest element in a list.
- Parameters:
iterable – iterable to find the maximum in
default – default value to return if iterable is empty.
key – function that maps iterable elements to values that are comparable. By default, use the iterable elements.
max_fail_probability – upper bound on the failure probability of the quantum algorithm.
- Raises:
ValueError – Raised when iterable is an empty sequence and no default is provided.
- Returns:
the desired maximum element
- qubrabench.oracle(func: Callable[[_P], _R]) Callable[[_P], _R] ¶
Wrapper to track queries for functions.
Usage:
@oracle def some_func(*args, **kwargs): ... with track_queries() as tracker: ... print(tracker.get_stats(some_func))
This can also be run with bound instance methods
class MyClass @oracle def some_method(self, *args, **kwargs): ... @classmethod @oracle def some_class_method(cls, *args, **kwargs): ... @staticmethod @oracle def some_static_method(*args, **kwargs): ... with track_queries() as tracker: obj = MyClass() ... print(tracker.get_stats(obj.some_method)) print(tracker.get_stats(obj.some_class_method)) print(tracker.get_stats(obj.some_static_method))
- qubrabench.search(iterable: Iterable[E], key: Callable[[E], bool], *, max_fail_probability: float, rng: Generator | None = None, max_classical_queries: int = 130) E | None ¶
Search a list for an element satisfying the given predicate.
>>> search([1,2,3,4,5], lambda x: x % 2 == 0, max_fail_probability=1/3) 2
By default performs a linear scan on the iterable and returns the first element satisfying the key. If the optional random generator rng is provided, instead shuffles the input iterable before scanning for a solution.
>>> search([1,2,3,4,5], lambda x: x % 2 == 0, rng=np.random.default_rng(42), max_fail_probability=1/3) 4
- Parameters:
iterable – iterable to be searched over
key – function to test if an element satisfies the predicate
max_fail_probability – upper bound on the failure probability of the quantum algorithm
rng – random generator - if provided shuffle the input before scanning
max_classical_queries – maximum number of classical queries before entering the quantum part of the algorithm
- Returns:
An element that satisfies the predicate, or None if no such argument can be found.
- qubrabench.track_queries() Iterator[BenchmarkFrame] ¶
Track queries counts through the execution.
Usage:
- with track_queries() as tracker:
# do some computation
print(tracker.get_stats(some_quantum_oracle)) print(tracker.get_stats(some_object_with_a_quantum_oracle_method))