paddle_quantum.mbqc.utils

This module contains various common classes and functions used for computation.

paddle_quantum.mbqc.utils.plus_state()

Define plus state.

The matrix form is:

\[\begin{split}\frac{1}{\sqrt{2}} \begin{bmatrix} 1 \\ 1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of plus state.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import plus_state
print("State vector of plus state: \n", plus_state().numpy())
State vector of plus state:
 [[0.70710678]
 [0.70710678]]
paddle_quantum.mbqc.utils.minus_state()

Define minus state.

The matrix form is:

\[\begin{split}\frac{1}{\sqrt{2}} \begin{bmatrix} 1 \\ -1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of minus state.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import minus_state
print("State vector of minus state: \n", minus_state().numpy())
State vector of minus state:
 [[ 0.70710678]
 [-0.70710678]]
paddle_quantum.mbqc.utils.zero_state()

Define zero state.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 \\ 0 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of zero state.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import zero_state
print("State vector of zero state: \n", zero_state().numpy())
State vector of zero state:
 [[1.]
 [0.]]
paddle_quantum.mbqc.utils.one_state()

Define one state.

The matrix form is:

\[\begin{split}\begin{bmatrix} 0 \\ 1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of one state.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import one_state
print("State vector of one state: \n", one_state().numpy())
State vector of one state:
 [[0.]
 [1.]]
paddle_quantum.mbqc.utils.h_gate()

Define Hadamard gate.

The matrix form is:

\[\begin{split}\frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of Hadamard gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import h_gate
print("Matrix of Hadamard gate: \n", h_gate().numpy())
Matrix of Hadamard gate:
 [[ 0.70710678  0.70710678]
 [ 0.70710678 -0.70710678]]
paddle_quantum.mbqc.utils.s_gate()

Define S gate.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 & 0 \\ 0 & i \end{bmatrix}\end{split}\]
Returns:

S 门矩阵对应的 Tensor 形式

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import s_gate
print("Matrix of S gate:\n", s_gate().numpy())
Matrix of S gate:
 [[1.+0.j 0.+0.j]
 [0.+0.j 0.+1.j]]
paddle_quantum.mbqc.utils.t_gate()

Define T gate.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 & 0 \\ 0 & e^{i \pi / 4} \end{bmatrix}\end{split}\]
Returns:

The Tensor form of T gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import t_gate
print("Matrix of T gate: \n", t_gate().numpy())
Matrix of T gate:
 [[1.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.70710678+0.70710678j]]
paddle_quantum.mbqc.utils.cz_gate()

Define Controlled-Z gate.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of Controlled-Z gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import cz_gate
print("Matrix of CZ gate: \n", cz_gate().numpy())
Matrix of CZ gate:
 [[ 1.  0.  0.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  0. -1.]]
paddle_quantum.mbqc.utils.cnot_gate()

Define Controlled-NOT (CNOT) gate.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of Controlled-NOT (CNOT) gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import cnot_gate
print("Matrix of CNOT gate: \n", cnot_gate().numpy())
Matrix of CNOT gate:
 [[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 0. 1.]
 [0. 0. 1. 0.]]
paddle_quantum.mbqc.utils.swap_gate()

Define SWAP gate.

The matrix form is:

\[\begin{split}\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\end{split}\]
Returns:

The Tensor form of SWAP gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import swap_gate
print("Matrix of Swap gate: \n", swap_gate().numpy())
Matrix of Swap gate:
 [[1. 0. 0. 0.]
 [0. 0. 1. 0.]
 [0. 1. 0. 0.]
 [0. 0. 0. 1.]]
paddle_quantum.mbqc.utils.pauli_gate(gate)

Define Pauli gate.

The matrix form of Identity gate I is:

\[\begin{split}\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}\end{split}\]

The matrix form of Pauli gate X is:

\[\begin{split}\begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\end{split}\]

The matrix form of Pauli gate Y is:

\[\begin{split}\begin{bmatrix} 0 & - i \\ i & 0 \end{bmatrix}\end{split}\]

The matrix form of Pauli gate Z is:

\[\begin{split}\begin{bmatrix} 1 & 0 \\ 0 & - 1 \end{bmatrix}\end{split}\]
Parameters:

gate (str) – Index of Pauli gate. “I”, “X”, “Y”, or “Z” denotes the corresponding gate.

Returns:

The matrix form of the Pauli gate.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import pauli_gate
I = pauli_gate('I')
X = pauli_gate('X')
Y = pauli_gate('Y')
Z = pauli_gate('Z')
print("Matrix of Identity gate: \n", I.numpy())
print("Matrix of Pauli X gate: \n", X.numpy())
print("Matrix of Pauli Y gate: \n", Y.numpy())
print("Matrix of Pauli Z gate: \n", Z.numpy())
Matrix of Identity gate:
 [[1. 0.]
 [0. 1.]]
Matrix of Pauli X gate:
 [[0. 1.]
 [1. 0.]]
Matrix of Pauli Y gate:
 [[ 0.+0.j -0.-1.j]
 [ 0.+1.j  0.+0.j]]
Matrix of Pauli Z gate:
 [[ 1.  0.]
 [ 0. -1.]]
paddle_quantum.mbqc.utils.rotation_gate(axis, theta)

Define Rotation gate.

\[ \begin{align}\begin{aligned}R_{x}(\theta) = \cos(\theta / 2) I - i\sin(\theta / 2) X\\R_{y}(\theta) = \cos(\theta / 2) I - i\sin(\theta / 2) Y\\R_{z}(\theta) = \cos(\theta / 2) I - i\sin(\theta / 2) Z\end{aligned}\end{align} \]
Parameters:
  • axis (str) – Rotation axis. ‘x’, ‘y’ or ‘z’ denotes the corresponding axis.

  • theta (Tensor) – Rotation angle.

Returns:

The matrix form of Rotation gate.

Return type:

Tensor

Code example:

from numpy import pi
from paddle import to_tensor
from paddle_quantum.mbqc.utils import rotation_gate

theta = to_tensor([pi / 6], dtype='float64')
Rx = rotation_gate('x', theta)
Ry = rotation_gate('y', theta)
Rz = rotation_gate('z', theta)
print("Matrix of Rotation X gate with angle pi/6: \n", Rx.numpy())
print("Matrix of Rotation Y gate with angle pi/6: \n", Ry.numpy())
print("Matrix of Rotation Z gate with angle pi/6: \n", Rz.numpy())
Matrix of Rotation X gate with angle pi/6:
 [[0.96592583+0.j         0.        -0.25881905j]
 [0.        -0.25881905j 0.96592583+0.j        ]]
Matrix of Rotation Y gate with angle pi/6:
 [[ 0.96592583+0.j -0.25881905+0.j]
 [ 0.25881905+0.j  0.96592583+0.j]]
Matrix of Rotation Z gate with angle pi/6:
 [[0.96592583-0.25881905j 0.        +0.j        ]
 [0.        +0.j         0.96592583+0.25881905j]]
paddle_quantum.mbqc.utils.to_projector(vector)

Transform a vector into its density matrix (or measurement projector).

\[|\psi\rangle \to |\psi\rangle\langle\psi|\]
Parameters:

vector (Tensor) – Vector of a quantum state or a measurement basis

Returns:

Density matrix (or measurement projector)

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import zero_state, plus_state
from paddle_quantum.mbqc.utils import to_projector

zero_proj = to_projector(zero_state())
plus_proj = to_projector(plus_state())
print("The projector of zero state: \n", zero_proj.numpy())
print("The projector of plus state: \n", plus_proj.numpy())
The projector of zero state:
 [[1. 0.]
 [0. 0.]]
The projector of plus state:
 [[0.5 0.5]
 [0.5 0.5]]
paddle_quantum.mbqc.utils.basis(label, theta=Tensor(shape=[1], dtype=float64, place=Place(cpu), stop_gradient=True,        [0.]))

Measurement basis.

Note

Commonly used measurements are measurements in the XY and YZ planes, and Pauli X, Y, Z measurements.

\[\begin{split}\begin{align*} & M^{XY}(\theta) = \{R_{z}(\theta)|+\rangle, R_{z}(\theta)|-\rangle\}\\ & M^{YZ}(\theta) = \{R_{x}(\theta)|0\rangle, R_{x}(\theta)|1\rangle\}\\ & X = M^{XY}(0)\\ & Y = M^{YZ}(\pi / 2) = M^{XY}(-\pi / 2)\\ & Z = M_{YZ}(0) \end{align*}\end{split}\]
Parameters:
  • label (str) – the labels of the measurement basis, “XY” denotes XY plane, “YZ” denotes YZ plane, “X” denotes X measurement, “Y” denotes Y measurement, “Z” denotes Z measurement.

  • theta (Tensor, optional) – measurement angle, the parameter is needed when the measurement is in XY plane or YZ plane.

Returns:

the list composed of measurement basis, the elements are of type Tensor.

Return type:

list

Code example:

from numpy import pi
from paddle import to_tensor
from paddle_quantum.mbqc.utils import basis
theta = to_tensor(pi / 6, dtype='float64')
YZ_plane_basis = basis('YZ', theta)
XY_plane_basis = basis('XY', theta)
X_basis = basis('X')
Y_basis = basis('Y')
Z_basis = basis('Z')
print("Measurement basis in YZ plane: \n", YZ_plane_basis)
print("Measurement basis in XY plane: \n", XY_plane_basis)
print("Measurement basis of X: \n", X_basis)
print("Measurement basis of Y: \n", Y_basis)
print("Measurement basis of Z: \n", Z_basis)
Measurement basis in YZ plane:
 [Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[(0.9659258262890683+0j)],
        [-0.25881904510252074j  ]]),
  Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[-0.25881904510252074j  ],
        [(0.9659258262890683+0j)]])]
