tensorcircuit.quantum¶
Quantum state and operator class backend by tensornetwork
- tensorcircuit.quantum.PauliString2COO(l: Sequence[int], weight: float | None = None) Any[source]¶
Generate sparse matrix from Pauli string sum
- Parameters:
l (Sequence[int]) – 1D Tensor representing for a Pauli string, e.g. [1, 0, 0, 3, 2] is for \(X_0Z_3Y_4\)
weight (Optional[float], optional) – the weight for the Pauli string defaults to None (all Pauli strings weight 1.0)
- Returns:
the tensorflow sparse matrix
- Return type:
Tensor
- tensorcircuit.quantum.PauliStringSum2COO(ls: Sequence[Sequence[int]], weight: Sequence[float] | None = None, numpy: bool = False) Any[source]¶
Generate sparse tensor from Pauli string sum. Currently requires tensorflow installed
- Parameters:
ls (Sequence[Sequence[int]]) – 2D Tensor, each row is for a Pauli string, e.g. [1, 0, 0, 3, 2] is for \(X_0Z_3Y_4\)
weight (Optional[Sequence[float]], optional) – 1D Tensor, each element corresponds the weight for each Pauli string defaults to None (all Pauli strings weight 1.0)
numpy (bool) – default False. If True, return numpy coo else return backend compatible sparse tensor
- Returns:
the scipy coo sparse matrix
- Return type:
Tensor
- tensorcircuit.quantum.PauliStringSum2COO_numpy(ls: Sequence[Sequence[int]], weight: Sequence[float] | None = None, *, numpy: bool = True) Any¶
Generate sparse tensor from Pauli string sum. Currently requires tensorflow installed
- Parameters:
ls (Sequence[Sequence[int]]) – 2D Tensor, each row is for a Pauli string, e.g. [1, 0, 0, 3, 2] is for \(X_0Z_3Y_4\)
weight (Optional[Sequence[float]], optional) – 1D Tensor, each element corresponds the weight for each Pauli string defaults to None (all Pauli strings weight 1.0)
numpy (bool) – default False. If True, return numpy coo else return backend compatible sparse tensor
- Returns:
the scipy coo sparse matrix
- Return type:
Tensor
- tensorcircuit.quantum.PauliStringSum2COO_tf(ls: Sequence[Sequence[int]], weight: Sequence[float] | None = None) Any[source]¶
Generate tensorflow sparse matrix from Pauli string sum [deprecated]
- Parameters:
ls (Sequence[Sequence[int]]) – 2D Tensor, each row is for a Pauli string, e.g. [1, 0, 0, 3, 2] is for \(X_0Z_3Y_4\)
weight (Optional[Sequence[float]], optional) – 1D Tensor, each element corresponds the weight for each Pauli string defaults to None (all Pauli strings weight 1.0)
- Returns:
the tensorflow coo sparse matrix
- Return type:
Tensor
- tensorcircuit.quantum.PauliStringSum2Dense(ls: Sequence[Sequence[int]], weight: Sequence[float] | None = None, numpy: bool = False) Any[source]¶
Generate dense matrix from Pauli string sum. Currently requires tensorflow installed.
- Parameters:
ls (Sequence[Sequence[int]]) – 2D Tensor, each row is for a Pauli string, e.g. [1, 0, 0, 3, 2] is for \(X_0Z_3Y_4\)
weight (Optional[Sequence[float]], optional) – 1D Tensor, each element corresponds the weight for each Pauli string defaults to None (all Pauli strings weight 1.0)
numpy (bool) – default False. If True, return numpy coo else return backend compatible sparse tensor
- Returns:
the tensorflow dense matrix
- Return type:
Tensor
- tensorcircuit.quantum.PauliStringSum2MVP(structures: Sequence[Sequence[int]], weights: Sequence[float]) Callable[[Any], Any][source]¶
Generate a matrix-vector product function for a given Pauli string sum. The returned function mvp(psi) computes sum(w_i * P_i * psi). This implementation efficiently handles the operation by using backend-agnostic slicing (for X/Y flips) and broadcasting (for Z/Y phases), avoiding explicit matrix construction.
- Parameters:
structures (Sequence[Sequence[int]]) – List of Pauli strings, e.g. [[1, 0, 3], [0, 2, 0]] for X0 Z2 and Y1. (0: I, 1: X, 2: Y, 3: Z)
weights (Sequence[float]) – List of weights for each Pauli string.
- Returns:
MVP function taking wavefunction (shape [2**n] or [2]*n) and returning the same shape.
- Return type:
Callable[[Tensor], Tensor]
- class tensorcircuit.quantum.QuAdjointVector(subsystem_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None)[source]¶
Bases:
QuOperatorRepresents an adjoint (row) vector via a tensor network.
- __init__(subsystem_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None) None[source]¶
Constructs a new QuAdjointVector from a tensor network. This encapsulates an existing tensor network, interpreting it as an adjoint vector (row vector).
- Parameters:
subsystem_edges (Sequence[Edge]) – The edges of the network to be used as the input edges.
ref_nodes (Optional[Collection[AbstractNode]], optional) – Nodes used to refer to parts of the tensor network that are not connected to any input or output edges (for example: a scalar factor).
ignore_edges (Optional[Collection[Edge]], optional) – Optional collection of edges to ignore when performing consistency checks.
- adjoint() QuOperator¶
The adjoint of the operator. This creates a new QuOperator with complex-conjugate copies of all tensors in the network and with the input and output edges switched.
- Returns:
The adjoint of the operator.
- Return type:
- check_network() None¶
Check that the network has the expected dimensionality. This checks that all input and output edges are dangling and that there are no other dangling edges (except any specified in ignore_edges). If not, an exception is raised.
- contract(final_edge_order: Sequence[Edge] | None = None) QuOperator¶
Contract the tensor network in place. This modifies the tensor network representation of the operator (or vector, or scalar), reducing it to a single tensor, without changing the value.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor.
- Returns:
The present object.
- Return type:
- copy() QuOperator¶
The deep copy of the operator.
- Returns:
The new copy of the operator.
- Return type:
- eval(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor. Note that this modifies the tensor network representing the operator. The default ordering for the axes of the final tensor is: *out_edges, *in_edges. If there are any “ignored” edges, their axes come first: *ignored_edges, *out_edges, *in_edges.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The final tensor representing the operator.
- Return type:
Tensor
- eval_matrix(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor in two dimentional matrix. The default ordering for the axes of the final tensor is: (\(\prod\) dimension of out_edges, \(\prod\) dimension of in_edges)
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The two-dimentional tensor representing the operator.
- Return type:
Tensor
- classmethod from_local_tensor(tensor: Any, space: Sequence[int], loc: Sequence[int], out_axes: Sequence[int] | None = None, in_axes: Sequence[int] | None = None) QuOperator¶
- classmethod from_tensor(tensor: Any, subsystem_axes: Sequence[int] | None = None) QuAdjointVector[source]¶
Construct a QuAdjointVector directly from a single tensor. This first wraps the tensor in a Node, then constructs the QuAdjointVector from that Node.
- Example:
def show_attributes(op): print(f"op.is_scalar() \t\t-> {op.is_scalar()}") print(f"op.is_vector() \t\t-> {op.is_vector()}") print(f"op.is_adjoint_vector() \t-> {op.is_adjoint_vector()}") print(f"op.eval() \n{op.eval()}")
>>> psi_tensor = np.random.rand(2, 2) >>> psi_tensor array([[0.27260127, 0.91401091], [0.06490953, 0.38653646]]) >>> op = qu.QuAdjointVector.from_tensor(psi_tensor, [0, 1]) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> False op.is_adjoint_vector() -> True op.eval() [[0.27260127 0.91401091] [0.06490953 0.38653646]]
- Parameters:
tensor (Tensor) – The tensor for constructing an QuAdjointVector.
subsystem_axes (Optional[Sequence[int]], optional) – Sequence of integer indices specifying the order in which to interpret the axes as subsystems (input edges). If not specified, the axes are taken in ascending order.
- Returns:
The new constructed QuAdjointVector give from the given tensor.
- Return type:
- property in_space: List[int]¶
- is_adjoint_vector() bool¶
Returns a bool indicating if QuOperator is an adjoint vector. Examples can be found in the QuOperator.from_tensor.
- is_scalar() bool¶
Returns a bool indicating if QuOperator is a scalar. Examples can be found in the QuOperator.from_tensor.
- is_vector() bool¶
Returns a bool indicating if QuOperator is a vector. Examples can be found in the QuOperator.from_tensor.
- property nodes: List[AbstractNode]¶
All tensor-network nodes involved in the operator.
- norm() QuOperator¶
The norm of the operator. This is the 2-norm (also known as the Frobenius or Hilbert-Schmidt norm).
- property out_space: List[int]¶
- partial_trace(subsystems_to_trace_out: Collection[int]) QuOperator¶
The partial trace of the operator. Subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
A new QuOperator or QuScalar representing the result.
- Return type:
- projector() QuOperator[source]¶
The projector of the operator. The operator, as a linear operator, on the adjoint of the operator.
Set \(A\) is the operator in matrix form, then the projector of operator is defined as: \(A^\dagger A\)
- Returns:
The projector of the operator.
- Return type:
- reduced_density(subsystems_to_trace_out: Collection[int]) QuOperator[source]¶
The reduced density of the operator.
Set \(A\) is the matrix of the operator, then the reduced density is defined as:
\[\mathrm{Tr}_{subsystems}(A^\dagger A)\]Firstly, take the projector of the operator, then trace out the subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
The QuOperator of the reduced density of the operator with given subsystems.
- Return type:
- property space: List[int]¶
- property subsystem_edges: List[Edge]¶
- tensor_product(other: QuOperator) QuOperator¶
Tensor product with another operator. Given two operators A and B, produces a new operator AB representing \(A \otimes B\). The out_edges (in_edges) of AB is simply the concatenation of the out_edges (in_edges) of A.copy() with that of B.copy(): new_out_edges = [*out_edges_A_copy, *out_edges_B_copy] new_in_edges = [*in_edges_A_copy, *in_edges_B_copy]
- Example:
>>> psi = qu.QuVector.from_tensor(np.random.rand(2, 2)) >>> psi_psi = psi.tensor_product(psi) >>> len(psi_psi.subsystem_edges) 4 >>> float(psi_psi.norm().eval()) 2.9887872748523585 >>> psi.norm().eval() ** 2 2.9887872748523585
- Parameters:
other (QuOperator) – The other operator (B).
- Returns:
The result (AB).
- Return type:
- trace() QuOperator¶
The trace of the operator.
- class tensorcircuit.quantum.QuOperator(out_edges: Sequence[Edge], in_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None)[source]¶
Bases:
objectRepresents a linear operator via a tensor network. To interpret a tensor network as a linear operator, some of the dangling edges must be designated as out_edges (output edges) and the rest as in_edges (input edges). Considered as a matrix, the out_edges represent the row index and the in_edges represent the column index. The (right) action of the operator on another then consists of connecting the in_edges of the first operator to the out_edges of the second. Can be used to do simple linear algebra with tensor networks.
- __init__(out_edges: Sequence[Edge], in_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None) None[source]¶
Creates a new QuOperator from a tensor network. This encapsulates an existing tensor network, interpreting it as a linear operator. The network is checked for consistency: All dangling edges must either be in out_edges, in_edges, or ignore_edges.
- Parameters:
out_edges (Sequence[Edge]) – The edges of the network to be used as the output edges.
in_edges (Sequence[Edge]) – The edges of the network to be used as the input edges.
ref_nodes (Optional[Collection[AbstractNode]], optional) – Nodes used to refer to parts of the tensor network that are not connected to any input or output edges (for example: a scalar factor).
ignore_edges (Optional[Collection[Edge]], optional) – Optional collection of dangling edges to ignore when performing consistency checks.
- Raises:
ValueError – At least one reference node is required to specify a scalar. None provided!
- adjoint() QuOperator[source]¶
The adjoint of the operator. This creates a new QuOperator with complex-conjugate copies of all tensors in the network and with the input and output edges switched.
- Returns:
The adjoint of the operator.
- Return type:
- check_network() None[source]¶
Check that the network has the expected dimensionality. This checks that all input and output edges are dangling and that there are no other dangling edges (except any specified in ignore_edges). If not, an exception is raised.
- contract(final_edge_order: Sequence[Edge] | None = None) QuOperator[source]¶
Contract the tensor network in place. This modifies the tensor network representation of the operator (or vector, or scalar), reducing it to a single tensor, without changing the value.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor.
- Returns:
The present object.
- Return type:
- copy() QuOperator[source]¶
The deep copy of the operator.
- Returns:
The new copy of the operator.
- Return type:
- eval(final_edge_order: Sequence[Edge] | None = None) Any[source]¶
Contracts the tensor network in place and returns the final tensor. Note that this modifies the tensor network representing the operator. The default ordering for the axes of the final tensor is: *out_edges, *in_edges. If there are any “ignored” edges, their axes come first: *ignored_edges, *out_edges, *in_edges.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The final tensor representing the operator.
- Return type:
Tensor
- eval_matrix(final_edge_order: Sequence[Edge] | None = None) Any[source]¶
Contracts the tensor network in place and returns the final tensor in two dimentional matrix. The default ordering for the axes of the final tensor is: (\(\prod\) dimension of out_edges, \(\prod\) dimension of in_edges)
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The two-dimentional tensor representing the operator.
- Return type:
Tensor
- classmethod from_local_tensor(tensor: Any, space: Sequence[int], loc: Sequence[int], out_axes: Sequence[int] | None = None, in_axes: Sequence[int] | None = None) QuOperator[source]¶
- classmethod from_tensor(tensor: Any, out_axes: Sequence[int] | None = None, in_axes: Sequence[int] | None = None) QuOperator[source]¶
Construct a QuOperator directly from a single tensor. This first wraps the tensor in a Node, then constructs the QuOperator from that Node.
- Example:
def show_attributes(op): print(f"op.is_scalar() \t\t-> {op.is_scalar()}") print(f"op.is_vector() \t\t-> {op.is_vector()}") print(f"op.is_adjoint_vector() \t-> {op.is_adjoint_vector()}") print(f"op.eval() \n{op.eval()}")
>>> psi_tensor = np.random.rand(2, 2) >>> psi_tensor array([[0.27260127, 0.91401091], [0.06490953, 0.38653646]]) >>> op = qu.QuOperator.from_tensor(psi_tensor, out_axes=[0], in_axes=[1]) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> False op.is_adjoint_vector() -> False op.eval() [[0.27260127 0.91401091] [0.06490953 0.38653646]]
- Parameters:
tensor (Tensor) – The tensor.
out_axes (Optional[Sequence[int]], optional) – The axis indices of tensor to use as out_edges.
in_axes (Optional[Sequence[int]], optional) – The axis indices of tensor to use as in_edges.
- Returns:
The new operator.
- Return type:
- property in_space: List[int]¶
- is_adjoint_vector() bool[source]¶
Returns a bool indicating if QuOperator is an adjoint vector. Examples can be found in the QuOperator.from_tensor.
- is_scalar() bool[source]¶
Returns a bool indicating if QuOperator is a scalar. Examples can be found in the QuOperator.from_tensor.
- is_vector() bool[source]¶
Returns a bool indicating if QuOperator is a vector. Examples can be found in the QuOperator.from_tensor.
- property nodes: List[AbstractNode]¶
All tensor-network nodes involved in the operator.
- norm() QuOperator[source]¶
The norm of the operator. This is the 2-norm (also known as the Frobenius or Hilbert-Schmidt norm).
- property out_space: List[int]¶
- partial_trace(subsystems_to_trace_out: Collection[int]) QuOperator[source]¶
The partial trace of the operator. Subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
A new QuOperator or QuScalar representing the result.
- Return type:
- tensor_product(other: QuOperator) QuOperator[source]¶
Tensor product with another operator. Given two operators A and B, produces a new operator AB representing \(A \otimes B\). The out_edges (in_edges) of AB is simply the concatenation of the out_edges (in_edges) of A.copy() with that of B.copy(): new_out_edges = [*out_edges_A_copy, *out_edges_B_copy] new_in_edges = [*in_edges_A_copy, *in_edges_B_copy]
- Example:
>>> psi = qu.QuVector.from_tensor(np.random.rand(2, 2)) >>> psi_psi = psi.tensor_product(psi) >>> len(psi_psi.subsystem_edges) 4 >>> float(psi_psi.norm().eval()) 2.9887872748523585 >>> psi.norm().eval() ** 2 2.9887872748523585
- Parameters:
other (QuOperator) – The other operator (B).
- Returns:
The result (AB).
- Return type:
- trace() QuOperator[source]¶
The trace of the operator.
- class tensorcircuit.quantum.QuScalar(ref_nodes: Collection[AbstractNode], ignore_edges: Collection[Edge] | None = None)[source]¶
Bases:
QuOperatorRepresents a scalar via a tensor network.
- __init__(ref_nodes: Collection[AbstractNode], ignore_edges: Collection[Edge] | None = None) None[source]¶
Constructs a new QuScalar from a tensor network. This encapsulates an existing tensor network, interpreting it as a scalar.
- Parameters:
ref_nodes (Collection[AbstractNode]) – Nodes used to refer to the tensor network (need not be exhaustive - one node from each disconnected subnetwork is sufficient).
ignore_edges (Optional[Collection[Edge]], optional) – Optional collection of edges to ignore when performing consistency checks.
- adjoint() QuOperator¶
The adjoint of the operator. This creates a new QuOperator with complex-conjugate copies of all tensors in the network and with the input and output edges switched.
- Returns:
The adjoint of the operator.
- Return type:
- check_network() None¶
Check that the network has the expected dimensionality. This checks that all input and output edges are dangling and that there are no other dangling edges (except any specified in ignore_edges). If not, an exception is raised.
- contract(final_edge_order: Sequence[Edge] | None = None) QuOperator¶
Contract the tensor network in place. This modifies the tensor network representation of the operator (or vector, or scalar), reducing it to a single tensor, without changing the value.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor.
- Returns:
The present object.
- Return type:
- copy() QuOperator¶
The deep copy of the operator.
- Returns:
The new copy of the operator.
- Return type:
- eval(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor. Note that this modifies the tensor network representing the operator. The default ordering for the axes of the final tensor is: *out_edges, *in_edges. If there are any “ignored” edges, their axes come first: *ignored_edges, *out_edges, *in_edges.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The final tensor representing the operator.
- Return type:
Tensor
- eval_matrix(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor in two dimentional matrix. The default ordering for the axes of the final tensor is: (\(\prod\) dimension of out_edges, \(\prod\) dimension of in_edges)
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The two-dimentional tensor representing the operator.
- Return type:
Tensor
- classmethod from_local_tensor(tensor: Any, space: Sequence[int], loc: Sequence[int], out_axes: Sequence[int] | None = None, in_axes: Sequence[int] | None = None) QuOperator¶
- classmethod from_tensor(tensor: Any) QuScalar[source]¶
Construct a QuScalar directly from a single tensor. This first wraps the tensor in a Node, then constructs the QuScalar from that Node.
- Example:
def show_attributes(op): print(f"op.is_scalar() \t\t-> {op.is_scalar()}") print(f"op.is_vector() \t\t-> {op.is_vector()}") print(f"op.is_adjoint_vector() \t-> {op.is_adjoint_vector()}") print(f"op.eval() \n{op.eval()}")
>>> op = qu.QuScalar.from_tensor(1.0) >>> show_attributes(op) op.is_scalar() -> True op.is_vector() -> False op.is_adjoint_vector() -> False op.eval() 1.0
- Parameters:
tensor (Tensor) – The tensor for constructing a new QuScalar.
- Returns:
The new constructed QuScalar from the given tensor.
- Return type:
- property in_space: List[int]¶
- is_adjoint_vector() bool¶
Returns a bool indicating if QuOperator is an adjoint vector. Examples can be found in the QuOperator.from_tensor.
- is_scalar() bool¶
Returns a bool indicating if QuOperator is a scalar. Examples can be found in the QuOperator.from_tensor.
- is_vector() bool¶
Returns a bool indicating if QuOperator is a vector. Examples can be found in the QuOperator.from_tensor.
- property nodes: List[AbstractNode]¶
All tensor-network nodes involved in the operator.
- norm() QuOperator¶
The norm of the operator. This is the 2-norm (also known as the Frobenius or Hilbert-Schmidt norm).
- property out_space: List[int]¶
- partial_trace(subsystems_to_trace_out: Collection[int]) QuOperator¶
The partial trace of the operator. Subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
A new QuOperator or QuScalar representing the result.
- Return type:
- tensor_product(other: QuOperator) QuOperator¶
Tensor product with another operator. Given two operators A and B, produces a new operator AB representing \(A \otimes B\). The out_edges (in_edges) of AB is simply the concatenation of the out_edges (in_edges) of A.copy() with that of B.copy(): new_out_edges = [*out_edges_A_copy, *out_edges_B_copy] new_in_edges = [*in_edges_A_copy, *in_edges_B_copy]
- Example:
>>> psi = qu.QuVector.from_tensor(np.random.rand(2, 2)) >>> psi_psi = psi.tensor_product(psi) >>> len(psi_psi.subsystem_edges) 4 >>> float(psi_psi.norm().eval()) 2.9887872748523585 >>> psi.norm().eval() ** 2 2.9887872748523585
- Parameters:
other (QuOperator) – The other operator (B).
- Returns:
The result (AB).
- Return type:
- trace() QuOperator¶
The trace of the operator.
- class tensorcircuit.quantum.QuVector(subsystem_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None)[source]¶
Bases:
QuOperatorRepresents a (column) vector via a tensor network.
- __init__(subsystem_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None) None[source]¶
Constructs a new QuVector from a tensor network. This encapsulates an existing tensor network, interpreting it as a (column) vector.
- Parameters:
subsystem_edges (Sequence[Edge]) – The edges of the network to be used as the output edges.
ref_nodes (Optional[Collection[AbstractNode]], optional) – Nodes used to refer to parts of the tensor network that are not connected to any input or output edges (for example: a scalar factor).
ignore_edges (Optional[Collection[Edge]], optional) – Optional collection of edges to ignore when performing consistency checks.
- adjoint() QuOperator¶
The adjoint of the operator. This creates a new QuOperator with complex-conjugate copies of all tensors in the network and with the input and output edges switched.
- Returns:
The adjoint of the operator.
- Return type:
- check_network() None¶
Check that the network has the expected dimensionality. This checks that all input and output edges are dangling and that there are no other dangling edges (except any specified in ignore_edges). If not, an exception is raised.
- contract(final_edge_order: Sequence[Edge] | None = None) QuOperator¶
Contract the tensor network in place. This modifies the tensor network representation of the operator (or vector, or scalar), reducing it to a single tensor, without changing the value.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor.
- Returns:
The present object.
- Return type:
- copy() QuOperator¶
The deep copy of the operator.
- Returns:
The new copy of the operator.
- Return type:
- eval(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor. Note that this modifies the tensor network representing the operator. The default ordering for the axes of the final tensor is: *out_edges, *in_edges. If there are any “ignored” edges, their axes come first: *ignored_edges, *out_edges, *in_edges.
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The final tensor representing the operator.
- Return type:
Tensor
- eval_matrix(final_edge_order: Sequence[Edge] | None = None) Any¶
Contracts the tensor network in place and returns the final tensor in two dimentional matrix. The default ordering for the axes of the final tensor is: (\(\prod\) dimension of out_edges, \(\prod\) dimension of in_edges)
- Parameters:
final_edge_order (Optional[Sequence[Edge]], optional) – Manually specify the axis ordering of the final tensor. The default ordering is determined by out_edges and in_edges (see above).
- Raises:
ValueError – Node count ‘{}’ > 1 after contraction!
- Returns:
The two-dimentional tensor representing the operator.
- Return type:
Tensor
- classmethod from_local_tensor(tensor: Any, space: Sequence[int], loc: Sequence[int], out_axes: Sequence[int] | None = None, in_axes: Sequence[int] | None = None) QuOperator¶
- classmethod from_tensor(tensor: Any, subsystem_axes: Sequence[int] | None = None) QuVector[source]¶
Construct a QuVector directly from a single tensor. This first wraps the tensor in a Node, then constructs the QuVector from that Node.
- Example:
def show_attributes(op): print(f"op.is_scalar() \t\t-> {op.is_scalar()}") print(f"op.is_vector() \t\t-> {op.is_vector()}") print(f"op.is_adjoint_vector() \t-> {op.is_adjoint_vector()}") print(f"op.eval() \n{op.eval()}")
>>> psi_tensor = np.random.rand(2, 2) >>> psi_tensor array([[0.27260127, 0.91401091], [0.06490953, 0.38653646]]) >>> op = qu.QuVector.from_tensor(psi_tensor, [0, 1]) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> True op.is_adjoint_vector() -> False op.eval() [[0.27260127 0.91401091] [0.06490953 0.38653646]]
- Parameters:
tensor (Tensor) – The tensor for constructing a “QuVector”.
subsystem_axes (Optional[Sequence[int]], optional) – Sequence of integer indices specifying the order in which to interpret the axes as subsystems (output edges). If not specified, the axes are taken in ascending order.
- Returns:
The new constructed QuVector from the given tensor.
- Return type:
- property in_space: List[int]¶
- is_adjoint_vector() bool¶
Returns a bool indicating if QuOperator is an adjoint vector. Examples can be found in the QuOperator.from_tensor.
- is_scalar() bool¶
Returns a bool indicating if QuOperator is a scalar. Examples can be found in the QuOperator.from_tensor.
- is_vector() bool¶
Returns a bool indicating if QuOperator is a vector. Examples can be found in the QuOperator.from_tensor.
- property nodes: List[AbstractNode]¶
All tensor-network nodes involved in the operator.
- norm() QuOperator¶
The norm of the operator. This is the 2-norm (also known as the Frobenius or Hilbert-Schmidt norm).
- property out_space: List[int]¶
- partial_trace(subsystems_to_trace_out: Collection[int]) QuOperator¶
The partial trace of the operator. Subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
A new QuOperator or QuScalar representing the result.
- Return type:
- projector() QuOperator[source]¶
The projector of the operator. The operator, as a linear operator, on the adjoint of the operator.
Set \(A\) is the operator in matrix form, then the projector of operator is defined as: \(A A^\dagger\)
- Returns:
The projector of the operator.
- Return type:
- reduced_density(subsystems_to_trace_out: Collection[int]) QuOperator[source]¶
The reduced density of the operator.
Set \(A\) is the matrix of the operator, then the reduced density is defined as:
\[\mathrm{Tr}_{subsystems}(A A^\dagger)\]Firstly, take the projector of the operator, then trace out the subsystems to trace out are supplied as indices, so that dangling edges are connected to each other as: out_edges[i] ^ in_edges[i] for i in subsystems_to_trace_out This does not modify the original network. The original ordering of the remaining subsystems is maintained.
- Parameters:
subsystems_to_trace_out (Collection[int]) – Indices of subsystems to trace out.
- Returns:
The QuOperator of the reduced density of the operator with given subsystems.
- Return type:
- property space: List[int]¶
- property subsystem_edges: List[Edge]¶
- tensor_product(other: QuOperator) QuOperator¶
Tensor product with another operator. Given two operators A and B, produces a new operator AB representing \(A \otimes B\). The out_edges (in_edges) of AB is simply the concatenation of the out_edges (in_edges) of A.copy() with that of B.copy(): new_out_edges = [*out_edges_A_copy, *out_edges_B_copy] new_in_edges = [*in_edges_A_copy, *in_edges_B_copy]
- Example:
>>> psi = qu.QuVector.from_tensor(np.random.rand(2, 2)) >>> psi_psi = psi.tensor_product(psi) >>> len(psi_psi.subsystem_edges) 4 >>> float(psi_psi.norm().eval()) 2.9887872748523585 >>> psi.norm().eval() ** 2 2.9887872748523585
- Parameters:
other (QuOperator) – The other operator (B).
- Returns:
The result (AB).
- Return type:
- trace() QuOperator¶
The trace of the operator.
- tensorcircuit.quantum.check_spaces(edges_1: Sequence[Edge], edges_2: Sequence[Edge]) None[source]¶
Check the vector spaces represented by two lists of edges are compatible. The number of edges must be the same and the dimensions of each pair of edges must match. Otherwise, an exception is raised.
- Parameters:
edges_1 (Sequence[Edge]) – List of edges representing a many-body Hilbert space.
edges_2 (Sequence[Edge]) – List of edges representing a many-body Hilbert space.
- Raises:
ValueError – Hilbert-space mismatch: “Cannot connect {} subsystems with {} subsystems”, or “Input dimension {} != output dimension {}.”
- tensorcircuit.quantum.correlation_from_counts(index: Sequence[int], results: Any) Any[source]¶
Compute \(\prod_{i\in \\text{index}} s_i\), where the probability for each bitstring is given as a vector
results. Results is in the format of “count_vector”- Example:
>>> prob = tc.array_to_tensor(np.array([0.6, 0.4, 0, 0])) >>> qu.correlation_from_counts([0, 1], prob) (0.20000002+0j) >>> qu.correlation_from_counts([1], prob) (0.20000002+0j)
- Parameters:
index (Sequence[int]) – list of int, indicating the position in the bitstring
results (Tensor) – probability vector of shape 2^n
- Returns:
Correlation expectation from measurement shots.
- Return type:
Tensor
- tensorcircuit.quantum.correlation_from_samples(index: Sequence[int], results: Any, n: int) Any[source]¶
Compute \(\prod_{i\in \\text{index}} s_i (s=\pm 1)\), Results is in the format of “sample_int” or “sample_bin”
- Parameters:
index (Sequence[int]) – list of int, indicating the position in the bitstring
results (Tensor) – sample tensor
n (int) – number of qubits
- Returns:
Correlation expectation from measurement shots
- Return type:
Tensor
- tensorcircuit.quantum.count_d2s(drepr: Any, eps: float = 1e-07) Tuple[Any, Any][source]¶
measurement shots results, dense representation to sparse tuple representation non-jittable due to the non fixed return shape count_tuple to count_vector
- Example:
>>> tc.quantum.counts_d2s(np.array([0.1, 0, -0.3, 0.2])) (array([0, 2, 3]), array([ 0.1, -0.3, 0.2]))
- Parameters:
drepr (Tensor) – [description]
eps (float, optional) – cutoff to determine nonzero elements, defaults to 1e-7
- Returns:
[description]
- Return type:
Tuple[Tensor, Tensor]
- tensorcircuit.quantum.count_s2d(srepr: Tuple[Any, Any], n: int, dim: int | None = None) Any[source]¶
measurement shots results, sparse tuple representation to dense representation count_vector to count_tuple
- Parameters:
srepr (Tuple[Tensor, Tensor]) – [description]
n (int) – number of qubits
dim (int, optional) – [description], defaults to None
- Returns:
[description]
- Return type:
Tensor
- tensorcircuit.quantum.count_t2v(drepr: Any, eps: float = 1e-07) Tuple[Any, Any]¶
measurement shots results, dense representation to sparse tuple representation non-jittable due to the non fixed return shape count_tuple to count_vector
- Example:
>>> tc.quantum.counts_d2s(np.array([0.1, 0, -0.3, 0.2])) (array([0, 2, 3]), array([ 0.1, -0.3, 0.2]))
- Parameters:
drepr (Tensor) – [description]
eps (float, optional) – cutoff to determine nonzero elements, defaults to 1e-7
- Returns:
[description]
- Return type:
Tuple[Tensor, Tensor]
- tensorcircuit.quantum.count_tuple2dict(count: Tuple[Any, Any], n: int, key: str = 'bin', dim: int | None = None) Dict[Any, int][source]¶
count_tuple to count_dict_bin or count_dict_int
- Parameters:
count (Tuple[Tensor, Tensor]) – count_tuple format (indices, counts)
n (int) – number of sites (qubits or qudits)
key (str, optional) – can be “int” or “bin”, defaults to “bin”
dim (int, optional) – local dimension, defaults to 2
- Returns:
count_dict
- Return type:
Dict[Any, int]
- tensorcircuit.quantum.count_vector2dict(count: Any, n: int, key: str = 'bin', dim: int | None = None) Dict[Any, int][source]¶
Convert count_vector to count_dict_bin or count_dict_int. For d>10 cases, a base-d string (0-9A-Z) is used.
- Parameters:
count (Tensor) – tensor in shape [d**n]
n (int) – number of sites
key (str, optional) – can be “int” or “bin”, defaults to “bin”
dim (int, optional) – local dimension (default 2)
- Returns:
mapping from configuration to count
- Return type:
Dict[Any, int]
- tensorcircuit.quantum.counts_v2t(srepr: Tuple[Any, Any], n: int, dim: int | None = None) Any¶
measurement shots results, sparse tuple representation to dense representation count_vector to count_tuple
- Parameters:
srepr (Tuple[Tensor, Tensor]) – [description]
n (int) – number of qubits
dim (int, optional) – [description], defaults to None
- Returns:
[description]
- Return type:
Tensor
- tensorcircuit.quantum.double_state(h: Any, beta: float = 1) Any[source]¶
Compute the double state of the given Hamiltonian operator
h.- Parameters:
h (Tensor) – Hamiltonian operator in form of Tensor.
beta (float, optional) – Constant for the optimization, default is 1.
- Returns:
The double state of
hwith the givenbeta.- Return type:
Tensor
- tensorcircuit.quantum.eliminate_identities(nodes: Collection[AbstractNode]) Tuple[dict, dict][source]¶
Eliminates any connected CopyNodes that are identity matrices. This will modify the network represented by nodes. Only identities that are connected to other nodes are eliminated.
- Parameters:
nodes (Collection[AbstractNode]) – Collection of nodes to search.
- Returns:
The Dictionary mapping remaining Nodes to any replacements, Dictionary specifying all dangling-edge replacements.
- Return type:
Dict[Union[CopyNode, AbstractNode], Union[Node, AbstractNode]], Dict[Edge, Edge]
- tensorcircuit.quantum.entanglement_negativity(rho: Any, transposed_sites: List[int], dim: int | None = None) Any[source]¶
_summary_
- Parameters:
rho (Tensor) – _description_
transposed_sites (List[int]) – _description_
dim (int) – dimension of qudit system
- Returns:
_description_
- Return type:
Tensor
- tensorcircuit.quantum.entropy(rho: Any | QuOperator, eps: float | None = None) Any[source]¶
Compute the entropy from the given density matrix
rho.- Example:
@partial(tc.backend.jit, jit_compile=False, static_argnums=(1, 2)) def entanglement1(param, n, nlayers): c = tc.Circuit(n) c = tc.templates.blocks.example_block(c, param, nlayers) w = c.wavefunction() rm = qu.reduced_density_matrix(w, int(n / 2)) return qu.entropy(rm) @partial(tc.backend.jit, jit_compile=False, static_argnums=(1, 2)) def entanglement2(param, n, nlayers): c = tc.Circuit(n) c = tc.templates.blocks.example_block(c, param, nlayers) w = c.get_quvector() rm = w.reduced_density([i for i in range(int(n / 2))]) return qu.entropy(rm)
>>> param = tc.backend.ones([6, 6]) >>> tc.backend.trace(param) >>> entanglement1(param, 6, 3) 1.3132654 >>> entanglement2(param, 6, 3) 1.3132653
- Parameters:
rho (Union[Tensor, QuOperator]) – The density matrix in form of Tensor or QuOperator.
eps (float) – Epsilon, default is 1e-12.
- Returns:
Entropy on the given density matrix.
- Return type:
Tensor
- tensorcircuit.quantum.extract_tensors_from_qop(qop: QuOperator) Tuple[List[Node], bool, int][source]¶
Extract and sort tensors from QuOperator for conversion to other tensor network formats.
- Parameters:
qop (QuOperator) – Input QuOperator to extract tensors from
- Returns:
Tuple containing (sorted_nodes, is_mps, nwires) where:
sorted_nodes: List of Node objects sorted in linear chain order
is_mps: Boolean flag indicating if the structure is MPS (True) or MPO (False)
nwires: Integer number of physical edges/qubits in the system
- Return type:
Tuple[List[Node], bool, int]
- tensorcircuit.quantum.fidelity(rho: Any, rho0: Any) Any[source]¶
Return fidelity scalar between two states rho and rho0.
\[\operatorname{Tr}(\sqrt{\sqrt{rho} rho_0 \sqrt{rho}})\]- Parameters:
rho (Tensor) – The density matrix in form of Tensor.
rho0 (Tensor) – The density matrix in form of Tensor.
- Returns:
The sqrtm of a Hermitian matrix
a.- Return type:
Tensor
- tensorcircuit.quantum.free_energy(rho: Any | QuOperator, h: Any | QuOperator, beta: float = 1, eps: float = 1e-12) Any[source]¶
Compute the free energy of the given density matrix.
- Example:
>>> rho = np.array([[1.0, 0], [0, 0]]) >>> h = np.array([[-1.0, 0], [0, 1]]) >>> qu.free_energy(rho, h, 0.5) -0.9999999999979998 >>> hq = qu.QuOperator.from_tensor(h) >>> qu.free_energy(rho, hq, 0.5) array([[-1.]])
- Parameters:
rho (Union[Tensor, QuOperator]) – The density matrix in form of Tensor or QuOperator.
h (Union[Tensor, QuOperator]) – Hamiltonian operator in form of Tensor or QuOperator.
beta (float, optional) – Constant for the optimization, default is 1.
eps (float, optional) – Epsilon, default is 1e-12.
- Returns:
The free energy of the given density matrix with the Hamiltonian operator.
- Return type:
Tensor
- tensorcircuit.quantum.generate_local_hamiltonian(*hlist: Sequence[Any], matrix_form: bool = True) QuOperator | Any[source]¶
Generate a local Hamiltonian operator based on the given sequence of Tensor. Note: further jit is recommended. For large Hilbert space, sparse Hamiltonian is recommended
- Parameters:
hlist (Sequence[Tensor]) – A sequence of Tensor.
matrix_form (bool, optional) – Return Hamiltonian operator in form of matrix, defaults to True.
- Returns:
The Hamiltonian operator in form of QuOperator or matrix.
- Return type:
Union[QuOperator, Tensor]
- tensorcircuit.quantum.get_all_nodes(edges: Iterable[Edge]) List[Node][source]¶
Return the set of nodes connected to edges.
- tensorcircuit.quantum.gibbs_state(h: Any, beta: float = 1) Any[source]¶
Compute the Gibbs state of the given Hamiltonian operator
h.- Parameters:
h (Tensor) – Hamiltonian operator in form of Tensor.
beta (float, optional) – Constant for the optimization, default is 1.
- Returns:
The Gibbs state of
hwith the givenbeta.- Return type:
Tensor
- tensorcircuit.quantum.heisenberg_hamiltonian(g: Any, hzz: float = 1.0, hxx: float = 1.0, hyy: float = 1.0, hz: float = 0.0, hx: float = 0.0, hy: float = 0.0, sparse: bool = True, numpy: bool = False) Any[source]¶
Generate Heisenberg Hamiltonian with possible external fields. Currently requires tensorflow installed
- Example:
>>> g = tc.templates.graphs.Line1D(6) >>> h = qu.heisenberg_hamiltonian(g, sparse=False) >>> tc.backend.eigh(h)[0][:10] array([-11.2111025, -8.4721365, -8.472136 , -8.472136 , -6. , -5.123106 , -5.123106 , -5.1231055, -5.1231055, -5.1231055], dtype=float32)
- Parameters:
g (Graph) – input circuit graph
hzz (float) – zz coupling, default is 1.0
hxx (float) – xx coupling, default is 1.0
hyy (float) – yy coupling, default is 1.0
hz (float) – External field on z direction, default is 0.0
hx (float) – External field on y direction, default is 0.0
hy (float) – External field on x direction, default is 0.0
sparse (bool, defalts True) – Whether to return sparse Hamiltonian operator, default is True.
numpy (bool, defaults False,) – whether return the matrix in numpy or tensorflow form
- Returns:
Hamiltonian measurements
- Return type:
Tensor
- tensorcircuit.quantum.identity(space: Sequence[int], dtype: Any | None = None) QuOperator[source]¶
Construct a ‘QuOperator’ representing the identity on a given space. Internally, this is done by constructing ‘CopyNode’s for each edge, with dimension according to ‘space’.
- Example:
>>> E = qu.identity((2, 3, 4)) >>> float(E.trace().eval()) 24.0
>>> tensor = np.random.rand(2, 2) >>> psi = qu.QuVector.from_tensor(tensor) >>> E = qu.identity((2, 2)) >>> psi.eval() array([[0.03964233, 0.99298281], [0.38564989, 0.00950596]]) >>> (E @ psi).eval() array([[0.03964233, 0.99298281], [0.38564989, 0.00950596]]) >>> >>> (psi.adjoint() @ E @ psi).eval() array(1.13640257) >>> psi.norm().eval() array(1.13640257)
- Parameters:
space (Sequence[int]) – A sequence of integers for the dimensions of the tensor product factors of the space (the edges in the tensor network).
dtype (Any type) – The data type by np.* (for conversion to dense). defaults None to tc dtype.
- Returns:
The desired identity operator.
- Return type:
- tensorcircuit.quantum.log_negativity(rho: Any, transposed_sites: List[int], base: str = 'e', dim: int | None = None) Any[source]¶
_summary_
- Parameters:
rho (Tensor) – _description_
transposed_sites (List[int]) – _description_
base (str, optional) – whether use 2 based log or e based log, defaults to “e”
dim (int) – dimension of qudit system
- Returns:
_description_
- Return type:
Tensor
- tensorcircuit.quantum.measurement_counts(state: Any, counts: int | None = 8192, format: str = 'count_vector', is_prob: bool = False, random_generator: Any | None = None, status: Any | None = None, jittable: bool = False, dim: int | None = None) Any[source]¶
Simulate the measuring of each qubit of
pin the computational basis, thus producing output like that ofqiskit.Six formats of measurement counts results:
“sample_int”: # np.array([0, 0])
“sample_bin”: # [np.array([1, 0]), np.array([1, 0])]
“count_vector”: # np.array([2, 0, 0, 0])
“count_tuple”: # (np.array([0]), np.array([2]))
“count_dict_bin”: # {“00”: 2, “01”: 0, “10”: 0, “11”: 0} / for cases din [10, 36], “10” -> “A”, …, “35” -> “Z”
“count_dict_int”: # {0: 2, 1: 0, 2: 0, 3: 0}
- Example:
>>> n = 4 >>> w = tc.backend.ones([2**n]) >>> tc.quantum.measurement_results(w, counts=3, format="sample_bin", jittable=True) array([[0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 1, 1]]) >>> tc.quantum.measurement_results(w, counts=3, format="sample_int", jittable=True) array([ 7, 15, 11]) >>> tc.quantum.measurement_results(w, counts=3, format="count_vector", jittable=True) array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1]) >>> tc.quantum.measurement_results(w, counts=3, format="count_tuple") (array([1, 2, 8]), array([1, 1, 1])) >>> tc.quantum.measurement_results(w, counts=3, format="count_dict_bin") {'0001': 1, '0011': 1, '1101': 1} >>> tc.quantum.measurement_results(w, counts=3, format="count_dict_int") {3: 1, 6: 2}
- Parameters:
state (Tensor) – The quantum state, assumed to be normalized, as either a ket or density operator.
counts (int) – The number of counts to perform.
shots (int) – alias for the argument
countsformat (str) – defaults to be “direct”, see supported format above
format – alias for the argument
formatis_prob (bool) – if True, the state is directly regarded as a probability list, defaults to be False
random_generator (Optional[Any]) – random_generator, defaults to None
status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator
jittable (bool) – if True, jax backend try using a jittable count, defaults to False
- Returns:
The counts for each bit string measured.
- Return type:
Tuple[]
- tensorcircuit.quantum.measurement_results(state: Any, counts: int | None = 8192, format: str = 'count_vector', is_prob: bool = False, random_generator: Any | None = None, status: Any | None = None, jittable: bool = False, dim: int | None = None) Any¶
Simulate the measuring of each qubit of
pin the computational basis, thus producing output like that ofqiskit.Six formats of measurement counts results:
“sample_int”: # np.array([0, 0])
“sample_bin”: # [np.array([1, 0]), np.array([1, 0])]
“count_vector”: # np.array([2, 0, 0, 0])
“count_tuple”: # (np.array([0]), np.array([2]))
“count_dict_bin”: # {“00”: 2, “01”: 0, “10”: 0, “11”: 0} / for cases din [10, 36], “10” -> “A”, …, “35” -> “Z”
“count_dict_int”: # {0: 2, 1: 0, 2: 0, 3: 0}
- Example:
>>> n = 4 >>> w = tc.backend.ones([2**n]) >>> tc.quantum.measurement_results(w, counts=3, format="sample_bin", jittable=True) array([[0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 1, 1]]) >>> tc.quantum.measurement_results(w, counts=3, format="sample_int", jittable=True) array([ 7, 15, 11]) >>> tc.quantum.measurement_results(w, counts=3, format="count_vector", jittable=True) array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1]) >>> tc.quantum.measurement_results(w, counts=3, format="count_tuple") (array([1, 2, 8]), array([1, 1, 1])) >>> tc.quantum.measurement_results(w, counts=3, format="count_dict_bin") {'0001': 1, '0011': 1, '1101': 1} >>> tc.quantum.measurement_results(w, counts=3, format="count_dict_int") {3: 1, 6: 2}
- Parameters:
state (Tensor) – The quantum state, assumed to be normalized, as either a ket or density operator.
counts (int) – The number of counts to perform.
shots (int) – alias for the argument
countsformat (str) – defaults to be “direct”, see supported format above
format – alias for the argument
formatis_prob (bool) – if True, the state is directly regarded as a probability list, defaults to be False
random_generator (Optional[Any]) – random_generator, defaults to None
status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator
jittable (bool) – if True, jax backend try using a jittable count, defaults to False
- Returns:
The counts for each bit string measured.
- Return type:
Tuple[]
- tensorcircuit.quantum.mutual_information(s: Any, cut: int | List[int], dim: int | None = None) Any[source]¶
Mutual information between AB subsystem described by
cut.- Parameters:
s (Tensor) – The density matrix in form of Tensor.
cut (Union[int, List[int]]) – The AB subsystem.
dim (Tensor) – The diagonal matrix in form of Tensor.
- Returns:
The mutual information between AB subsystem described by
cut.- Return type:
Tensor
- tensorcircuit.quantum.onehot_d_tensor(_k: int | Any, d: int = 2) Any[source]¶
Construct a one-hot vector (or matrix) of local dimension
d.- Parameters:
_k (int or Tensor) – index or indices to set as 1. Can be an int or a backend Tensor.
d (int, optional) – local dimension (number of categories), defaults to 2
- Returns:
one-hot encoded vector (shape [d]) or matrix (shape [len(_k), d])
- Return type:
Tensor
- tensorcircuit.quantum.op2tensor(fn: Callable[[...], Any], op_argnums: int | Sequence[int] = 0) Callable[[...], Any][source]¶
- tensorcircuit.quantum.partial_transpose(rho: Any, transposed_sites: List[int], dim: int | None = None) Any[source]¶
_summary_
- Parameters:
rho (Tensor) – density matrix
transposed_sites (List[int]) – sites int list to be transposed
dim (int) – dimension of qudit system
- Returns:
_description_
- Return type:
Tensor
- tensorcircuit.quantum.ps2coo_core(idx_x: Any, idx_y: Any, idx_z: Any, weight: Any, nqubits: int) Tuple[Any, Any][source]¶
- tensorcircuit.quantum.ps2xyz(ps: List[int]) Dict[str, List[int]][source]¶
pauli string list to xyz dict
# ps2xyz([1, 2, 2, 0]) = {“x”: [0], “y”: [1, 2], “z”: []}
- Parameters:
ps (List[int]) – _description_
- Returns:
_description_
- Return type:
Dict[str, List[int]]
- tensorcircuit.quantum.qop2quimb(qop: QuOperator) Any[source]¶
Convert QuOperator to MPO or MPS in Quimb package.
Requirements: QuOperator must represent valid MPS/MPO structure: - Linear chain topology with open boundaries only - MPS: no input edges, consistent virtual bonds between adjacent tensors - MPO: equal input/output edges, rank-4 tensors - Edge connectivity: each internal node connected to exactly 2 neighbors - Cyclic boundary conditions NOT supported
- Parameters:
qop (QuOperator) – MPO in the form of QuOperator
- Returns:
MPO in the form of Quimb package
- Return type:
quimb.tensor.tensor_gen.MatrixProductOperator
- tensorcircuit.quantum.qop2tenpy(qop: QuOperator) Any[source]¶
Convert TensorCircuit QuOperator to MPO or MPS from TeNPy.
Requirements: QuOperator must represent valid MPS/MPO structure: - Linear chain topology with open boundaries only - MPS: no input edges, consistent virtual bonds, rank-3 or 4(with empty input edges) tensors - MPO: equal input/output edges, rank-4 tensors - Cyclic boundary conditions NOT supported
- Parameters:
qop (QuOperator) – The corresponding state/operator as a QuOperator.
- Returns:
MPO or MPS object from the TeNPy package.
- Return type:
Union[tenpy.networks.mpo.MPO, tenpy.networks.mps.MPS]
- tensorcircuit.quantum.qop2tn(qop: QuOperator) Any[source]¶
Convert QuOperator back to MPO or MPS in TensorNetwork package.
- Parameters:
qop – MPO or MPS in the form of QuOperator, param in docstring
- Returns:
MPO or MPS in the form of TensorNetwork
- Return type:
Union[tn.matrixproductstates.MPO, tn.matrixproductstates.MPS]
- tensorcircuit.quantum.quantum_constructor(out_edges: Sequence[Edge], in_edges: Sequence[Edge], ref_nodes: Collection[AbstractNode] | None = None, ignore_edges: Collection[Edge] | None = None) QuOperator[source]¶
Constructs an appropriately specialized QuOperator. If there are no edges, creates a QuScalar. If the are only output (input) edges, creates a QuVector (QuAdjointVector). Otherwise creates a QuOperator.
- Example:
def show_attributes(op): print(f"op.is_scalar() -> {op.is_scalar()}") print(f"op.is_vector() -> {op.is_vector()}") print(f"op.is_adjoint_vector() -> {op.is_adjoint_vector()}") print(f"len(op.out_edges) -> {len(op.out_edges)}") print(f"len(op.in_edges) -> {len(op.in_edges)}")
>>> psi_node = tn.Node(np.random.rand(2, 2)) >>> >>> op = qu.quantum_constructor([psi_node[0]], [psi_node[1]]) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> False op.is_adjoint_vector() -> False len(op.out_edges) -> 1 len(op.in_edges) -> 1 >>> # psi_node[0] -> op.out_edges[0] >>> # psi_node[1] -> op.in_edges[0]
>>> op = qu.quantum_constructor([psi_node[0], psi_node[1]], []) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> True op.is_adjoint_vector() -> False len(op.out_edges) -> 2 len(op.in_edges) -> 0 >>> # psi_node[0] -> op.out_edges[0] >>> # psi_node[1] -> op.out_edges[1]
>>> op = qu.quantum_constructor([], [psi_node[0], psi_node[1]]) >>> show_attributes(op) op.is_scalar() -> False op.is_vector() -> False op.is_adjoint_vector() -> True len(op.out_edges) -> 0 len(op.in_edges) -> 2 >>> # psi_node[0] -> op.in_edges[0] >>> # psi_node[1] -> op.in_edges[1]
- Parameters:
out_edges (Sequence[Edge]) – A list of output edges.
in_edges (Sequence[Edge]) – A list of input edges.
ref_nodes (Optional[Collection[AbstractNode]], optional) – Reference nodes for the tensor network (needed if there is a. scalar component).
ignore_edges (Optional[Collection[Edge]], optional) – Edges to ignore when checking the dimensionality of the tensor network.
- Returns:
The new created QuOperator object.
- Return type:
- tensorcircuit.quantum.quimb2qop(qb_mpo: Any) QuOperator[source]¶
Convert MPO in Quimb package to QuOperator.
- Parameters:
tn_mpo (
quimb.tensor.tensor_gen.*) – MPO in the form of Quimb package- Returns:
MPO in the form of QuOperator
- Return type:
- tensorcircuit.quantum.reachable(inputs: AbstractNode | Iterable[AbstractNode] | Edge | Iterable[Edge]) List[AbstractNode][source]¶
Computes all nodes reachable from node or edge.node1 by connected edges.
- Parameters:
inputs – A AbstractNode/Edge or collection of AbstractNodes/Edges
- Returns:
A list of AbstractNode objects that can be reached from node via connected edges.
- Raises:
TypeError – If inputs contains other then Edge or Node.
- tensorcircuit.quantum.reduced_density_matrix(state: Any | QuOperator, cut: int | List[int], p: Any | None = None, normalize: bool = True, dim: int | None = None) Any | QuOperator[source]¶
Compute the reduced density matrix from the quantum state
state.- Parameters:
state (Union[Tensor, QuOperator]) – The quantum state in form of Tensor or QuOperator.
cut (Union[int, List[int]]) – the index list that is traced out, if cut is a int, it indicates [0, cut] as the traced out region
p (Optional[Tensor]) – probability decoration, default is None.
normalize (bool) – if True, returns a trace 1 density matrix. Otherwise, does not normalize.
dim (int) – dimension of qudit system
- Returns:
The reduced density matrix.
- Return type:
Union[Tensor, QuOperator]
- tensorcircuit.quantum.reduced_wavefunction(state: Any, cut: List[int], measure: List[int] | None = None, dim: int | None = None) Any[source]¶
Compute the reduced wavefunction from the quantum state
state. The fixed measure result is guaranteed by users, otherwise final normalization may required in the return- Parameters:
state (Tensor) – _description_
cut (List[int]) – the list of position for qubit to be reduced
measure (List[int]) – the fixed results of given qubits in the same shape list as
cutdim (int) – dimension of qudit system
- Returns:
_description_
- Return type:
Tensor
- tensorcircuit.quantum.renyi_entropy(rho: Any | QuOperator, k: int = 2) Any[source]¶
Compute the Renyi entropy of order \(k\) by given density matrix.
- Parameters:
rho (Union[Tensor, QuOperator]) – The density matrix in form of Tensor or QuOperator.
k (int, optional) – The order of Renyi entropy, default is 2.
- Returns:
The \(k\) th order of Renyi entropy.
- Return type:
Tensor
- tensorcircuit.quantum.renyi_free_energy(rho: Any | QuOperator, h: Any | QuOperator, beta: float = 1, k: int = 2) Any[source]¶
Compute the Renyi free energy of the corresponding density matrix and Hamiltonian.
- Example:
>>> rho = np.array([[1.0, 0], [0, 0]]) >>> h = np.array([[-1.0, 0], [0, 1]]) >>> qu.renyi_free_energy(rho, h, 0.5) -1.0 >>> qu.free_energy(rho, h, 0.5) -0.9999999999979998
- Parameters:
rho (Union[Tensor, QuOperator]) – The density matrix in form of Tensor or QuOperator.
h (Union[Tensor, QuOperator]) – Hamiltonian operator in form of Tensor or QuOperator.
beta (float, optional) – Constant for the optimization, default is 1.
k (int, optional) – The order of Renyi entropy, default is 2.
- Returns:
The \(k\) th order of Renyi entropy.
- Return type:
Tensor
- tensorcircuit.quantum.sample2all(sample: Any, n: int, format: str = 'count_vector', jittable: bool = False, dim: int | None = None) Any[source]¶
transform
sample_intorsample_binresults to other forms specified byformat- Parameters:
sample (Tensor) – measurement shots results in
sample_int(shape [shots]) orsample_bin(shape [shots, n])n (int) – number of sites
format (str, optional) – see
tensorcircuit.quantum.measurement_results(), defaults to “count_vector”format – alias for the argument
formatjittable (bool, optional) – only applicable to count transformation in jax backend, defaults to False
dim (Optional[int]) – local dimension (2 for qubit; >2 for qudit), defaults to 2
- Returns:
measurement results specified as
format- Return type:
Any
- tensorcircuit.quantum.sample2count(sample: Any, n: int, jittable: bool = True, dim: int | None = None) Tuple[Any, Any][source]¶
sample_int to count_tuple (indices, counts), size = d**n
- Parameters:
sample (Tensor) – linear-index samples, shape [shots]
n (int) – number of sites
jittable (bool) – whether to return fixed-size outputs (backend dependent)
dim (int, optional) – local dimension per site, default 2 (qubit)
- Returns:
(unique_indices, counts)
- Return type:
Tuple[Tensor, Tensor]
- tensorcircuit.quantum.sample_bin2int(sample: Any, n: int, dim: int | None = None) Any[source]¶
bin sample to int sample
- Parameters:
sample (Tensor) – in shape [trials, n] of elements (0, 1)
n (int) – number of sites
dim (int, optional) – local dimension, defaults to 2
- Returns:
in shape [trials]
- Return type:
Tensor
- tensorcircuit.quantum.sample_int2bin(sample: Any, n: int, dim: int | None = None) Any[source]¶
Convert linear-index samples to per-site digits (base-d).
- Parameters:
sample (Tensor) – shape [trials], integers in [0, d**n)
n (int) – number of sites
dim (int, optional) – local dimension, defaults to 2
- Returns:
shape [trials, n], entries in [0, d-1]
- Return type:
Tensor
- tensorcircuit.quantum.spin_by_basis(n: int, m: int, elements: Tuple[int, int] = (1, -1)) Any[source]¶
Generate all n-bitstrings as an array, each row is a bitstring basis. Return m-th col.
- Example:
>>> qu.spin_by_basis(2, 1) array([ 1, -1, 1, -1])
- Parameters:
n (int) – length of a bitstring
m (int) – m<n,
elements (Tuple[int, int], optional) – the binary elements to generate, default is (1, -1).
- Returns:
The value for the m-th position in bitstring when going through all bitstring basis.
- Return type:
Tensor
- tensorcircuit.quantum.taylorlnm(x: Any, k: int) Any[source]¶
Taylor expansion of \(ln(x+1)\).
- Parameters:
x (Tensor) – The density matrix in form of Tensor.
k (int, optional) – The \(k\) th order, default is 2.
- Returns:
The \(k\) th order of Taylor expansion of \(ln(x+1)\).
- Return type:
Tensor
- tensorcircuit.quantum.tenpy2qop(tenpy_obj: Any) QuOperator[source]¶
Converts a TeNPy MPO or MPS to a TensorCircuit QuOperator. This definitive version correctly handles axis ordering and boundary conditions to be compatible with eval_matrix.
- Parameters:
tenpy_obj (Union[tenpy.networks.mpo.MPO, tenpy.networks.mps.MPS]) – A MPO or MPS object from the TeNPy package.
- Returns:
The corresponding state or operator as a QuOperator.
- Return type:
- tensorcircuit.quantum.tn2qop(tn_obj: Any) QuOperator[source]¶
Convert MPO in TensorNetwork package to QuOperator.
- Parameters:
tn_mpo (
tn.matrixproductstates.mpo.*) – MPO in the form of TensorNetwork package- Returns:
MPO in the form of QuOperator
- Return type:
- tensorcircuit.quantum.trace_distance(rho: Any, rho0: Any, eps: float = 1e-12) Any[source]¶
Compute the trace distance between two density matrix
rhoandrho2.- Parameters:
rho (Tensor) – The density matrix in form of Tensor.
rho0 (Tensor) – The density matrix in form of Tensor.
eps (float, optional) – Epsilon, defaults to 1e-12
- Returns:
The trace distance between two density matrix
rhoandrho2.- Return type:
Tensor
- tensorcircuit.quantum.trace_product(*o: Any | QuOperator) Any[source]¶
Compute the trace of several inputs
oas tensor orQuOperator.\[\operatorname{Tr}(\prod_i O_i)\]- Example:
>>> o = np.ones([2, 2]) >>> h = np.eye(2) >>> qu.trace_product(o, h) 2.0 >>> oq = qu.QuOperator.from_tensor(o) >>> hq = qu.QuOperator.from_tensor(h) >>> qu.trace_product(oq, hq) array([[2.]]) >>> qu.trace_product(oq, h) array([[2.]]) >>> qu.trace_product(o, hq) array([[2.]])
- Returns:
The trace of several inputs.
- Return type:
Tensor
- tensorcircuit.quantum.truncated_free_energy(rho: Any, h: Any, beta: float = 1, k: int = 2) Any[source]¶
Compute the truncated free energy from the given density matrix
rho.- Parameters:
rho (Tensor) – The density matrix in form of Tensor.
h (Tensor) – Hamiltonian operator in form of Tensor.
beta (float, optional) – Constant for the optimization, default is 1.
k (int, optional) – The \(k\) th order, defaults to 2
- Returns:
The \(k\) th order of the truncated free energy.
- Return type:
Tensor
- tensorcircuit.quantum.u1_enlarge(s: Any, n: int, m: int) Any[source]¶
Enlarge a state s in the subspace with m down spins in n sites to the full Hilbert space wavefunction of size 2**n
- Parameters:
s (Tensor) – input state of size C_n^m
n (int) – number of total sites
m (int) – number of down spins (1 in 0, 1)
- Returns:
enlarged state of size 2**n
- Return type:
Tensor
- tensorcircuit.quantum.u1_inds(n: int, m: int) Any[source]¶
Generate all the combination index of m down spins in n sites.
print(u1_inds(5, 1)) # [1, 2, 4, 8, 16]
- Parameters:
n (int) – number of total sites
m (int) – number of down spins (1 in 0, 1)
- Returns:
index tensor
- Return type:
Tensor
- tensorcircuit.quantum.u1_mask(n: int, m: int) Any[source]¶
Return the 1d array of size 2**n filled with zero, one only in elements corresponding to the m down spins
- Parameters:
n (int) – number of total sites
m (int) – number of down spins (1 in 0, 1)
- Returns:
_description_
- Return type:
Tensor
- tensorcircuit.quantum.u1_project(s: Any, n: int, m: int) Any[source]¶
Project a state s to the subspace with m down spins in n sites
- Parameters:
s (Tensor) – input state of size 2**n
n (int) – number of total sites
m (int) – number of down spins (1 in 0, 1)
- Returns:
projected state of size C_n^m
- Return type:
Tensor