unitaria.Node¶
- class unitaria.Node(dimension_in: int, dimension_out: int)[source]¶
Bases:
ABCAbstract class for all nodes in the computational graph
The encoded vector or the action of the encoded matrix can be obtained either through matrix arithmetic using
computeor as a quantum block encoding usingcircuit,normalization,subspace_in, andsubspace_out.When creating your own subclass of
Node, you should implement the functions_subspace_in,_subspace_out,_normalization,_circuit,compute, andcompute_adjoint. Potentially alsochildrenandparameters.Note the prefixed underscores for some of these methods, which are necessary due to how the properties of
Nodeare cached.To check that these methods are implemented correctly, use
verify.As an alternative if you can represent your custom node in terms of other nodes, and just want to provide a more efficient implementation of some of the functions – say
computeandcompute_adjoint– you can instead create a subclass ofProxyNode.- abstractmethod _circuit(target: Sequence[int], clean_ancillae: Sequence[int], borrowed_ancillae: Sequence[int]) Circuit[source]¶
Method for computing
circuit.To be implemented in all subclasses of
Node.
- abstractmethod _normalization() float[source]¶
Method for computing
normalization.To be implemented in all subclasses of
Node.
- abstractmethod _subspace_in() Subspace[source]¶
Method for computing
subspace_in.To be implemented in all subclasses of
Node.
- abstractmethod _subspace_out() Subspace[source]¶
Method for computing
subspace_out.To be implemented in all subclasses of
Node.
- adjoint()¶
- abstractmethod borrowed_ancilla_count() int[source]¶
Returns the number of borrowed ancillae used by the circuit of this node, i.e. qubits that can be in any state and will be returned to this state by the end of the circuit.
- children() list[Node][source]¶
The children nodes of this node
Mostly used for serialization and systematic verification of the computational graph. Children and parameters together should fully define the matrix encoded by any node.
- circuit(target: Sequence[int] = None, clean_ancillae: Sequence[int] = None, borrowed_ancillae: Sequence[int] = None) Circuit[source]¶
The circuit corresponding to the unitary of the block encoding.
Qubit indices for the target and ancillae can be passed via arguments, otherwise the default is simply use the indices 0, 1, … in the order target, clean_ancillae, borrowed_ancillae. If indices are passed, the length of the ancillae needs to match the values returned by
clean_ancillae_count()andborrowed_ancillae_count().
- abstractmethod clean_ancilla_count() int[source]¶
Returns the number of borrowed ancillae used by the circuit of this node, i.e. qubits that must be in state
|0>at the beginning of the circuit and will be returned to this state by the end of the circuit.
- abstractmethod compute(input: ndarray) ndarray[source]¶
Apply the action of this nodes matrix to the input.
If this node encodes a vector, then
input = Noneis valid, in which case the method should simply return the encoded vector.Input may be a vector or a higher order tensor. If it is a vector it will have dimension equal to the dimension of
qubits_in. If it is a tensor, the last dimension will be equal to the dimension ofqubits_in. In this case, the operation should be applied to all vectorsinput[i, j, ..., k, :]in parallel. The shape of the returned array should match the input shape in all but the last dimension.
- abstractmethod compute_adjoint(input: ndarray) ndarray[source]¶
Apply the adjoint action of this nodes matrix to the input.
See
computefor input and output formats.
- compute_norm(input: np.array | None = None) float[source]¶
Method to compute the norm of this vector given the arithmetic definition of this node using
compute.
- draw(verbose: bool = False) str[source]¶
Rich text output of the computational graph
- Parameters:
verbose – if set to
True, the definition of anyProxyNodeis inserted into the
- is_guaranteed_unitary() bool[source]¶
If this returns true, the matrix the node represents divided by its normalization must be unitary.
This must be ensured by the implementor of this method. A unitary node is useful, since it avoids having to use projections in multiplications.
- parameters() dict[source]¶
The parameters of this graph
Mostly used for serialization and systematic verification of the computational graph. Children and parameters together should fully define the matrix encoded by any node.
- simulate(input: int | None = None) ndarray[source]¶
Returns a numpy array representing this node, as given by
simulate.When
inputisNone, the output of this method should matchcompute, which can be checked usingverify.- Parameters:
input – The index of the optional initial state, with which this node should be simulated. Should be a number between
0andnode.dimension_out - 1
- simulate_norm(input: int | None = None) float[source]¶
Method to simulate the norm of the encoded vector in the subspace using a circuit.
When calling this function on a node encoding a matrix,
inputhas to be a vector. In this case the norm of the matrix applied toinputis given.- Parameters:
input – A vector to which the encoded matrix is applied before computing the norm.
- toarray(force_matrix: bool = False) ndarray[source]¶
Returns a numpy array representing this node, as given by
compute.The output of this method should match
simulate, which can be checked usingverify.By default this will return a one-dimension array if the node represents a vector. However, this behaviour can be suppressed by setting
force_matrix = True- Parameters:
force_matrix – Force the method to return a two-dimensional array, even when the node corresponds to a vector.
- tree(verbose: bool = False, tree: Tree | None = None, holes: list[Node] = []) Tree[source]¶
Method for rich text output of the computational graph.
Typically you should call
drawinstead of this method.
- tree_label(verbose: bool = False)[source]¶
Label by which this node should be represented in textual (debug) output.
Defaults to the name of the nodes class plus its parameters.
- _cached_circuit[source]¶
Calls _circuit with target, clean_ancillae and borrowed_ancillae being the qubits 0, 1, … so that the result can be cached. This is then mapped by circuit to the actually requested qubit indices.
- normalization[source]¶
Normalization of the block encoding.
Non-negative number, which has to be multiplied with the outputs of the circuit to ensure proper scaling of the result.
- subspace_in[source]¶
The embedding of the input vectorspace.
Specifically this specifies how the vectorspace is included in state space nodes circuit, which has dimension 2^n where n is the number of qubits. In other words, this defines whether a particular basis state is “valid” or “invalid”.
In the formalism of block encodings this corresponds to the projection \Pi_1.
- subspace_out[source]¶
The embedding of the output vectorspace.
Specifically this specifies how the vectorspace is included in state space nodes circuit, which has dimension 2^n where n is the number of qubits. In other words, this defines whether a particular basis state is “valid” or “invalid”.
In the formalism of block encodings this corresponds to the projection \Pi_2.