Measurement basis in XY plane:
 [Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[(0.6830127018922193-0.1830127018922193j)],
        [(0.6830127018922193+0.1830127018922193j)]]),
  Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[ (0.6830127018922193-0.1830127018922193j)],
        [(-0.6830127018922193-0.1830127018922193j)]])]
Measurement basis of X:
 [Tensor(shape=[2, 1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[0.70710678],
        [0.70710678]]),
  Tensor(shape=[2, 1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[ 0.70710678],
        [-0.70710678]])]
Measurement basis of Y:
 [Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[(0.5-0.5j)],
        [(0.5+0.5j)]]),
  Tensor(shape=[2, 1], dtype=complex128, place=CPUPlace, stop_gradient=True,
       [[ (0.5-0.5j)],
        [(-0.5-0.5j)]])]
Measurement basis of Z:
 [Tensor(shape=[2, 1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[1.],
        [0.]]),
  Tensor(shape=[2, 1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[0.],
        [1.]])]
paddle_quantum.mbqc.utils.kron(tensor_list)

Take the tensor product of all the elements in the list.

\[[A, B, C, \cdots] \to A \otimes B \otimes C \otimes \cdots\]
Parameters:

tensor_list (list) – a list contains the element to taking tensor product.

Returns:

the results of the tensor product are of type Tensor. If there is only one Tensor in the list, return the Tensor.

