tensorcircuit.gates#

Declarations of single-qubit and two-qubit gates and their corresponding matrix.

class tensorcircuit.gates.Gate(tensor: Union[Any, tensornetwork.network_components.AbstractNode], name: Optional[str] = None, axis_names: Optional[List[str]] = None, backend: Optional[Union[str, tensornetwork.backends.abstract_backend.AbstractBackend]] = None)[source]#

Bases: tensornetwork.network_components.Node

Wrapper of tn.Node, quantum gate

__init__(tensor: Union[Any, tensornetwork.network_components.AbstractNode], name: Optional[str] = None, axis_names: Optional[List[str]] = None, backend: Optional[Union[str, tensornetwork.backends.abstract_backend.AbstractBackend]] = None) β†’ None#

Create a node.

Parameters
  • tensor – The concrete that is represented by this node, or a AbstractNode object. If a tensor is passed, it can be be either a numpy array or the tensor-type of the used backend. If a AbstractNode is passed, the passed node has to have the same backend as given by backend.

  • name – Name of the node. Used primarily for debugging.

  • axis_names – List of names for each of the tensor’s axes.

  • backend – The name of the backend or an instance of a AbstractBackend.

Raises

ValueError – If there is a repeated name in axis_names or if the length doesn’t match the shape of the tensor.

add_axis_names(axis_names: List[str]) β†’ None#

Add axis names to a Node.

Parameters

axis_names – List of names for each of the tensor’s axes.

Raises

ValueError – If there is a repeated name in axis_names or if the length doesn’t match the shape of the tensor.

add_edge(edge: tensornetwork.network_components.Edge, axis: Union[int, str], override: bool = False) β†’ None#

Add an edge to the node on the given axis.

Parameters
  • edge – The edge to add.

  • axis – The axis the edge points to.

  • override – If true, replace the existing edge with the new one.

Raises

ValueError – If the edge on axis is not dangling.

property axis_names: List[str]#
copy(conjugate: bool = False) β†’ tensorcircuit.gates.Gate[source]#
disable() β†’ None#
property dtype#
property edges: List[tensornetwork.network_components.Edge]#
fresh_edges(axis_names: Optional[List[str]] = None) β†’ None#
classmethod from_serial_dict(serial_dict) β†’ tensornetwork.network_components.Node#

Return a node given a serialized dict representing it.

Parameters

serial_dict – A python dict representing a serialized node.

Returns

A node.

get_all_dangling() β†’ List[tensornetwork.network_components.Edge]#

Return the set of dangling edges connected to this node.

get_all_edges() β†’ List[tensornetwork.network_components.Edge]#
get_all_nondangling() β†’ Set[tensornetwork.network_components.Edge]#

Return the set of nondangling edges connected to this node.

get_axis_number(axis: Union[str, int]) β†’ int#

Get the axis number for a given axis name or value.

get_dimension(axis: Union[str, int]) β†’ Optional[int]#

Get the dimension of the given axis.

Parameters

axis – The axis of the underlying tensor.

Returns

The dimension of the given axis.

Raises

ValueError – if axis isn’t an int or if axis is too large or small.

get_edge(axis: Union[int, str]) β†’ tensornetwork.network_components.Edge#
get_rank() β†’ int#

Return rank of tensor represented by self.

get_tensor() β†’ Any#
has_dangling_edge() β†’ bool#
has_nondangling_edge() β†’ bool#
property name: str#
op_protection(other: Union[int, float, complex, tensornetwork.network_components.Node]) β†’ Any#
reorder_axes(perm: List[int]) β†’ tensornetwork.network_components.AbstractNode#

Reorder axes of the node’s tensor.

This will also update all of the node’s edges.

Parameters

perm – Permutation of the dimensions of the node’s tensor.

Returns

This node post reordering.

Raises

AttributeError – If the Node has no tensor.

reorder_edges(edge_order: List[tensornetwork.network_components.Edge]) β†’ tensornetwork.network_components.AbstractNode#

Reorder the edges for this given Node.

This will reorder the node’s edges and transpose the underlying tensor accordingly.

Parameters

edge_order – List of edges. The order in the list determines the new edge ordering.

Returns

This node post reordering.

Raises
  • ValueError – If either the list of edges is not the same as expected or if you try to reorder with a trace edge.

  • AttributeError – If the Node has no tensor.

