mimiqcircuits.backends.compiled_projection¶
Compiled form of a projection circuit.
extract_projection()
returns the projection as a Circuit, and
evaluate_projection()
interprets it one instruction at a time, for one shot at a time. That
is the reference semantics, and it costs one interpreted loop per shot.
CompiledProjection compiles the same circuit once, into a
straight-line program over classical bits, and runs it over a whole
block of shots. Two tiers:
Tier.IDENTITY. Bitbreads qubitbfor every bit and the sample is exactly as wide as the register, so the samples are already the answer and are returned unchanged. This is the common case:measure(range, range),measure_all(), and any circuit with no classical register, sinceextract_projectionsynthesises the identity mapping for those.Tier.PROGRAM. Everything else. The block becomes one(shots, num_bits)array and each operation is a single vector operation over its columns, so a permuted read-out, a reset-folded constant and aXortail all cost the same handful of them.
The tier depends on the width of the samples as well as on the
circuit, because a Measure reading past the end of a sample
contributes a zero rather than a qubit. It is therefore chosen the
first time a block of a given width is evaluated, and cached.
Semantics are those of evaluate_projection, which stays the
reference implementation the compiled form is tested against.
Classes
|
A projection circuit compiled for block evaluation. |
|
Names of the two evaluation strategies, in increasing generality. |
- class mimiqcircuits.backends.compiled_projection.CompiledProjection(num_bits, steps=<factory>, _plans=<factory>)[source]¶
Bases:
objectA projection circuit compiled for block evaluation.
Build one with
from_circuit()and evaluate a whole block of shots withevaluate_batch(). An instance is reusable across blocks and holds no per-shot state.- num_bits¶
Width of the classical bitstring the projection produces, equal to
projection.num_bits().- Type:
- steps¶
The straight-line program, before specialisation to a sample width. Internal representation, subject to change.
- classmethod from_circuit(projection)[source]¶
Compile projection for block evaluation.
- Parameters:
projection (Circuit) – the projection circuit returned by
extract_projection(), in the frame its samples will arrive in. Qubit remapping must already have been applied, otherwise the tier keys off the wrong frame and a permuted read-out is mistaken for an identity one.- Returns:
the compiled form, of width
projection.num_bits().- Return type:
- Raises:
ValueError – if projection holds an operation outside the classical language, that is anything other than
Measure,SetBit0,SetBit1,Not,And,Or,XorandParityCheck.
- evaluate_batch(samples)[source]¶
Evaluate the projection for every shot in samples.
- Parameters:
samples (Sequence[BitString]) – one computational-basis outcome per shot, all of the same width. Not quantum states: each is a single shot already drawn from one.
- Returns:
one classical bitstring per shot, of length
num_bits, in the order the samples came in.- Return type:
list[BitString]
On the identity tier the input bitstrings are returned as they are, without copying, so a caller that keeps using the samples afterwards must copy them itself.
- evaluate(sample)[source]¶
Evaluate the projection for a single shot.
Provided for parity with
evaluate_projection().evaluate_batch()is the fast path and the one drivers should call.
- __init__(num_bits, steps=<factory>, _plans=<factory>)¶