Return type:

Tensor

Code example 1:

from paddle import to_tensor
from paddle_quantum.mbqc.utils import pauli_gate, kron
tensor0 = pauli_gate('I')
tensor1 = to_tensor([[1, 1], [1, 1]], dtype='float64')
tensor2 = to_tensor([[1, 2], [3, 4]], dtype='float64')
tensor_list = [tensor0, tensor1, tensor2]
tensor_all = kron(tensor_list)
print("The tensor product result: \n", tensor_all.numpy())
The tensor product result:
[[1. 2. 1. 2. 0. 0. 0. 0.]
 [3. 4. 3. 4. 0. 0. 0. 0.]
 [1. 2. 1. 2. 0. 0. 0. 0.]
 [3. 4. 3. 4. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 2. 1. 2.]
 [0. 0. 0. 0. 3. 4. 3. 4.]
 [0. 0. 0. 0. 1. 2. 1. 2.]
 [0. 0. 0. 0. 3. 4. 3. 4.]]

Code example 2:

from paddle_quantum.mbqc.utils import pauli_gate, kron
tensor0 = pauli_gate('I')
tensor_list = [tensor0]
tensor_all = kron(tensor_list)
print("The tensor product result: \n", tensor_all.numpy())
The tensor product result:
[[1. 0.]
[0. 1.]]
paddle_quantum.mbqc.utils.permute_to_front(state, which_system)

Move a subsystem of a system to the first.

Assume that a quantum state \(\psi\rangle\) can be decomposed to tensor product form:

\[|\psi\rangle = |\psi_1\rangle \otimes |\psi_2\rangle \otimes |\psi_3\rangle \otimes \cdots\]

the labels of each \(|\psi_i\rangle\) is \(i\) , so the total labels of the current system are:

\[\text{label} = \{1, 2, 3, \cdots \}\]

Assume that the label of the subsystem to be moved is: i

The output new quantum state is:

\[|\psi_i\rangle \otimes |\psi_1\rangle \otimes \cdots |\psi_{i-1}\rangle \otimes |\psi_{i+1}\rangle \otimes \cdots\]
Parameters:
  • state (State) – the quantum state to be processed

  • which_system (str) – the labels of the subsystem to be moved.

Returns:

the final state after the move operation.

Return type:

State

paddle_quantum.mbqc.utils.permute_systems(state, new_system)

Permute the quantum system to given order

Assume that a quantum state \(\psi\rangle\) can be decomposed to tensor product form:

\[|\psi\rangle = |\psi_1\rangle \otimes |\psi_2\rangle \otimes |\psi_3\rangle \otimes \cdots\]

the labels of each \(|\psi_i\rangle\) is \(i\) , so the total labels of the current system are:

\[\text{label} = \{1, 2, 3, \cdots \}\]

the order of labels of the given new system is:

\[\{i_1, i_2, i_3, \cdots \}\]

The output new quantum state is:

\[|\psi_{i_1}\rangle \otimes |\psi_{i_2}\rangle \otimes |\psi_{i_3}\rangle \otimes \cdots\]
Parameters:
  • state (State) – the quantum state to be processed

  • new_system (list) – target order of the system

Returns:

the quantum state after permutation.

Return type:

State

paddle_quantum.mbqc.utils.compare_by_density(state1, state2)

Compare whether two quantum states are the same by their density operators.

Parameters:
  • state1 (State) – the first quantum state

  • state2 (State) – the second quantum state

paddle_quantum.mbqc.utils.compare_by_vector(state1, state2)

Compare whether two quantum states are the same by their column vector form.

Parameters:
  • state1 (State) – the first quantum state

  • state2 (State) – the second quantum state

paddle_quantum.mbqc.utils.random_state_vector(n, is_real=False)

Generate a state vector randomly.

Parameters:
  • n (int) – the number of qubits of the random state.

  • is_real (int, optional) – True denotes a state vector with real values, False denotes a quantum

  • values (state with complex) –

  • False (default to) –

Returns:

the column vector of the random quantum state.

Return type:

Tensor

Code example:

from paddle_quantum.mbqc.utils import random_state_vector
random_vec = random_state_vector(2)
print(random_vec.numpy())
random_vec = random_state_vector(1, is_real=True)
print(random_vec.numpy())
[[-0.06831946+0.04548425j]
 [ 0.60460088-0.16733175j]
 [ 0.39185213-0.24831266j]
 [ 0.45911355-0.41680807j]]
[[0.77421121]
 [0.63292732]]
paddle_quantum.mbqc.utils.div_str_to_float(div_str)

Converts the division string to the corresponding floating point number.

For example, the string ‘3/2’ to the float number 1.5.

Parameters:

div_str (str) – division string

Returns:

the float number

Return type:

float

Code example:

from paddle_quantum.mbqc.utils import div_str_to_float
division_str = "1/2"
division_float = div_str_to_float(division_str)
print("The corresponding float value is: ", division_float)
The corresponding float value is:  0.5
paddle_quantum.mbqc.utils.int_to_div_str(idx1, idx2=1)

Transform two integers to a division string.

Parameters:
  • idx1 (int) – the first integer

  • idx2 (int) – the second integer

Returns:

the division string

Return type:

str

Code example:

from paddle_quantum.mbqc.utils import int_to_div_str
one = 1
two = 2
division_string = int_to_div_str(one, two)
print("The corresponding division string is: ", division_string)
The corresponding division string is:  1/2
paddle_quantum.mbqc.utils.print_progress(current_progress, progress_name, track=True)

Plot the progress bar.

Parameters:
  • current_progress (float / int) – the percentage of the current progress.

  • progress_name (str) – the name of the current progress.

  • track (bool) – the boolean switch of whether plot.

Code example:

from paddle_quantum.mbqc.utils import print_progress
print_progress(14/100, "Current Progress")
Current Progress              |■■■■■■■                                           |   14.00%
paddle_quantum.mbqc.utils.plot_results(dict_lst, bar_label, title, xlabel, ylabel, xticklabels=None)
Plot the histogram based on the key-value pair of the dict.

The key is the abscissa, and the corresponding value is the ordinate

Note

The function is mainly used for plotting the sampling statistics or histogram.

Parameters:
  • dict_lst (list) – a list contains the data to be plotted

  • bar_label (list) – the name of different bars in the histogram

  • title (str) – the title of the figure

  • xlabel (str) – the label of the x axis.

  • ylabel (str) – the label of the y axis.

  • xticklabels (list, optional) – the label of each ticks of the x-axis.

paddle_quantum.mbqc.utils.write_running_data(textfile, eg, width, mbqc_time, reference_time)

Write the running times of the quantum circuit.

In many cases of circuit models, we need to compare the simulation time of our MBQC model with other methods such as qiskit or UAnsatz circuit model in paddle_quantum. So we define this function.

Hint

this function is used with the read_running_data function.

Warning

Before using this function, we need to open a textfile. After using this function, we need to close the textfile.

Parameters:
  • textfile (TextIOWrapper) – the file to be written in.

  • eg (str) – the name of the current case

  • width (float) – the width of the circuit(number of qubits)

  • mbqc_time (float) – the simulation time of the ``MBQC` model.

  • reference_time (float) – the simulation time of the circuit

  • paddle_quantum. (based model in qiskit or UAnsatz in) –

paddle_quantum.mbqc.utils.read_running_data(file_name)

Read the running time of the quantum circuit.

In many cases of circuit models, we need to compare the simulation time of our MBQC model with other methods such as qiskit or UAnsatz circuit model in paddle_quantum. So we define this function and save the running time to a list. There are two dicts in the list, the first dict contains the running time of qiskit or UAnsatz, the second contains the simulation time of our MBQC model.

Hint

This function is used with the write_running_data function.

Parameters:

file_name (str) – the name of the file to be read.

Returns:

The list of running time.

Return type:

list