set_name(name) β†’ None#
set_tensor(tensor) β†’ None#
property shape: Tuple[Optional[int], ...]#
property sparse_shape: Any#
property tensor: Any#
tensor_from_edge_order(perm: List[tensornetwork.network_components.Edge]) β†’ tensornetwork.network_components.AbstractNode#
to_serial_dict() β†’ Dict#

Return a serializable dict representing the node.

Returns: A dict object.

class tensorcircuit.gates.GateF(m: Any, n: Optional[str] = None, ctrl: Optional[List[int]] = None)[source]#

Bases: object

__init__(m: Any, n: Optional[str] = None, ctrl: Optional[List[int]] = None)[source]#
adjoint() β†’ tensorcircuit.gates.GateF[source]#
controlled() β†’ tensorcircuit.gates.GateF[source]#
ided(before: bool = True) β†’ tensorcircuit.gates.GateF[source]#
ocontrolled() β†’ tensorcircuit.gates.GateF[source]#
class tensorcircuit.gates.GateVF(f: Callable[[...], tensorcircuit.gates.Gate], n: Optional[str] = None, ctrl: Optional[List[int]] = None)[source]#

Bases: tensorcircuit.gates.GateF

__init__(f: Callable[[...], tensorcircuit.gates.Gate], n: Optional[str] = None, ctrl: Optional[List[int]] = None)[source]#
adjoint() β†’ tensorcircuit.gates.GateVF[source]#
controlled() β†’ tensorcircuit.gates.GateF#
ided(before: bool = True) β†’ tensorcircuit.gates.GateF#
ocontrolled() β†’ tensorcircuit.gates.GateF#
tensorcircuit.gates.any_gate(unitary: Any, name: str = 'any') β†’ tensorcircuit.gates.Gate[source]#

Note one should provide the gate with properly reshaped.

Parameters
  • unitary (Tensor) – corresponding gate

  • name (str) – The name of the gate.

Returns

the resulted gate

Return type

Gate

tensorcircuit.gates.array_to_tensor(*num: Union[float, Any], dtype: Optional[str] = None) β†’ Any#

Convert the inputs to Tensor with specified dtype.

Example

>>> from tensorcircuit.gates import num_to_tensor
>>> # OR
>>> from tensorcircuit.gates import array_to_tensor
>>>
>>> x, y, z = 0, 0.1, np.array([1])
>>>
>>> tc.set_backend('numpy')
numpy_backend
>>> num_to_tensor(x, y, z)
[array(0.+0.j, dtype=complex64), array(0.1+0.j, dtype=complex64), array([1.+0.j], dtype=complex64)]
>>>
>>> tc.set_backend('tensorflow')
tensorflow_backend
>>> num_to_tensor(x, y, z)
[<tf.Tensor: shape=(), dtype=complex64, numpy=0j>,
 <tf.Tensor: shape=(), dtype=complex64, numpy=(0.1+0j)>,
 <tf.Tensor: shape=(1,), dtype=complex64, numpy=array([1.+0.j], dtype=complex64)>]
>>>
>>> tc.set_backend('pytorch')
pytorch_backend
>>> num_to_tensor(x, y, z)
[tensor(0.+0.j), tensor(0.1000+0.j), tensor([1.+0.j])]
>>>
>>> tc.set_backend('jax')
jax_backend
>>> num_to_tensor(x, y, z)
[DeviceArray(0.+0.j, dtype=complex64),
 DeviceArray(0.1+0.j, dtype=complex64),
 DeviceArray([1.+0.j], dtype=complex64)]
Parameters
  • num (Union[float, Tensor]) – inputs

  • dtype (str, optional) – dtype of the output Tensors

Returns

List of Tensors

Return type

List[Tensor]

tensorcircuit.gates.bmatrix(a: Any) β†’ str[source]#

Returns a \(\LaTeX\) bmatrix.

Example

>>> gate = tc.gates.r_gate()
>>> array = tc.gates.matrix_for_gate(gate)
>>> array
array([[1.+0.j, 0.+0.j],
    [0.+0.j, 1.+0.j]], dtype=complex64)
>>> print(tc.gates.bmatrix(array))
\begin{bmatrix}    1.+0.j & 0.+0.j\\    0.+0.j & 1.+0.j \end{bmatrix}

Formatted Display:

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]
Parameters

