Phase-space Representation of Stabilizer States#
A stabilizer state \(\ketbra{\psi}{\psi}\) can be uniquely defined by the set of its stabilizers, i.e. those unitary operators \(U\) that have \(\psi\) as an eigenstate with eigenvalue \(1\). In general, \(n\)-qubit stabilizer states are stabilized by \(d = 2^n\) Pauli operators on said \(n\) qubits. However, it is known that the set of \(d\) Paulis can be generated by only \(n\) unique members of the set. In that case, indeed, the number of operators needed to represent a stabilizer state reduces to \(n\). Each one of these \(n\) Pauli generators takes \(2n + 1\) bits to specify, yielding a \(n(2n+1)\) total number of bits needed. In particular, Aaronson and Gottesman (2004) demonstrated that the application of Clifford gates on stabilizer states can be efficiently simulated in this representation at the cost of storing the generators of the destabilizers, in addition to the stabilizers.
A \(n\)-qubit stabilizer state is uniquely defined by a symplectic matrix of the form
where \((x_{kl},z_{kl})\) are the bits encoding the \(n\)-qubits Pauli generator as
The qibo.quantum_info.clifford.Clifford object is in charge of storing the
phase-space representation of a stabilizer state.
This object is automatically created after the execution of a Clifford circuit through the
qibo.backends.clifford.CliffordBackend, but it can also be created by directly
passing a symplectic matrix to the constructor.
The generators of the stabilizers can be extracted with the
qibo.quantum_info.clifford.Clifford.generators() method,
or the complete set of \(d = 2^{n}\) stabilizers operators can be extracted through the
qibo.quantum_info.clifford.Clifford.stabilizers() method.
generators, phases = clifford.generators()
stabilizers = clifford.stabilizers()
The destabilizers can be extracted analogously with qibo.quantum_info.clifford.Clifford.destabilizers().
We provide integration with the stim package. It is possible to run Clifford circuits using stim as a platform:
from qibo.backends import CliffordBackend
from qibo.quantum_info import Clifford, random_clifford
clifford_backend = CliffordBackend(platform="stim")
circuit = random_clifford(nqubits)
result = clifford_backend.execute_circuit(circuit)
## Note that the execution above is equivalent to the one below
result = Clifford.from_circuit(circuit, platform="stim")
- class qibo.quantum_info.clifford.Clifford(data, nqubits=None, measurements=None, nshots=1000, platform=None, _backend=None, _measurement_gate=None, _samples=None)[source]#
Object storing the results of a circuit execution with the
qibo.backends.clifford.CliffordBackend.- Parameters:
data (ArrayLike or
qibo.models.circuit.Circuit) – IfArrayLike, it is the symplectic matrix of the stabilizer state in phase-space representation. Ifqibo.models.circuit.Circuit, it is a circuit composed only of Clifford gates and computational-basis measurements.nqubits (int, optional) – number of qubits of the state.
measurements (list, optional) – list of measurements gates
qibo.gates.M. Defaults toNone.nshots (int, optional) – number of shots used for sampling the measurements. Defaults to \(1000\).
platform (str, optional) –
platform to use in the execution of the
qibo.backends.CliffordBackend. It accepts"numpy","numba","cupy", and"stim"(see stim). IfNone, defaults to the corresponding platform from the current backend. Defaults toNone._backend (CliffordBackend | None) –
_measurement_gate (M | None) –
_samples (_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None) –
- classmethod from_circuit(circuit, initial_state=None, nshots=1000, platform=None)[source]#
Allows to create a
qibo.quantum_info.clifford.Cliffordobject by executing the input circuit.- Parameters:
circuit (
qibo.models.circuit.Circuit) – Clifford circuit to run.initial_state (ArrayLike, optional) – symplectic matrix of the initial state. If
None, defaults to the symplectic matrix of the zero state. Defaults toNone.nshots (int, optional) – number of measurement shots to perform if
circuithas measurement gates. Defaults to \(10^{3}\).platform (str, optional) –
engine to use in the execution of the
qibo.backends.CliffordBackend. It accepts"numpy","numba","cupy", and"stim"(see stim). IfNone, defaults to the corresponding platform from the current backend. Defaults toNone.
- Returns:
Object storing the result of the circuit execution.
- Return type:
- to_circuit(algorithm='AG04', **kwargs)[source]#
Converts symplectic matrix into a Clifford circuit.
- Parameters:
algorithm (str, optional) – If
AG04, uses the decomposition algorithm from Aaronson & Gottesman (2004). IfBM20andClifford.nqubits <= 3, uses the decomposition algorithm from Bravyi & Maslov (2020). Defaults toAG04.kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. For details, see the documentation of
qibo.models.circuit.Circuit.
- Returns:
circuit composed of Clifford gates.
- Return type:
- stabilizers(symplectic=False, return_array=False)[source]#
Extracts the stabilizers of the state.
- Parameters:
symplectic (bool, optional) – If
True, returns the rows of the symplectic matrix that correspond to the \(n\) generators of the \(2^{n}\) total stabilizers, independently ofreturn_array.return_array (bool, optional) – To be used when
symplectic = False. IfTruereturns the stabilizers asArrayLike. IfFalse, returns stabilizers as strings. Defaults toFalse.
- Returns:
Stabilizers of the state.
- Return type:
(ArrayLike or list)
- destabilizers(symplectic=False, return_array=False)[source]#
Extracts the destabilizers of the state.
- Parameters:
symplectic (bool, optional) – If
True, returns the rows of the symplectic matrix that correspond to the \(n\) generators of the \(2^{n}\) total destabilizers, independently ofreturn_array.return_array (bool, optional) – To be used when
symplectic = False. IfTruereturns the destabilizers asArrayLike. IfFalse, their representation as strings is returned. Defaults toFalse.
- Returns:
Destabilizers of the state.
- Return type:
(ArrayLike or list)
- state()[source]#
Builds the density matrix representation of the state.
Note
This method is inefficient in runtime and memory for a large number of qubits.
- Returns:
Density matrix of the state.
- Return type:
ArrayLike
- property measurement_gate: M#
Single measurement gate containing all measured qubits.
Useful for sampling all measured qubits at once when simulating.
- samples(binary=True, registers=False)[source]#
Returns raw measurement samples.
- Parameters:
- Returns:
- If
binaryisTrue samples are returned in binary form as a tensor of shape
(nshots, n_measured_qubits).- If
binaryisFalse samples are returned in decimal form as a tensor of shape
(nshots,).- If
registersisTrue samples are returned in a
dictwhere the keys are the register names and the values are the samples tensors for each register.- If
registersisFalse a single tensor is returned which contains samples from all the measured qubits, independently of their registers.
- If
- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | dict
- frequencies(binary=True, registers=False)[source]#
Returns the frequencies of measured samples.
- Parameters:
- Returns:
A collections.Counter where the keys are the observed values and the values the corresponding frequencies, that is the number of times each measured value/bitstring appears.
- If
binaryisTrue the keys of the
collections.Counterare in binary form, as strings of \(0\) and \(1\).- If
binaryisFalse the keys of the
collections.Counterare integers.- If
registersisTrue a dict of
collections.Counteris returned where keys are the name of each register.- If
registersisFalse a single
collections.Counteris returned which contains samples from all the measured qubits, independently of their registers.
- If
- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | dict
- probabilities(qubits=None)[source]#
Computes the probabilities of the selected qubits from the measured samples.
- copy(deep=False)[source]#
Returns copy of
qibo.quantum_info.clifford.Cliffordobject.- Parameters:
deep (bool, optional) – If
True, creates another copy in memory. Defaults toFalse.- Returns:
copy of original
Cliffordobject.- Return type: