Introduction to Linear Algebra and Quantum Information modules of Paddle Quantum¶
Copyright (c) 2023 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
linalg
and qinfo
module are Paddle Quantum modules that support operations of matrices and functions of quantum information respectively. linalg
module provides many matrix operations includeing transpose, conjuagte, tensor product and trace. And qinfo
module mainly includes partial trace, different quantum entropy, fidelity of quantum states and trace distance, which are functions that related to quantum information theory.
Common operations of matrix¶
We know that quantum mechanics has a close connection with linear algebra. Here, we will introduce the common operations of matrix in linalg
module with simple examples.
import paddle
import paddle_quantum
from paddle_quantum.state import State
from paddle.linalg import eigvals, eig
from paddle_quantum.linalg import dagger, NKron, density_matrix_random, unitary_random
from paddle_quantum.qinfo import (
partial_trace,
state_fidelity,
trace_distance,
von_neumann_entropy,
relative_entropy,
)
paddle_quantum.set_backend("density_matrix")
c:\Users\liugeng02\Anaconda3\envs\2023q2\lib\site-packages\openfermion\hamiltonians\hartree_fock.py:11: DeprecationWarning: Please use `OptimizeResult` from the `scipy.optimize` namespace, the `scipy.optimize.optimize` namespace is deprecated. from scipy.optimize.optimize import OptimizeResult c:\Users\liugeng02\Anaconda3\envs\2023q2\lib\site-packages\paddle\tensor\creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations if data.dtype == np.object: c:\Users\liugeng02\Anaconda3\envs\2023q2\lib\site-packages\paddle\tensor\creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations if data.dtype == np.object:
We first initialize two random unitary matrices through built-in function of Paddle Quantum. The matrix A and B here are both in paddle.Tensor
format.
A = unitary_random(num_qubits=1)
B = unitary_random(num_qubits=1)
print(f"Matrix A is:\n{A}\n")
print(f"Matrix B is:\n{B}")
Matrix A is: Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True, [[(-0.008479282259941101-0.3407862186431885j), (0.6076244115829468-0.7173460721969604j) ], [(-0.3203158378601074-0.8838498592376709j) , (-0.12643268704414368+0.3165784478187561j) ]]) Matrix B is: Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True, [[(-0.6520524621009827-0.2549170255661011j) , (-0.5733906030654907-0.42552101612091064j)], [ (0.5613574981689453+0.44127389788627625j), (-0.4174516499042511-0.5620402097702026j) ]])
matrix multiplication:There are two ways to calculate matrix multiplication, the first way is using matmul
method of Paddle, and the second way is directly using @
.
transpose:The transpose of matrix A can be calculated using A.t()
.
conjugate:The conjugate of matrix A can be calculated using A.conjugate()
.
conjugate transpose:There are two ways to calculate conjugate transpose of a matrix. The first way is calculating the conjugate of the matrix followed by calculating the transpose, using A.conj().t()
; the second way is directly using dagger
method of Paddle Quantum.
tensor product of two matrices:The tensor product of two matrices can be calculated using paddle.kron()
.
tensor product of multiple matrices:The tensor product of multiple matrices can be calculated using NKron()
of Paddle Quantum.
trace of matrix:The trace of a matrix can be calculated using paddle.trace()
.
partial trace of matrix:The partial trace of a matrix can be calculated using partial_trace()
of Paddle Quantum.
eigenvalue and eigenvector of matrix:The eigenvalues and eigenvectors of a matrix can be calculated using eig
, and the eigenvalues can be directly calculated using eigvals
.
multiplyAB_1 = paddle.matmul(A, B) # matrix multiplication
multiplyAB_2 = A @ B # matrix multiplication
A_transpose = A.t() # transpose
A_conjugate = A.conj() # conjugate
A_dagger = dagger(A) # conjugate transpose
tensor_product_AB = paddle.kron(A, B) # tensor product of two matrices
tensor_product_ABA = NKron(A, B, A) # tensor product of multiple matrices
A_trace = paddle.trace(A) # trace of the matrix
partial_trace_matrix = partial_trace(tensor_product_AB, dim1=2, dim2=2, A_or_B=2) # partial trace of matrix
eigenvalue, eigenvector = eig(A) # eigenvalue and eigenvector of the matrix
Common functions in quantum information¶
We first initialize two random single qubit quantum states with density_matrix_random
.
state1 = density_matrix_random(1)
print(f"The first quantum state is:\n {state1}\n")
state2 = density_matrix_random(1)
print(f"The second quantum state is:\n {state2}")
The first quantum state is: Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True, [[(0.5706692337989807+0j) , (0.4849703907966614+0.09904339164495468j)], [(0.4849703907966614-0.09904339164495468j), (0.4293307662010193+0j) ]]) The second quantum state is: Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True, [[ (0.8634329438209534+0j) , (-0.04915342852473259+0.33985358476638794j)], [(-0.04915342852473259-0.33985358476638794j), (0.13656707108020782+0j) ]])
We can use state_fidelity()
to calculate the fidelity of two quantum states.
fidelity = state_fidelity(state1, state2)
print(f"The fidelity is:\n{fidelity}")
The fidelity is: Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True, [0.75565338])
c:\Users\liugeng02\Anaconda3\envs\2023q2\lib\site-packages\paddle\fluid\framework.py:1104: DeprecationWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence this warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations elif dtype == np.bool:
It is worth noting that the functions of Paddle Quantum that related to quantum states supports different format of input, including paddle.Tensor
, numpy.ndarray
, and State
. At the same time, the output format is consistent with the input format. For example, the output will be numpy.ndarray
format if the input is also numpy.ndarray
format.
# Input with numpy.ndarray format
state1 = state1.numpy()
state2 = state2.numpy()
print(state_fidelity(state1, state2))
0.7556533814816342
# Input with State format
state1 = State(state1)
state2 = State(state2)
print(state_fidelity(state1, state2))
Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True, [0.75565338])
We can use trace_distance
to calculate the trace distance between two quantum states.
TraceDistance = trace_distance(state1, state2)
print(f"The trace distance is:\n{TraceDistance}")
The trace distance is: Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True, [0.65497208])
We can use von_neumann_entropy()
to calculate the von neumann entropy of a quantum state.
v_entropy = von_neumann_entropy(state2)
print(f"The von veumann entropy of the quantum state is:\n{v_entropy}")
The von veumann entropy of the quantum state is: Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True, [0.00000026])
We can use relative_entropy()
to calculate the relative entropy of two quantum states.
r_entropy = relative_entropy(state1, state2)
print(f"The relative entropy is:\n{r_entropy}")
logm result may be inaccurate, approximate err = 3.3328131580525864e-07 logm result may be inaccurate, approximate err = 2.3121323283812061e-07 The relative entropy is: Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True, [11.14819717])