unitaria.Subspace¶
- class unitaria.Subspace(tensor_factors: list[SubspaceFactor] | str = [])[source]¶
Bases:
objectSubspace of the statespace of a number of qubits.
In
unitaria, subspaces are always the span of vectors in the computational basis, so this object just stores the indices of these computational basis states.Constructors¶
If you just need a subspace with a given dimension, use
Subspace.from_dim.Otherwise, the preferred way to construct subspaces is using the string constructor. It takes a string consisting of
#and0, respectively representing a bit that can be in either state, or a bit that should be in its0state.>>> import unitaria as ut >>> ut.Subspace("#").enumerate_basis() array([0, 1], dtype=int32) >>> ut.Subspace("0").enumerate_basis() array([0], dtype=int32)
Alternatively, the subspace can be constructed according to its internal representation, see below.
When given multiple symbols, they are combined using tensor products as expected.
>>> import unitaria as ut >>> ut.Subspace("##0").enumerate_basis() array([0, 2, 4, 6], dtype=int32)
Subspaces can be combined using the operators
&(tensor product) or|direct sum.>>> import unitaria as ut >>> (ut.Subspace("#") & ut.Subspace("0")).enumerate_basis() array([0, 2], dtype=int32) >>> (ut.Subspace("#") | ut.Subspace("0")).enumerate_basis() array([0, 1, 2], dtype=int32)
Intutively, with the
|operator the highest bit decides the subspace of the lower bits. So in the example above, when the highes bit is0then the lower bit can either be0or1, but when the highest bit is1then the lower bit has to be0.Reading the subspace¶
The method
enumerate_basisgives a list of all the indices in the subspace, but this should typically only be used for verification. It does not make sense as part of an efficient quantum algorithm, since the complexity ofenumerate_basisis always linear in the dimension.The methods
test_basison the other hand is efficient. It checks whether a given index is in the subspace.The dimension of the subspace can be obtained using
Subspace.dimension. The dimension of the super-space can be caluclated from the number of qubits, which is stored inSubspace.total_qubits. Specifically, the super-space dimension is2 ** subspace.total_qubits.>>> import unitaria as ut >>> ut.Subspace("0#0").dimension 2 >>> ut.Subspace("0#0").total_qubits 3
Internal representation¶
Typically one does not need to inspect
Subspaceobjects, most properties can be derived using its methods. Internally, the object stores a decomposition of the subspace into tensor factors. This decomposition is simplified at construction and so does not have to correspond to the factors that are put in. Any of the factors can be eithera
ZeroQubitSubspace, indicating the subspace of the space of one qubit, where this qubit is zero, ora
ControlledSubspace, indicating that a subspace, where the most siginificant bit determines the subspaces of the lower bits. These subspaces are given byControlledSubspace.case_zeroandControlledSubspace.case_one. With this one can also construct the full subspace of a qubit byControlledSubspace(Subspace(), Subspace()). (For this there is also the constantFullQubitSubspace.)
- param tensor_factors:
List or string of factors making up the subspace, see below.
- raises ValueError:
If a string with characters other than
#or0is given or a list with anything that is not aSubspaceFactor
- static from_dim(dim: int, bits: int | None = None) Subspace[source]¶
Create a subspace of a given dimension. :param dim: The dimension of the subspace :param bits: The number of qubits of the super-space, if not given, the smallest number of qubits such that the dimension fits will be used. :return: A subspace of the given dimension.
- case_one() Subspace | None[source]¶
Returns the subspace where the highest relevant bit is one.
The highest relevant bit is the first bit that does not correspond to a zero factor, see
Subspace.initial_zeros.- Returns:
The subspace, or none, if all factors are zero.
- case_zero() Subspace | None[source]¶
Returns the subspace where the highest relevant bit is zero.
The highest relevant bit is the first bit that does not correspond to a zero factor, see
Subspace.initial_zeros.- Returns:
The subspace, or none, if all factors are zero.
- circuit(target: Sequence[int], flag: int, ancillae: Sequence[int]) Circuit[source]¶
A circuit which checks whether a state is inside the subspace.
The result of the check will be stored in a flag qubit where the index is the output of
total_qubits. Specifically, this qubit will be flipped if the other qubits represent a state outside the embedded vector space.
- draw_tree() str[source]¶
Draws a tree representation of the subspace according to its internal representation. :return: A string representing the tree structure of the subspace.
- match_nonzero(other: Subspace) bool[source]¶
Tests whether the nonzero factors of two subspaces are equal. :return: True if the nonzero factors are equal, False otherwise
- truncate(dimension: int) Subspace[source]¶
Return the subspace, which contains the first
dimensionbasis vectors of this subspace.The number of qubits remains unchanged.
- Parameters:
dimension – The dimension of the truncated subspace
- Returns:
The truncated subspace
- Raises:
ValueError – If
dimensionis not in the range(0, self.dimension].
- tensor_factors: list[SubspaceFactor]¶