a (np.array) – 2D numpy array

Raises

ValueError – ValueError(β€œbmatrix can at most display two dimensions”)

Returns

\(\LaTeX\)-formatted string for bmatrix of the array a

Return type

str

tensorcircuit.gates.cr_gate(theta: float = 0, alpha: float = 0, phi: float = 0) β†’ tensorcircuit.gates.Gate[source]#

Controlled rotation gate. When the control qubit is 1, rgate is applied to the target qubit.

Parameters
  • theta (float, optional) – angle in radians

  • alpha (float, optional) – angle in radians

  • phi (float, optional) – angle in radians

Returns

CR Gate

Return type

Gate

tensorcircuit.gates.exp1_gate(unitary: Any, theta: float, half: bool = False, name: str = 'none') β†’ tensorcircuit.gates.Gate#

Faster exponential gate directly implemented based on RHS. Only works when \(U^2 = I\) is an identity matrix.

\[\begin{split}\textrm{exp}(U) &= e^{-j \theta U} \\ &= \cos(\theta) I - j \sin(\theta) U \\\end{split}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • half (bool) – if True, the angel theta is mutiplied by 1/2, defaults to False

  • name (str, optional) – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.exp_gate(unitary: Any, theta: float, name: str = 'none') β†’ tensorcircuit.gates.Gate#

Exponential gate.

\[\textrm{exp}(U) = e^{-j \theta U}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • name – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.exponential_gate(unitary: Any, theta: float, name: str = 'none') β†’ tensorcircuit.gates.Gate[source]#

Exponential gate.

\[\textrm{exp}(U) = e^{-j \theta U}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • name – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.exponential_gate_unity(unitary: Any, theta: float, half: bool = False, name: str = 'none') β†’ tensorcircuit.gates.Gate[source]#

Faster exponential gate directly implemented based on RHS. Only works when \(U^2 = I\) is an identity matrix.

\[\begin{split}\textrm{exp}(U) &= e^{-j \theta U} \\ &= \cos(\theta) I - j \sin(\theta) U \\\end{split}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • half (bool) – if True, the angel theta is mutiplied by 1/2, defaults to False

  • name (str, optional) – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.gate_wrapper(m: Any, n: Optional[str] = None) β†’ tensorcircuit.gates.Gate[source]#
tensorcircuit.gates.get_u_parameter(m: Any) β†’ Tuple[float, float, float][source]#

From the single qubit unitary to infer three angles of IBMUgate,

Parameters

m (Tensor) – numpy array, no backend agnostic version for now

Returns

theta, phi, lbd

Return type

Tuple[Tensor, Tensor, Tensor]

tensorcircuit.gates.iswap_gate(theta: float = 1.0) β†’ tensorcircuit.gates.Gate[source]#

iSwap gate.

\[\begin{split}\textrm{iSwap}(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & \cos(\frac{\pi}{2} \theta ) & j \sin(\frac{\pi}{2} \theta ) & 0\\ 0 & j \sin(\frac{\pi}{2} \theta ) & \cos(\frac{\pi}{2} \theta ) & 0\\ 0 & 0 & 0 & 1\\ \end{pmatrix}\end{split}\]
Parameters

theta (float) – angle in radians

Returns

iSwap Gate

Return type

Gate

tensorcircuit.gates.matrix_for_gate(gate: tensorcircuit.gates.Gate, tol: float = 1e-06) β†’ Any[source]#

Convert Gate to numpy array.

Example

>>> gate = tc.gates.r_gate()
>>> tc.gates.matrix_for_gate(gate)
    array([[1.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j]], dtype=complex64)
Parameters

gate (Gate) – input Gate

Returns

Corresponding Tensor

Return type

Tensor

tensorcircuit.gates.meta_gate() β†’ None[source]#

Inner helper function to generate gate functions, such as z() from _z_matrix

tensorcircuit.gates.meta_vgate() β†’ None[source]#
tensorcircuit.gates.mpo_gate(mpo: Any, name: str = 'mpo') β†’ Any[source]#
tensorcircuit.gates.multicontrol_gate(unitary: Any, ctrl: Union[int, Sequence[int]] = 1) β†’ Any[source]#

Multicontrol gate. If the control qubits equal to ctrl, \(U\) is applied to the target qubits.

E.g., multicontrol_gate(tc.gates._zz_matrix, [1, 0, 1]) returns a gate of 5 qubits,

where the last 2 qubits are applied \(ZZ\) gate, if the first 3 qubits are \(\ket{101}\).

Parameters
  • unitary (Tensor) – input unitary \(U\)

  • ctrl (Union[int, Sequence[int]]) – control bit sequence

Returns

Multicontrol Gate

Return type

Operator

tensorcircuit.gates.num_to_tensor(*num: Union[float, Any], dtype: Optional[str] = None) β†’ Any[source]#

Convert the inputs to Tensor with specified dtype.

Example

>>> from tensorcircuit.gates import num_to_tensor
>>> # OR
>>> from tensorcircuit.gates import array_to_tensor
>>>
>>> x, y, z = 0, 0.1, np.array([1])
>>>
>>> tc.set_backend('numpy')
numpy_backend
>>> num_to_tensor(x, y, z)
[array(0.+0.j, dtype=complex64), array(0.1+0.j, dtype=complex64), array([1.+0.j], dtype=complex64)]
>>>
>>> tc.set_backend('tensorflow')
tensorflow_backend
>>> num_to_tensor(x, y, z)
[<tf.Tensor: shape=(), dtype=complex64, numpy=0j>,
 <tf.Tensor: shape=(), dtype=complex64, numpy=(0.1+0j)>,
 <tf.Tensor: shape=(1,), dtype=complex64, numpy=array([1.+0.j], dtype=complex64)>]
>>>
>>> tc.set_backend('pytorch')
pytorch_backend
>>> num_to_tensor(x, y, z)
[tensor(0.+0.j), tensor(0.1000+0.j), tensor([1.+0.j])]
>>>
>>> tc.set_backend('jax')
jax_backend
>>> num_to_tensor(x, y, z)
[DeviceArray(0.+0.j, dtype=complex64),
 DeviceArray(0.1+0.j, dtype=complex64),
 DeviceArray([1.+0.j], dtype=complex64)]
Parameters
  • num (Union[float, Tensor]) – inputs

  • dtype (str, optional) – dtype of the output Tensors

Returns

List of Tensors

Return type

List[Tensor]

tensorcircuit.gates.phase_gate(theta: float = 0) β†’ tensorcircuit.gates.Gate[source]#

The phase gate

\[\begin{split}\textrm{phase}(\theta) = \begin{pmatrix} 1 & 0 \\ 0 & e^{i\theta} \\ \end{pmatrix}\end{split}\]
Parameters

theta (float, optional) – angle in radians, defaults to 0

Returns

phase gate

Return type

Gate

tensorcircuit.gates.r_gate(theta: float = 0, alpha: float = 0, phi: float = 0) β†’ tensorcircuit.gates.Gate[source]#

General single qubit rotation gate

\[R(\theta, \alpha, \phi) = \cos(\theta) I - j \cos(\phi) \sin(\alpha) \sin(\theta) X - j \sin(\phi) \sin(\alpha) \sin(\theta) Y - j \sin(\theta) \cos(\alpha) Z\]
Parameters
  • theta (float, optional) – angle in radians

  • alpha (float, optional) – angle in radians

  • phi (float, optional) – angle in radians

Returns

R Gate

Return type

Gate

tensorcircuit.gates.random_single_qubit_gate() β†’ tensorcircuit.gates.Gate[source]#

Random single qubit gate described in https://arxiv.org/abs/2002.07730.

Returns

A random single-qubit gate

Return type

Gate

tensorcircuit.gates.random_two_qubit_gate() β†’ tensorcircuit.gates.Gate[source]#

Returns a random two-qubit gate.

Returns

A random two-qubit gate

Return type

Gate

tensorcircuit.gates.rgate_theoretical(theta: float = 0, alpha: float = 0, phi: float = 0) β†’ tensorcircuit.gates.Gate[source]#

Rotation gate implemented by matrix exponential. The output is the same as rgate.

\[R(\theta, \alpha, \phi) = e^{-j \theta \left[\sin(\alpha) \cos(\phi) X + \sin(\alpha) \sin(\phi) Y + \cos(\alpha) Z\right]}\]
Parameters
  • theta (float, optional) – angle in radians

  • alpha (float, optional) – angle in radians

  • phi (float, optional) – angle in radians

Returns

Rotation Gate

Return type

Gate

tensorcircuit.gates.rx_gate(theta: float = 0) β†’ tensorcircuit.gates.Gate[source]#

Rotation gate along \(x\) axis.

\[RX(\theta) = e^{-j\frac{\theta}{2}X}\]
Parameters

theta (float, optional) – angle in radians

Returns

RX Gate

Return type

Gate

tensorcircuit.gates.rxx_gate(*, unitary: Any = array([[0., 0., 0., 1.], [0., 0., 1., 0.], [0., 1., 0., 0.], [1., 0., 0., 0.]]), theta: float, half: bool = True, name: str = 'none') β†’ tensorcircuit.gates.Gate#

Faster exponential gate directly implemented based on RHS. Only works when \(U^2 = I\) is an identity matrix.

\[\begin{split}\textrm{exp}(U) &= e^{-j \theta U} \\ &= \cos(\theta) I - j \sin(\theta) U \\\end{split}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • half (bool) – if True, the angel theta is mutiplied by 1/2, defaults to False

  • name (str, optional) – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.ry_gate(theta: float = 0) β†’ tensorcircuit.gates.Gate[source]#

Rotation gate along \(y\) axis.

\[RY(\theta) = e^{-j\frac{\theta}{2}Y}\]
Parameters

theta (float, optional) – angle in radians

Returns

RY Gate

Return type

Gate

tensorcircuit.gates.ryy_gate(*, unitary: Any = array([[0. + 0.j, 0. - 0.j, 0. - 0.j, - 1. + 0.j], [0. + 0.j, 0. + 0.j, 1. - 0.j, 0. - 0.j], [0. + 0.j, 1. - 0.j, 0. + 0.j, 0. - 0.j], [- 1. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j]]), theta: float, half: bool = True, name: str = 'none') β†’ tensorcircuit.gates.Gate#

Faster exponential gate directly implemented based on RHS. Only works when \(U^2 = I\) is an identity matrix.

\[\begin{split}\textrm{exp}(U) &= e^{-j \theta U} \\ &= \cos(\theta) I - j \sin(\theta) U \\\end{split}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • half (bool) – if True, the angel theta is mutiplied by 1/2, defaults to False

  • name (str, optional) – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.rz_gate(theta: float = 0) β†’ tensorcircuit.gates.Gate[source]#

Rotation gate along \(z\) axis.

\[RZ(\theta) = e^{-j\frac{\theta}{2}Z}\]
Parameters

theta (float, optional) – angle in radians

Returns

RZ Gate

Return type

Gate

tensorcircuit.gates.rzz_gate(*, unitary: Any = array([[1., 0., 0., 0.], [0., - 1., 0., - 0.], [0., 0., - 1., - 0.], [0., - 0., - 0., 1.]]), theta: float, half: bool = True, name: str = 'none') β†’ tensorcircuit.gates.Gate#

Faster exponential gate directly implemented based on RHS. Only works when \(U^2 = I\) is an identity matrix.

\[\begin{split}\textrm{exp}(U) &= e^{-j \theta U} \\ &= \cos(\theta) I - j \sin(\theta) U \\\end{split}\]
Parameters
  • unitary (Tensor) – input unitary \(U\)

  • hermitian (Tensor) – alias for the argument unitary

  • hamiltonian (Tensor) – alias for the argument unitary

  • theta (float) – angle in radians

  • half (bool) – if True, the angel theta is mutiplied by 1/2, defaults to False

  • name (str, optional) – suffix of Gate name

Returns

Exponential Gate

Return type

Gate

tensorcircuit.gates.u_gate(theta: float = 0, phi: float = 0, lbd: float = 0) β†’ tensorcircuit.gates.Gate[source]#

IBMQ U gate following the converntion of OpenQASM3.0. See OpenQASM doc

\[\begin{split}\begin{split}U(\theta,\phi,\lambda) := \left(\begin{array}{cc} \cos(\theta/2) & -e^{i\lambda}\sin(\theta/2) \\ e^{i\phi}\sin(\theta/2) & e^{i(\phi+\lambda)}\cos(\theta/2) \end{array}\right).\end{split}\end{split}\]
Parameters
  • theta (float, optional) – _description_, defaults to 0

  • phi (float, optional) – _description_, defaults to 0

  • lbd (float, optional) – _description_, defaults to 0

Returns

_description_

Return type

Gate