qml.measurements.ClassicalShadowMP¶
- class ClassicalShadowMP(wires=None, seed=None, id=None)[source]¶
Bases:
MeasurementTransform
Represents a classical shadow measurement process occurring at the end of a quantum variational circuit.
Please refer to
pennylane.classical_shadow()
for detailed documentation.- Parameters:
wires (.Wires) – The wires the measurement process applies to.
seed (Union[int, None]) – The seed used to generate the random measurements
id (str) – custom label given to a measurement instance, can be useful for some applications where the instance has to be identified
Attributes
Whether or not the MeasurementProcess returns a defined decomposition when calling
expand
.returns an integer hash uniquely representing the measurement process
The Python numeric type of the measurement result.
The wires the measurement process acts on.
Whether or not the MeasurementProcess measures in the computational basis.
The wires the measurement process acts on.
- has_decomposition¶
Whether or not the MeasurementProcess returns a defined decomposition when calling
expand
.- Type:
Bool
- hash¶
returns an integer hash uniquely representing the measurement process
- Type:
int
- numeric_type¶
- raw_wires¶
The wires the measurement process acts on.
For measurements involving more than one set of wires (such as mutual information), this is a list of the Wires objects. Otherwise, this is the same as
wires()
- samples_computational_basis¶
- wires¶
The wires the measurement process acts on.
This is the union of all the Wires objects of the measurement.
Methods
Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.
eigvals
()Eigenvalues associated with the measurement process.
expand
()Expand the measurement of an observable to a unitary rotation and a measurement in the computational basis.
map_wires
(wire_map)Returns a copy of the current measurement process with its wires changed according to the given wire map.
process
(tape, device)Returns the measured bits and recipes in the classical shadow protocol.
process_density_matrix_with_shots
(state, ...)Process the given quantum state (density matrix) with the given number of shots
process_state_with_shots
(state, wire_order, ...)Process the given quantum state with the given number of shots
queue
([context])Append the measurement process to an annotated queue.
shape
([shots, num_device_wires])Calculate the shape of the result object tensor.
simplify
()Reduce the depth of the observable to the minimum.
- diagonalizing_gates()¶
Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.
- Returns:
the operations that diagonalize the observables
- Return type:
List[.Operation]
- eigvals()¶
Eigenvalues associated with the measurement process.
If the measurement process has an associated observable, the eigenvalues will correspond to this observable. Otherwise, they will be the eigenvalues provided when the measurement process was instantiated.
Note that the eigenvalues are not guaranteed to be in any particular order.
Example:
>>> m = MeasurementProcess(Expectation, obs=qml.X(1)) >>> m.eigvals() array([1, -1])
- Returns:
eigvals representation
- Return type:
array
- expand()¶
Expand the measurement of an observable to a unitary rotation and a measurement in the computational basis.
- Returns:
a quantum tape containing the operations required to diagonalize the observable
- Return type:
.QuantumTape
Example:
Consider a measurement process consisting of the expectation value of an Hermitian observable:
>>> H = np.array([[1, 2], [2, 4]]) >>> obs = qml.Hermitian(H, wires=['a']) >>> m = MeasurementProcess(Expectation, obs=obs)
Expanding this out:
>>> tape = m.expand()
We can see that the resulting tape has the qubit unitary applied, and a measurement process with no observable, but the eigenvalues specified:
>>> print(tape.operations) [QubitUnitary(array([[-0.89442719, 0.4472136 ], [ 0.4472136 , 0.89442719]]), wires=['a'])] >>> print(tape.measurements[0].eigvals()) [0. 5.] >>> print(tape.measurements[0].obs) None
- map_wires(wire_map)¶
Returns a copy of the current measurement process with its wires changed according to the given wire map.
- Parameters:
wire_map (dict) – dictionary containing the old wires as keys and the new wires as values
- Returns:
new measurement process
- Return type:
.MeasurementProcess
- process(tape, device)[source]¶
Returns the measured bits and recipes in the classical shadow protocol.
The protocol is described in detail in the classical shadows paper. This measurement process returns the randomized Pauli measurements (the
recipes
) that are performed for each qubit and snapshot as an integer:0 for Pauli X,
1 for Pauli Y, and
2 for Pauli Z.
It also returns the measurement results (the
bits
); 0 if the 1 eigenvalue is sampled, and 1 if the -1 eigenvalue is sampled.The device shots are used to specify the number of snapshots. If
T
is the number of shots andn
is the number of qubits, then both the measured bits and the Pauli measurements have shape(T, n)
.This implementation is device-agnostic and works by executing single-shot quantum tapes containing randomized Pauli observables. Devices should override this if they can offer cleaner or faster implementations.
See also
- Parameters:
tape (QuantumTape) – the quantum tape to be processed
device (pennylane.devices.LegacyDevice) – the device used to process the quantum tape
- Returns:
A tensor with shape
(2, T, n)
, where the first row represents the measured bits and the second represents the recipes used.- Return type:
tensor_like[int]
- process_density_matrix_with_shots(state, wire_order, shots, rng=None)[source]¶
Process the given quantum state (density matrix) with the given number of shots
- Parameters:
state (Sequence[complex]) – quantum density matrix given as a rank-N tensor, where each dim has size 2 and N is twice the number of wires.
wire_order (Wires) – wires determining the subspace that
state
acts on; a matrix of dimension \(2^n\) acts on a subspace of \(n\) wiresshots (int) – The number of shots
rng (Union[None, int, array_like[int], SeedSequence, BitGenerator, Generator]) – A seed-like parameter matching that of
seed
fornumpy.random.default_rng
. If no value is provided, a default RNG will be used. The random measurement outcomes in the form of bits will be generated from this argument, while the random recipes will be created from theseed
argument provided to.ClassicalShadowsMP
.
- Returns:
A tensor with shape
(2, T, n)
, where the first row represents the measured bits and the second represents the recipes used.- Return type:
tensor_like[int]
- process_state_with_shots(state, wire_order, shots, rng=None)[source]¶
Process the given quantum state with the given number of shots
- Parameters:
state (Sequence[complex]) – quantum state vector given as a rank-N tensor, where each dimension has size 2 and N is the number of wires.
wire_order (Wires) – wires determining the subspace that
state
acts on; a matrix of dimension \(2^n\) acts on a subspace of \(n\) wiresshots (int) – The number of shots
rng (Union[None, int, array_like[int], SeedSequence, BitGenerator, Generator]) – A seed-like parameter matching that of
seed
fornumpy.random.default_rng
. If no value is provided, a default RNG will be used. The random measurement outcomes in the form of bits will be generated from this argument, while the random recipes will be created from theseed
argument provided to.ClassicalShadowsMP
.
- Returns:
A tensor with shape
(2, T, n)
, where the first row represents the measured bits and the second represents the recipes used.T
is the number of shots, andn
is the number of qubits.- Return type:
tensor_like[int]
- queue(context=<class 'pennylane.queuing.QueuingManager'>)¶
Append the measurement process to an annotated queue.
- shape(shots=None, num_device_wires=0)[source]¶
Calculate the shape of the result object tensor.
- Parameters:
shots (Optional[int]) – the number of shots used execute the circuit.
None
indicates an analytic simulation. Shot vectors are handled by calling this method multiple times.num_device_wires (int) – The number of wires that will be used if the measurement is broadcasted across all available wires (
len(mp.wires) == 0
). If the device itself doesn’t provide a number of wires, the number of tape wires will be provided here instead:
- Returns:
An arbitrary length tuple of ints. May be an empty tuple.
- Return type:
tuple[int,…]
>>> qml.probs(wires=(0,1)).shape() (4,) >>> qml.sample(wires=(0,1)).shape(shots=50) (50, 2) >>> qml.state().shape(num_device_wires=4) (16,) >>> qml.expval(qml.Z(0)).shape() ()
- simplify()¶
Reduce the depth of the observable to the minimum.
- Returns:
A measurement process with a simplified observable.
- Return type:
.MeasurementProcess