API Reference for QIClib 1.0
-
Every functions, classes, or constants in QIClib belongs to the
namespace qic
. - First time users may want to have a look on sample programs.
- First time users may want to have a look on frequently asked questions.
- If you discover any bugs or regressions, please report them
- Notes on API additions
Overview
- Classes and constants
- Functions
- Classes for quantum discord like features
- Preprocessor macros to tune the library in compile time
[top] Classes and constants
Init | Class for library initialization | |
SPM<POD_TYPE>, spm, spmf | Several predefined constant special matrices like basis states, projectors and operators | |
GATES<POD_TYPE>, gates, gatesf | Several predefined constant quantum gates and generators of quantum gate | |
Func<POD_TYPE>, func, funcf | Several predefined functions to be
used with funcm_sym or funcm_gen
| |
RandomDevices, rdevs | Predefined random number engines/generators, used in functions like randU etc. |
Functions
is_Hermitian | Hermiticity check | |
is_Unitary | Unitarity check | |
is_Normal | To check whether the the matrix is normal or not | |
is_pure | To check purity of a density matrix | |
is_valid_state | To check whether the matrix represents a valid quantum state | |
is_diagonalizable | To check whether the matrix is diagonalizable or not | |
is_equal | To check whether two matrices are equal | |
dense_to_sparse | To convert a dense matrix (Mat) to a sparse (SpMat) matrix | |
sparse_to_dense | To convert a sparse matrix (SpMat) to a dense (Mat) matrix | |
range | Similar to Python's range() function. Useful in range-based for loops | |
TrX | Partial trace | |
Tx | Partial transpose | |
sysperm | Permute subsystems of a quantum state | |
sqrtm_sym | Principal square root of real symmetric or Hermitian matrices | |
sqrtm_gen | Principal square root of general square matrices | |
powm_sym | Matrix power for real symmetric or Hermitian matrices | |
powm_gen | Matrix power for general square matrices | |
expm_sym | Matrix exponential for real symmetric or Hermitian matrices | |
expm_gen | Matrix exponential for general square matrices | |
funcm_sym | Matrix function for real symmetric or Hermitian matrices | |
funcm_gen | Matrix function for general square matrices | |
tensor | Tensor product of arbitrary no. of matrices | |
tensor_pow | Tensor product power | |
dsum | Direct sum of arbitrary no. of matrices | |
dsum_pow | Direct sum power | |
absm | Matrix absolute value of a square matrix | |
schatten | Schatten p-norm of a matrix | |
purify | Minimal purification of a density matrix | |
gram_schmidt | Modified Gram-Schmidt orthogonalization | |
conv_to_pure | To convert density matrix of a pure state to a column vector | |
std_to_HS | To convert 2-qubit density matrix from the standard basis to the Hilbert-Schmidt basis | |
HS_to_std | To convert 2-qubit density matrix from the Hilbert-Schmidt basis back to the standard basis | |
mket | To generate multipartite qudit pure state | |
mproj | To genearte multipartite qudit projector | |
randU | To generate object with random values (uniform distribution) | |
randN | To generate object with random values (normal distribution) | |
randI | To generate object with random integers | |
randHermitian | To generate random Hermitian matrix | |
randUnitary | To generate random unitary matrix | |
randPsi | To generate random pure states | |
randRho | To generate random mixed states | |
randPerm | To generate random permutation of unsigned integers | |
entropy | von Neumann entropy of a quantum state | |
shannon | Shannon entropy of a probability distribution | |
renyi | Renyi entropy of a quantum state | |
renyi_prob | Renyi entropy of a probability distribution | |
tsallis | Tsallis entropy of a quantum state | |
tsallis_prob | Tsallis entropy of a probability distribution | |
mutual_info | Quantum mutual information between 2 subsystems of a quantum state | |
rel_entropy | Relative entropy between two quantum states | |
rel_entropy_prob | Relative entropy between two probability distributions | |
entanglement | Entanglement entropy of a pure quantum state | |
neg | Negativity of a quantum state | |
log_neg | Logarithmic negativity of a quantum state | |
concurrence | Concurrence of a two-qubit quantum state | |
EoF | Entanglement of formation of a two-qubit quantum state | |
ent_check_CMC | To check if a bipartite state is entangled or not (based on covariant matrix criteria, can be used to detect bound entangled states) | |
schmidt, schmidt_full | Schmidt decomposition of a bipartite pure state | |
schmidtA, schmidtB, schmidtAB, schmidtA_full, schmidtB_full, schmidtAB_full | Schmidt vectors of a bipartite pure state | |
l1_coh | l1-norm coherence of a quantum state | |
rel_entropy_coh | Relative entropy of coherence of a quantum state | |
HS_dist | Hilbert-Schmidt distance between two density matrices | |
tr_dist | Trace distance between two density matrices | |
Bures_dist | Bures distance between two density matrices | |
fidelity | Fidelity between two density matrices | |
apply | To apply a quantum gate to a quantum state | |
apply_ctrl | To apply a quantum gate or a set of Kraus operators to a quantum state as a controlled gate | |
make_ctrl | To convert a quantum gate into a controlled quantum gate | |
measure | To measure a quantum state using a set of Kraus or projection operators | |
measure_comp | To measure a quantum state in the computational basis |
Classes for discord like features
- Note: These features depend on NLopt.
- Note: If you want to use old API's for discord like function, define
QICLIB_USE_OLD_DISCORD
macro before includingQIClib
header. See preprocessor macros in QIClib for details. Old API's for discord like functions are not maintained anymore.
discord_space | Computational space for calculating quantum discord (actual as well as constrained-regular) for quantum states when measurement is done over a qubit or qutrit system | |
deficit_space | Computational space for calculating quantum work deficit (actual as well as constrained-regular) for quantum states when measurement is done over a qubit or qutrit system |
In this documentation the mat, cx_mat, vec, and cx_vec type is used for convenience. But every function should also work with float counterparts, like fmat, cx_fmat, fvec, and cx_fvec.
Classes and constants
Init
- Class for library initialization. Automatically loaded if you use this library.
- Prints current time and date upon program start. After program completion, prints current time and date along with total runtime.
- To disable this feature, define
QICLIB_NO_INIT_MESSAGE
macro before includingQIClib
header. See preprocessor macros in QIClib for details.
SPM<POD_TYPE>
spm
spmf
- Several predefined special matrices and vectors like, basis, projectors, operators etc.
POD_TYPE
can be eitherdouble
orfloat
. - This is a singleton class, can be constructed only once.
You can only take
const
reference of this class usingSPM<POD_TYPE>::get_instance()
function (see below). For the ease of use, QIClib library automatically instantiates this class fordouble
andfloat
asspm
andspmf
respectively. Use ofspm
orspmf
is recommended rather than explicitSPM<POD_TYPE>::get_instance()
. -
spm.S
givesfield
of Pauli matrices as constant complex matrices (const cx_mat
).spm.S(0)
,spm.S(1)
,spm.S(2)
, andspm.S(3)
are respectively I2x2, σx, σy, and σz.
(Similarly forspmf.S
). -
spm.basis2
givesfield
of 2-dimensional basis vectors as constant complex column vectors (const cx_vec
).spm.basis2(0, i)
andspm.basis2(1, i)
are respectively |0> and |1> in i direction (i = 0, 1, 2, 3).
spm.proj2
gives corresponding projectors as constant complex matrices (const cx_mat
).
(Similarly forspmf.basis2
andspmf.proj2
). -
spm.basis3
givesfield
of 3-dimensional basis vectors constant complex column vectors (const cx_vec
).spm.basis3(0, i)
,spm.basis3(1, i)
andspm.basis3(2, i)
are respectively |0>, |1> and |2> in i direction (i = 0, 1, 2, 3).spm.proj3
gives corresponding projectors constant complex matrices (const cx_mat
).
(Similarly forspmf.basis3
andspmf.proj3
). -
spm.bell.phim
,spm.bell.phip
,spm.bell.psim
, andspm.bell.psip
give four Bell states as constant real vectors (const vec
).
(Similarly forspmf.bell
). - Note: You cannot take a copy of the whole
SPM<POD_TYPE>
class, but you can take reference toconst
. For this useconst SPM<POD_TYPE>& SOMENAME = SPM<POD_TYPE>::get_instance();
. However, for each member variables, likeS
orproj3
etc., you can either take a copy or reference toconst
(See the following example).
Note: Taking copy or reference toconst
is not advisable for the member variables. Direct use of member variables is recommended. - Example:
const SPM<double>& myspm = SPM<double>::get_instance(); // take const ref of the whole class const cx_mat& S1 = spm.S(1); // \sigma_x matrix, take reference cx_mat S2 = spm.S(2); // \sigma_y matrix, take a copy const cx_vec& plus = spm.basis2(0, 1); // |+> state const cx_mat& proj_plus = spm.proj2(0, 1); // |+><+| projector const cx_vec& U = spm.basis3(0, 3); // 1st eigenvector of //Spin S_z operator in 3-dim const cx_mat& M = spm.basis3(1, 3); // 2nd eigenvector of //Spin S_z operator in 3-dim const cx_mat& M = spm.basis3(2, 3); // 3rd eigenvector of //Spin S_z operator in 3-dim
GATES<POD_TYPE>
gates
gatesf
- Several predefined constant quantum gates and generators of quantum gates.
POD_TYPE
can be eitherdouble
orfloat
. - This is a singleton class, can be constructed only once.
You can only take
const
reference of this class usingGATES<POD_TYPE>::get_instance()
function (see below). For the ease of use, QIClib library automatically instantiates this class fordouble
andfloat
asgates
andgatesf
respectively. Use ofgates
orgatesf
is recommended rather than explicitGATES<POD_TYPE>::get_instance()
. -
gates.X
,gates.Y
,gates.Z
, andgates.Had
give Pauli X,Y, and Z and Hadamard gates respectively.gates.Y
is a constant complex matrix (const cx_mat
), where as others are constant real matrices (const mat
).
(Similarly forgatesf.X
,gatesf.Y
,gatesf.Z
, andgatesf.Had
). -
gates.CNOT
,gates.CZ
andgates.swap
give controlled NOT, controlled Pauli Z, and swap gates respectively as constant real matrices (const mat
).
(Similarly forgatesf.CNOT
,gatesf.CZ
, andgatesf.swap
). -
gates.Tof
andgates.Fred
give Toffoli and Fredkin gates respectively as constant real matrices (const mat
).
(Similarly forgatesf.Tof
andgatesf.Fred
). -
gates.U2(theta, unitV)
: Generates a member of U(2) group.theta
is adouble
anduniV
is a 3-dimensional unit column vector (vec
). Output is a fixed size 2x2 complex unitary matrix (cx_mat22
) as U = cos(theta/2) I + i sin(theta/2)(unitV.σ).
(Similarly forgatesf.U2(theta, unitV)
). -
gates.PS(phi)
: Generates a phase-shift gate according to the anglephi
(double
). Output is a fixed size 2x2 complex unitary matrix (cx_mat22
) as U = diag(1, exp(i*phi)).
(Similarly forgatesf.PS(phi)
). -
gates.qft(dim)
: Generates unitary matrix for quantum Fourier transform of dimension specified bydim
, as complex matrix (cx_mat
).
(Similarly forgatesf.qft(dim)
). - Note: You cannot take a copy of the whole
GATES<POD_TYPE>
class, but you can take reference toconst
. For this useconst GATES<POD_TYPE>& SOMENAME = GATES<POD_TYPE>::get_instance();
. However, for each member variables, likeHad
orCNOT
etc., you can either take a copy or reference toconst
. Member functions likeU2
orqft
etc. behave like normal functions. (See the following example).
Note: Taking copy or reference toconst
is not advisable for the member variables. Direct use of member variables is recommended. - Example:
const GATES<double>& mygates = GATES<double>::get_instance(); // take const ref of the whole class const mat& XX = gates.X; // \sigma_x matrix, take reference cx_mat YY = gates.Y; // \sigma_y matrix, take a copy cx_mat Q = gates.qft(8); // quantum Fourier transform // for 8 dimension
Func<type>
func
funcf
- Class with several predefined static member functions to be used with
funcm_sym
orfuncm_gen
. -
func
is an alias forFunc<double>
andfuncf
is an alias forFunc<float>
. - Every member function takes one complex type and returns one complex type.
- List of member functions:
- func::sin
func::cos
func::tan - func::asin
func::acos
func::atan - func::sinh
func::cosh
func::tanh - func::asinh
func::acosh
func::atanh - func::sqrt
func::log
func::log2 - func::real
func::imag
func::norm
- func::sin
RandomDevices
rdevs
- Predefined random number engines/generators, used in functions like randU etc. This class is thread safe.
- This is a singleton class, can be constructed only once.
You can only take reference of this class using
RandomDevices::get_thread_local_instance()
orRandomDevices::get_instance()
, but this is not advisable at all. QIClib library automatically instantiates this class asredvs
. Userdevs
rather than explicitRandomDevices::get_thread_local_instance()
orRandomDevices::get_instance()
. - There are two member variables,
rd
andrng
.rd
is an instance ofstd::random_device
, andrng
is an instance of Mersenne twister engine,std::mt19937_64
orstd::mt19937
depending on whether Armadillo uses 64bit integers or not. See this. - By default,
rng
is seeded with the random return value ofrd
. To seedrng
with user defined value, userdevs.set_seed(YOUR_SEED)
. To seedrng
with the random return value ofrd
again, userdevs.set_seed_random()
. - Example:
std::cauchy_distribution<double> dis(0,1); // Cauchy distribution with parameters 0 and 1 double a[10], b[10], c[10]; // seed is random, by default for(int i = 0; i < 10; ++i) { a[i] = dis(rdevs.rng); // generate 10 random number // according to Cauchy distribution // with parameters 0 and 1 } rdevs.set_seed(10); // set seed to 10 for(int i = 0; i < 10; ++i) { b[i] = dis(redvs.rng); // generate 10 random number // according to Cauchy distribution // with parameters 0 and 1 } rdevs.set_seed_random(); // again seed is random for(int i = 0; i < 10; ++i) { c[i] = dis(rdevs.rng); // generate 10 random number // according to Cauchy distribution // with parameters 0 and 1 }
Functions
is_Hermitian(A)
is_Hermitian(A, atol, rtol)
- Hermiticity check. Returns
true
ifA
is real symmetric (mat
) or Hermitian (cx_mat
), elsefalse
. -
atol
andrtol
are optional. By default,atol
is floating point precision used in QIClib, andrtol
is 10 times of that. See preprocessor macros in QIClib for details.
is_Unitary(A)
is_Unitary(A, atol, rtol)
- Unitarity check. Returns
true
ifA
is real orthogonal (mat
) or unitary (cx_mat
), elsefalse
. -
atol
andrtol
are optional. By default,atol
is floating point precision used in QIClib, andrtol
is 10 times of that. See preprocessor macros in QIClib for details.
is_Normal(A)
is_Normal(A, atol, rtol)
- To check whether the the matrix is normal or not.
Returns
true
ifA
is a normal matrix, elsefalse
. -
atol
andrtol
are optional. By default,atol
is floating point precision used in QIClib, andrtol
is 10 times of that. See preprocessor macros in QIClib for details.
is_pure(A)
is_pure(A, check_norm = true)
is_pure(A, check_norm, tol)
- To check purity of a row/column vector or density matrix.
Returns
true
ifA
is a pure state, elsefalse
. -
check_norm
andtol
are optional. By default,check_norm = true
and normalization of the vector or matrix will be checked, andtol
is floating point precision used in QIClib. See preprocessor macros in QIClib for details.
is_valid_state(A)
is_valid_state(A, tol)
- To check whether the matrix or vector represents a valid quantum state. Returns
true
ifA
is a valid quantum state, elsefalse
. -
tol
is optional, by default,tol
is floating point precision used in QIClib. See preprocessor macros in QIClib for details. - Note: Normalization will always be checked.
is_diagonalizable(A)
- To check whether the matrix is diagonalizable.
Returns
true
ifA
is diagonalizable, elsefalse
.
is_equal(A, B)
is_equal(A, B, typecheck = false)
is_equal(A, B, typecheck, atol, rtol)
- To check whether two matrices are equal in values.
Returns
true
ifA
andB
are element-wise (approximately) equal, elsefalse
. -
typecheck
is optional. By default,typecheck=false
, and element types (complex or real) ofA
andB
need not to be same. -
atol
andrtol
are optional. By default,atol
is floating point precision used in QIClib, andrtol
is 10 times of that. See preprocessor macros in QIClib for details.
dense_to_sparse(A)
dense_to_sparse(A, tol)
- To Convert a dense matrix
A
(Mat) to a sparse (SpMat) matrix with the same element type. -
tol
is optional. Any element having absolute value less thantol
will be treated as zero. By default,tol
is floating point precision used in QIClib. See preprocessor macros in QIClib for details.
sparse_to_dense(A)
Go to top
range(stop)
range(start, stop)
range(start, stop, step)
- Similar to Python's
range()
function. Useful in range-basedfor
loops. Returnsstd::vector
of arithmetic (floating point or integral types) values, from (and including)start
to (and excluding)stop
with step-size equal tostep
. -
start
andstep
are optional, by default,start = 0
andstep = 1
. - Example:
for(auto&& i : range(10)) { // i from 0 to 9 //do something } std::vector<int> R1 = range(2, 10, 2); std::vector<double> R2 = range(10, -1.5, -0.5);
TrX(A, subsys)
TrX(A, subsys, dim)
- Partial trace of a quantum state, where
subsys
is auvec
containing the indices of to be traced out subsystems. -
A
has be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
mat A = randn<mat>(8, 8); // 8x8 matrix A *= A.t(); // make Hermitian A /= trace(A); //normalize cx_mat B = randRho(12); // random 12x12 density matrix, see randRho() // trace out 2nd and 3rd party mat A1 = TrX(A, {2, 3}); // all dim are 2, total 3 parties mat A2 = TrX(A, {2, 3}, 2); // same as before // trace out 2nd and 3rd party cx_mat B1 = TrX(B, {2, 3}, {2, 3, 2}); // explicitly written dimensions
Tx(A, subsys)
Tx(A, subsys, dim)
- Partial transpose of a quantum state, where
subsys
is auvec
containing the indices of to be transposed subsystems. -
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
mat A = randn<mat>(8, 8); // 8x8 matrix A *= A.t(); // make Hermitian A /= trace(A); //normalize cx_mat B = randRho(12); // random 12x12 density matrix, see randRho() // transpose 2nd and 3rd party mat A1 = Tx(A, {2, 3}); // all dim are 2, total 3 parties mat A2 = Tx(A, {2, 3}, 2); // same as before // transpose 2nd and 3rd party cx_mat B1 = Tx(B, {2, 3}, {2, 3, 2}); // explicitly written dimensions
sysperm(A, perm)
sysperm(A, perm, dim)
- Permute subsystems of a quantum state, where
perm
is auvec
containing the permutation of subsystem indices. -
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
perm
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
mat A = randn<mat>(8, 8); // 8x8 matrix A *= A.t(); // make hermitian A /= trace(A); //normalise cx_mat B = randRho(12); // random 12x12 density matrix, see randRho() // permute 2nd and 3rd party mat A1 = sysperm(A, {1, 3, 2}); // all dim are 2, total 3 parties mat A2 = sysperm(A, {1, 3, 2}, 2); // same as before // permute 2nd and 3rd party cx_mat B1 = sysperm(B, {1, 3, 2}, {2, 3, 2}); // explicitly written dimensions // for B1, dim = {2, 2, 3}
sqrtm_sym(A)
- Principal square root of real symmetric or Hermitian matrices.
-
A
has to be a square matrix (mat
orcx_mat
). - Due to generality, always returns complex matrices (
cx_mat
), even for positive real matrices. - Note:
sqrtm_sym
is faster thansqrtm_gen
. For real symmetric or Hermitian matrices always usesqrtm_sym
. - Example:
cx_mat A = randn<cx_mat>(5,5); A *= A.t(); // make hermitian mat B = randn<mat>(5,5); B *= B.t(); // make hermitian cx_mat sqrtA = sqrtm_sym(A); cx_mat sqrtB = sqrtm_sym(B);
sqrtm_gen(A)
- Principal square root of general square matrices.
-
A
has to be a square matrix (mat
orcx_mat
). - Due to generality, always returns complex matrices, even for positive real matrices.
- Note:
sqrtm_sym
is faster thansqrtm_gen
. For real symmetric or Hermitian matrices always usesqrtm_sym
. - Note: Only works if
A
is diagonalizable matrix. To make sure, useis_diagonalizable
function first. - Example:
cx_mat A = randn<cx_mat>(5,5); mat B = randn<mat>(5,5); cx_mat sqrtA = sqrtm_gen(A); cx_mat sqrtB = sqrtm_gen(B);
powm_sym(A, n)
- Matrix power for real symmetric or Hermitian matrices.
-
A
has to be a square matrix (mat
orcx_mat
).n
can be any type of scaler, likedouble
,complex<double>
,int
etc. - Due to generality, always returns complex matrices (if
n
is not of integer type), even for positive real matrices. Ifn
is of integer type matrix element type will be preserved. - Note:
powm_sym
is faster thanpowm_gen
. For real symmetric or Hermitian matrices always usepowm_sym
. - Example:
mat A = randn<mat>(5, 5); A *= A.t(); // make hermitian mat A_3 = powm_sym(A, 3); cx_mat A_3.14 = powm_sym(A, 3.14);
powm_gen(A, n)
- Matrix power for general square matrices.
-
A
has to be a square matrix (mat
orcx_mat
).n
can be any type of scaler, likedouble
,complex<double>
,int
etc. - Due to generality, always returns complex matrices (if
n
is not of integer type), even for positive real matrices. Ifn
is of integer type matrix element type will be preserved. - Note:
powm_sym
is faster thanpowm_gen
. For real symmetric or Hermitian matrices always usepowm_sym
. - Note: Only works if
A
is diagonalizable matrix. To make sure, useis_diagonalizable
function first. - Example:
mat A = randn<mat>(5, 5); mat A_3 = powm_gen(A, 3); cx_mat A_3.14 = powm_gen(A, 3.14);
expm_sym(A)
expm_sym(A, n)
- Matrix exponential for real symmetric or Hermitian matrices.
expm_sym(A,n)
calculates exp(n*A). -
A
has to be a square real symmetric or Hermitian matrix (mat
orcx_mat
).n
can be any type of scaler, likedouble
,complex<double>
,int
etc. - Note:
expm_sym
is often slower but more accurate thanexpm_gen
or Armadillo'sexpmat
. But for very large matrices it can be faster than the alternatives. - Example:
mat A = randn<mat>(5, 5); A *= A.t(); // make hermitian mat A_e = expm_sym(A); complex<double> I (0.0, 1.0); cx_mat AI_e = expm_sym(A, I); // exp(I*A)
expm_gen(A)
- Matrix exponential for general square matrices.
-
A
has to be a square matrix (mat
orcx_mat
). - Note:
expm_gen
is basically same as Armadillo'sexpmat
, and only to be used with older versions of Armadillo. - Example:
cx_mat A = randn<cx_mat>(5, 5); cx_mat A_e = expm_gen(A); complex<double> I (0.0, 1.0); cx_mat AI_e = expm_gen(I*A);
funcm_sym(A, function pointer)
funcm_sym(A, functor)
funcm_sym(A, lambda function)
- Matrix function for real symmetric or Hermitian matrices.
-
A
has to be a square real symmetric or Hermitian matrix (mat
orcx_mat
). function pointer, functor or lambda function has to take one complex type and return one complex type. - Due to generality, always returns complex matrices.
- If you want to use standard complex functions, use static member functions of
Func<type>
class. - Note:
funcm_sym
is faster thanfuncm_gen
. For real symmetric or Hermitian matrices always usefuncm_sym
. - Note: If you want to transform the matrix element-wise, use
.transform
instead. - Example:
cx_mat A = randn<cx_mat>(5, 5); A *= A.t(); // make hermitian //define a lambda function auto sinm = [](complex<double> a){return std::sin(a);}; cx_mat A_sin = funcm_sym(A, sinm); // calculate sin(A) cx_mat A_sin2 = funcm_sym(A, func::sin); // same as A_sin, //using
Func<type>
class
funcm_gen(A, function pointer)
funcm_gen(A, functor)
funcm_gen(A, lambda function)
- Matrix function for general square matrices.
-
A
has to be a square matrix (mat
orcx_mat
). function pointer, functor or lambda function has to take one complex type and return one complex type. - Due to generality, always returns complex matrices.
- If you want to use standard complex functions, use static member functions of
Func<type>
class. - Note:
funcm_sym
is faster thanfuncm_gen
. For real symmetric or Hermitian matrices always usefuncm_sym
. - Note: Only works if
A
is diagonalizable matrix. To make sure, useis_diagonalizable
function first. - Note: If you want to transform the matrix element-wise, use
.transform
instead. - Example:
cx_mat A = randn<cx_mat>(5, 5); //define a lambda function auto sinm = [](complex<double> a){return std::sin(a);}; cx_mat A_sin = funcm_gen(A, sinm); // calculate sin(A) cx_mat A_sin2 = funcm_gen(A, func::sin); // same as A_sin, // using
Func<type>
class
tensor(A, B, ...)
- Tensor product of arbitrary no. of matrices
A,B,...
. Return type is deduced from the types of input matrices. - Can also take
std::vector
andfield
of matrices. - Example:
cx_mat A = randn<cx_mat>(5, 5); //complex matrix cx_mat B = randn<cx_mat>(4, 4); //complex matrix cx_mat C = randn<cx_mat>(3, 3); //complex matrix mat D = randn<mat>(6, 6); //real matrix cx_mat T1 = tensor(A, B, C, D); // tensor product of A,B,C,D // return type is deduced as cx_mat std::vector<cx_mat> V = {A, B, C}; cx_mat T2 = tensor(V); // tensor product of A,B,C cx_mat T3 = tensor({A, B, C}); // same as above
tensor_pow(A, n)
- Tensor product power of a matrix.
- Returns A⊗n .
dsum(A, B, ...)
- Direct sum of arbitrary no. of matrices
A,B,...
. Return type is deduced from the types of input matrices. - Can also take
std::vector
andfield
of matrices. - Example:
cx_mat A = randn<cx_mat>(5, 5); // complex matrix cx_mat B = randn<cx_mat>(4, 4); // complex matrix cx_mat C = randn<cx_mat>(3, 3); // complex matrix mat D = randn<mat>(6, 6); // real matrix cx_mat T1 = dsum(A, B, C, D); // direct sum of A, B, C, D // return type is deduced to be cx_mat std::vector<cx_mat> V = {A, B, C}; cx_mat T2 = dsum(V); // direct sum of A, B, C cx_mat T3 = dsum({A, B, C}); // same as above
dsum_pow(A, n)
- Direct sum power of a matrix.
- Returns A⊕n .
absm(A)
- Matrix absolute value of a square matrix.
-
A
has to be a square matrix (mat
orcx_mat
). - Returns
sqrtm_sym(A.t()*A)
. Return type is same as that ofA
.
schatten(A, p)
- Schatten p-norm of a matrix.
-
p
has to be greater than or equal to 0.
purify(A)
purify(A, tol)
- Minimal purification of a density matrix. Returns
vec
orcx_vec
depending on the type ofA
. -
tol
is optional. By default,tol
is equal to the floating point precision used in QIClib. See preprocessor macros in QIClib for details. Eigenvalues (ofA
) less thantol
are treated zero.
gram_schmidt(A)
gram_schmidt(A, normalize = true)
- Modified Gram-Schmidt orthogonalization.
-
A
can be either a matrix (mat
orcx_mat
) orstd::vector
/field
of vectors (vec
orcx_vec
). -
normalize
is optional. By default, it istrue
. If it isfalse
then orthogonal vectors will not be normalized.
conv_to_pure(A)
- To convert density matrix of a pure state to a column vector
(
vec
orcx_vec
). -
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). - If
A
is a column vector, then it is returned back unchanged. - If
A
is not a pure state, then eigenvector corresponding to highest eigenvalue is returned. To make sure, useis_pure
function first.
std_to_HS(A)
- To convert 2-qubit density matrix from the standard basis to the Hilbert-Schmidt (or Pauli) basis.
-
A
has to be a square matrix (mat
orcx_mat
) of 4x4. - Always returns a 4x4 fixed size real matrix (
mat44
).
HS_to_std(A)
- To convert 2-qubit density matrix from the Hilbert-Schmidt (or Pauli) basis to the standard basis.
-
A
has to be a real square matrix (mat
) of 4x4. - Always returns a 4x4 fixed size complex matrix (
cx_mat44
).
mket(mask)
mket<ELEM_TYPE>(mask)
mket(mask, dim)
mket<ELEM_TYPE>(mask, dim)
- To create multipartite qudit pure state in standard computational basis according to the
uvec
mask
. (See following example). -
ELEM_TYPE
is optional, by default, it isdouble
. It specifies the element type of returned column vector.ELEM_TYPE
can be real or complex types. -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Example:
vec A = mket({0, 0, 1}); // |001> state // each subsystem is qubit cx_vec B = mket<complex<double> >({0, 0, 1}); // same a above // but complex vector returned vec C = mket({0, 0, 1}, 2); // same a above vec D = mket({0, 2, 1}, {2, 3, 2}); //|021> state // 1st and 3rd party are qubit // 2nd one is qutrit cx_vec E = mket<complex<double> >({0, 2, 1},{2, 3, 2}); //same as above // but complex vector returned
mproj(mask)
mproj<ELEM_TYPE>(mask)
mproj(mask, dim)
mproj<ELEM_TYPE>(mask, dim)
- To create multipartite qudit projectors in standard computational basis according to the
uvec
mask
(See following example). -
ELEM_TYPE
is optional, by default, it isdouble
. It specifies the element type of returned matrix.ELEM_TYPE
can be real or complex types. -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Example:
mat A = mproj({0, 0, 1}); // |001><001| projector // each subsystem is qubit cx_mat B = mproj<complex<double> >({0, 0, 1}); // same a above // but complex matrix returned mat C = mproj({0, 0, 1}, 2); // same a above mat D = mproj({0, 2, 1}, {2, 3, 2}); //|021><021| projector // 1st and 3rd party are qubit // 2nd one is qutrit cx_mat E = mproj<complex<double> >({0, 2, 1},{2, 3, 2}); //same as above // but complex matrix returned
randU<ELEM_TYPE = double>(range = {0, 1})
randU<VEC_TYPE = vec>(n_elem, range = {0, 1})
randU<MAT_TYPE = mat>(n_rows, n_cols, range = {0, 1})
- To generate object with uniform random values in the range specified by the column vector
range
. By default, the range is in between0
to1
. - The first functions generate only one random element of type (real or complex) specified by
ELEM_TYPE
. By default,TYPE
isdouble
. - The second functions generate a row or column vector of type (with real or complex elements) specified by
VEC_TYPE
, withn_elem
number of elements. By default,VEC_TYPE
isvec
. - The third function generates a matrix of type (with real or complex elements) specified by
MAT_TYPE
, withn_rows
number of rows,n_cols
number of columns. By default,MAT_TYPE
ismat
. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
double a = randU(); // random number between 0 and 1 complex<double> b = randU<complex<double> >(); // complex random number // between (0,0) and (1,1) double c = randU({-5, 5}); // random number between -5 and 5 cx_vec V = randU<cx_vec>(10); // cx_vec with 10 elements cx_rowvec R = randU<cx_rowvec>(10, {-5, 5}); // cx_rowvec with 10 elements mat M1 = randU(10, 10); // 10x10 mat mat M2 = randU(10, 10, {-5, 5}); // 10x10 mat cx_mat M3 = randU<cx_mat>(10, 10, {-5, 5}); // 10x10 cx_mat
randN<ELEM_TYPE = double>(mean_sd = {0, 1})
randN<VEC_TYPE = vec>(n_elem, mean_sd = {0, 1})
randN<MAT_TYPE = mat>(n_rows, n_cols, mean_sd = {0, 1})
- To generate object with random values from normal distribution with mean and standard deviation specified by the
column vector
mean_sd
. By default, the mean and standard deviation are0
and1
respectively. - The first function generate only one random element of type (real or complex) specified by
ELEM_TYPE
. By defaultTYPE
isdouble
. - The second function generate a row or column vector of type (with real or complex elements) specified by
VEC_TYPE
, withn_elem
number of elements. By default,VEC_TYPE
isvec
. - The third function generate a matrix of type (with real or complex elements) specified by
MAT_TYPE
, withn_rows
number of rows,n_cols
number of columns. By default,MAT_TYPE
ismat
. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
double a = randN(); // random number from a normal distribution // with mean 0 and sd 1 complex<double> b = randN<complex<double> >(); // complex random number // from a normal distribution // with mean 0 and sd 1 double c = randN({-5, 5}); // random number from a normal distribution // with mean -5 and sd 5 cx_vec V = randN<cx_vec>(10); // cx_vec with 10 elements cx_rowvec R = randN<cx_rowvec>(10, {-5, 5}); // cx_rowvec with 10 elements mat M1 = randN(10, 10); // 10x10 mat mat M2 = randN(10, 10, {-5, 5}); // 10x10 mat cx_mat M3 = randN<cx_mat>(10, 10, {-5, 5}); // 10x10 cx_mat
randI<ELEM_TYPE = sword>(range = {0, 1000})
randI<VEC_TYPE = ivec>(n_elem, range = {0, 1000})
randI<MAT_TYPE = imat>(n_rows, n_cols, range = {0, 1000})
- To generate object with uniform random integers in the range specified by the column vector
range
. By default, the range is in between0
to1000
. - The first function generates only one random integer of type (real or complex)
specified by
ELEM_TYPE
. By defaultTYPE
issword
. - The second function generates a row or column vector of type (with real or complex elements) specified by
VEC_TYPE
, withn_elem
number of elements. By default,VEC_TYPE
isivec
. - The third function generates a matrix of type (with real or complex elements) specified by
MAT_TYPE
, withn_rows
number of rows,n_cols
number of columns. By default,MAT_TYPE
isimat
. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
sword a = randI(); // random integer (arma::sword) between 0 and 10000 int a1 = randI<int>(); // random integer (int) between 0 and 10000 complex<double> b = randI<complex<double> >(); // complex random integer // (type-casted to complex<double>) // between (0,0) and (1000,1000) sword c = randI({-100, 100}); // random integer (arma::sword) between -100 and 100 ivec V = randI(10); // ivec with 10 elements irowvec R = randI<irowvec>(10, {-100, 100}); // irowvec with 10 elements imat M1 = randI(10, 10); // 10x10 imat mat M2 = randI<mat>(10, 10, {-100, 100}); // 10x10 mat
randHermitian<ELEM_TYPE = complex<double> >(dim)
- To generate random Hermitian (
cx_mat
) or real symmetric matrix (mat
).dim
is an unsigned integer (uword
) specifying the dimension of the matrix. -
ELEM_TYPE
specifies the element type of the matrix (complex (or real) floating point type). By default, it iscomplex<double>
. IfELEM_TYPE
is real number (double
) the function generates random real symmetric matrix. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
cx_mat H1 = randHermitian(10); // 10x10 Hermitian cx_mat mat H2 = randHermitian<double>(10); // 10x10 real symmetric matrix
randUnitary<ELEM_TYPE = complex<double> >(dim)
- To generate random unitary (
cx_mat
) or real orthogonal matrix (mat
), uniformly distributed according to the Haar measure.dim
is an unsigned integer (uword
) specifying the dimension of the matrix. -
ELEM_TYPE
specifies the element type of the matrix (complex (or real) floating point type). By default, it iscomplex<double>
. IfELEM_TYPE
is real number (double
) the function generates random real orthogonal matrix. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
cx_mat U1 = randUnitary(10); // 10x10 Unitary cx_mat mat U2 = randUnitary<double>(10); // 10x10 real orthogonal matrix
randPsi<ELEM_TYPE = complex<double> >(dim)
- To generate random pure states (
cx_vec
orvec
), uniformly distributed according to the Haar measure.dim
is an unsigned integer (uword
) specifying the dimension of the state. -
ELEM_TYPE
specifies the element type of the matrix (complex (or real) floating point type). By default, it iscomplex<double>
. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
cx_vec psi1 = randPsi(10); // pure state (cx_vec) of dimension 10 vec psi2 = randPsi<double>(10); // real pure state (vec)
randPerm(n, start = 0)
- To generate random permutation of unsigned (positive) integers of size
n
. Returns auvec
. -
start
(uword
) is optional. It specifies starting point of the permutation. By default, it is 0. - To change the seed of the random number generator, use
rdevs.set_seed(YOUR_SEED)
. To set random seed, userdevs.set_seed_random()
. By default, the random number generator is instantiated with random seed. SeeRandomDevices
class for more details. - Example:
uvec perm1 = randPerm(5); // random permutation of {0,1,2,3,4} uvec perm2 = randPerm(5, 2); // random permutation of {2,3,4,5,6}
entropy(A)
- von Neumann entropy of a quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). - If
A
is a column vector, return value is always zero.
shannon(V)
- Shannon entropy of a probability distribution.
-
V
has to be a positive real column vector (vec
orstd::vector
of positive real numbers).
renyi(A, a)
- Renyi entropy of a quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
), anda
has to to greater than or equal to zero. - If
A
is a column vector, return value is always zero.
renyi_prob(V, a)
- Renyi entropy of a probability distribution.
-
V
has to be a positive real column vector (vec
orstd::vector
of positive real numbers), anda
has to to greater than or equal to zero.
tsallis(A, a)
- Tsallis entropy of a quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
), anda
has to to greater than or equal to zero. - If
A
is a column vector, return value is always zero.
tsallis_prob(V, a)
- Tsallis entropy of a probability distribution.
-
V
has to be a positive real column vector (vec
orstd::vector
of positive real numbers), anda
has to to greater than or equal to zero.
mutual_info(A, dim)
mutual_info(A, subsys1, subsys2)
mutual_info(A, subsys1, subsys2, dim)
- Quantum mutual information between 2 subsystems of a quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). - In the first case,
dim
has to be auvec
of two elements, containing the dimensions of two subsystems. - In the second case,
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem.subsys1
andsubsys1
areuvec
containing the indices parties that constitute of 1st partition and 2nd partition respectively. - Indices in
subsys1
andsubsys2
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
cx_mat A = randRho(12); // 12x12 density matrix cx_mat B = randRho(16); // 16x16 density matrix // mutual_info between two parties with dim 4 and 3 double A1 = mutual_info(A, {4, 3}); // 1st party has dim=4, // 2nd party has dim=3 // mutual_info between 1,3 and 2,4 parties double B1 = mutual_info(B, {1, 3}, {2, 4}); double B2 = mutual_info(B, {1, 3}, {2, 4}, 2); //same as above // all party has dim = 2 double B1 = mutual_info(B, {1, 3}, {2, 4}, {2, 2, 2, 2}); // same as above // explicitly written dimensions
rel_entropy(A, B)
- Relative entropy of between two quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). Same forB
.
rel_entropy_prob(V1, V2)
- Relative entropy of between two probability distribution.
-
V1
andV2
have to be positive real column vectors of same type (vec
orstd::vector
of positive real numbers).
entanglement(A, dim)
- Entanglement entropy of a pure quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
), anddim
has to be auvec
of two elements, containing the dimensions of two subsystems.. - If
A
is a square matrix and not a density matrix of a pure state, then von Neumann entropy of traced out 2nd party density matrix is returned. To make sure useis_pure
function first.
neg(A, subsys)
neg(A, subsys, dim)
- Negativity of a quantum state, where
subsys
is auvec
containing the indices of transposed subsystems. -
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
cx_mat A = randRho(8); // 8x8 density matrix cx_mat B = randRho(12); // 12x12 density matrix // negativity by transposing 2nd and 3rd party double A1 = neg(A, {2, 3}); // all dim are 2, total 3 parties // negativity by transposing 2nd and 3rd party double B1 = neg(B, {2, 3}, {2, 3, 2}); // explicitly written dimensions
log_neg(A, subsys)
log_neg(A, subsys, dim)
- Logarithmic negativity of a quantum state, where
subsys
is auvec
containing the indices of transposed subsystems. -
A
has to be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
cx_mat A = randRho(8); // 8x8 density matrix cx_mat B = randRho(12); // 12x12 density matrix // logarithmic negativity by transposing 2nd and 3rd party double A1 = log_neg(A, {2, 3}); // all dim are 2, total 3 parties // logarithmic negativity by transposing 2nd and 3rd party double B1 = log_neg(B, {2, 3}, {2, 3, 2}); // explicitly written dimensions
concurrence(A)
- Concurrence of a two-qubit quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) of dimension 4.
EoF(A)
- Entanglement of formation of a two-qubit quantum state.
-
A
has to be a square matrix (mat
orcx_mat
) or column vector (vec
orcx_vec
) of dimension 4.
ent_check_CMC(A, dim)
ent_check_CMC(A, dim1, dim2)
- To check if a bipartite state is entangled or not (based on covariant matrix criteria (Phys. Rev. A 78, 052319 (2008), Proposition IV.2), can be used to detect bound entangled states)
-
A
has to be a square matrix (mat
orcx_mat
). - Returns
true
ifA
is entangled, elsefalse
. - The first form assumes both the subsystems have same dimension.
dim
is an unsigned integer type (uword
) stating the dimensions of both the subsystems. - The second case applies if the subsystems have different dimensions.
dim1
anddim2
are unsigned integer types (uword
) stating the dimensions of 1st and 2nd party respectively.
vec S = schmidt(A, dim)
schmidt(A, dim, S, U, V)
schmidt_full(A, dim, S, U, V)
- Schmidt decomposition of a bipartite pure state.
-
A
has to be a square matrix (mat
orcx_mat
) or column vector (vec
orcx_vec
). -
dim
is auvec
of two elements, containing dimensions of each party. -
S
is a real vector containing Schmidt coefficients.U
andV
are matrices that store Schmidt vectors column-wise, such thatA = Σi S(i) * kron(U.col(i), V.col(i))
. -
schmidt_full
gives full Schmidt basis on both sides (i.e.,U
andV
). - If
A
is a square matrix, then it is translated into a column vector usingconv_to_pure
. - If decomposition fails then
vec S = schmidt(A,dim)
throwsstd::runtime_error
exception, andschmidt(A,dim,S,U,V)
andschmidt_full(A,dim,S,U,V)
returnsfalse
and resetsS
,U
, andV
. - Example:
cx_vec A = randPsi(8); // 8 dimensional pure state vec S1 = schmidt(A, {2, 4}); vec S; cx_mat U,V; schmidt(A, {2, 4}, S, U, V);
schmidtA(A, dim)
schmidtA_full(A, dim)
schmidtB(A, dim)
schmidtB_full(A, dim)
schmidtAB(A, dim)
schmidtAB_full(A, dim)
- Schmidt vectors of a bipartite pure state.
-
A
has to be a square matrix (mat
orcx_mat
) or column vector (vec
orcx_vec
). -
dim
is auvec
of two elements, containing dimensions of each party. - If
A
is a square matrix, then it is translated into a column vector usingconv_to_pure
. -
schmidtA(A,dim)
returns truncated Schmidt basis on Alice's side in a column-wise manner, whileschmidtA_full(A,dim)
returns full Schmidt basis on Alice's side. -
schmidtB(A,dim)
returns truncated Schmidt basis on Bob's side in a column-wise manner, whileschmidtB_full(A,dim)
returns full Schmidt basis on Bob's side. -
schmidtAB(A,dim)
returnsfield
of matrices containing truncated Schmidt basis on both sides in a column-wise manner, whileschmidtAB_full(A,dim)
returnsfield
of matrices containing full Schmidt basis on both side. - If decomposition fails then these functions throw
std::runtime_error
exception. - Example:
cx_mat A = randPsi(8); // 8 dimensional pure state cx_mat V = schmidtB(A, {2, 4}); // V is 4x2 matrix cx_mat Vf = schmidtB_full(A, {2, 4}); // Vf is 4x4 matrix field<cx_mat> AB = schmidtAB(A, {2, 4}); //AB(0) == Schmidt basis on Alice's side //AB(1) == Schmidt basis on Bob's side
l1_coh(A)
l1_coh(A, U)
- l1-norm coherence of a quantum state.
-
A
can be either a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
U
is a Unitary matrix (mat
orcx_mat
) to rotate the state for obtaining coherence with respect to the desired basis.
rel_entropy_coh(A)
rel_entropy_coh(A, U)
- Relative entropy of coherence of a quantum state.
-
A
can be either a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
U
is a Unitary matrix (mat
orcx_mat
) to rotate the state for obtaining coherence with respect to the desired basis.
HS_dist(A, B)
- Hilbert-Schmidt distance between two density matrices.
-
A
andB
have to be square matrices (mat
orcx_mat
) of same dimension.
tr_dist(A, B)
- Trace distance between two density matrices.
-
A
andB
have to be square matrices (mat
orcx_mat
) of same dimension.
Bures_dist(A, B)
- Bures distance between two density matrices.
-
A
andB
have to be square matrices (mat
orcx_mat
) of same dimension.
fidelity(A, B)
- Fidelity between two density matrices.
-
A
andB
have to be square matrices (mat
orcx_mat
) of same dimension.
apply(A, U, subsys)
apply(A, U, subsys, dim)
apply(A, Ks, subsys, dim)
apply(A, Ks)
- To apply a quantum gate
U
or a set of Kraus operatorsKs
to a quantum stateA
. -
A
has be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
U
has to a square matrix (mat
orcx_mat
), andKs
can be afield
or astd::vector
of square matrices (mat
orcx_mat
) having same dimensions. - In the first three cases,
subsys
is auvec
containing the indices of subsystems, where the gate or the Kraus operators will be applied. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - In the first three cases, the dimension of the gate
U
or the Kraus operatorsKs
must match the dimension of subsystems specified insubsys
. -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - In the last case, the set of Kraus operators
Ks
acts on the whole quantum stateA
. The dimension of the Kraus operatorsKs
must match the dimension of the quantum stateA
. - Note: Return type is deduced from the element types of
A
andU
/Ks
. For simplicity useauto
to deduce the return type. - Example:
cx_mat A = randRho(8); // 8x8 density matrix cx_mat B = randRho(2); // 2x2 density matrix const mat& U1 = spm.S(1); // \sigma_x gate cx_mat U2 = kron(spm.S(1),spm.S(1)); // kron(\sigma_x,\sigma_x) gate vector<cx_mat> BF = {(1 - 0.25) * spm.S(0), 0.25 * spm.S(1)}; // Kraus operators for Bit-Flip channel with p = 0.25 cx_mat A1 = apply(A, U1, {2}); // all dim are 2, total 3 parties cx_mat A2 = apply(A, U2, {1, 3}, {2, 2, 2}); // explicitly written dimensions cx_mat A3 = apply(A, BF, {2}, {2, 2, 2}); // apply Bit-Flip on 2nd party cx_mat B1 = apply(B, BF); // apply Bit-Flip on B
apply_ctrl(A, U, ctrl, subsys)
apply_ctrl(A, U, ctrl, subsys, dim)
- To apply a quantum gate
U
to a quantum stateA
as a controlled gate.subsys
is auvec
containing the indices subsystems, where the gate will be applied, andctrl
is auvec
containing the indices of control subsystems. -
A
has be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
U
to has be a square matrix (mat
orcx_mat
) and the dimension of gateU
must match the dimension of subsystems specified insubsys
. - All control subsystems must have same dimensions.
-
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
andctrl
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Note: Return type is deduced from the element types of
A
andU
. For simplicity useauto
to deduce the return type. - Example:
cx_mat A = randRho(8); // 8x8 density matrix const mat& U1 = gates.X; // \sigma_x gate mat U2 = kron(gates.X, gates.X); // kron(\sigma_x,\sigma_x) gate cx_mat A1 = apply_ctrl(A, U1, {1}, {2}); // all dim are 2, total 3 parties cx_mat A2 = apply_ctrl(A, U2, {2}, {1, 3}, {2, 2, 2}); // explicitly written dimensions
make_ctrl(U, ctrl, subsys, n, dim = 2)
make_ctrl(U, ctrl, subsys, dim)
- To convert a quantum gate
U
into a controlled quantum gate.subsys
is auvec
containing the indices subsystems, where the gate will be applied, andctrl
is auvec
containing the indices of control subsystems. -
U
to has be a square matrix (mat
orcx_mat
) and the dimension of gateU
must match the dimension of subsystems specified insubsys
. - All control subsystems must have same dimensions.
- In the first case,
n
is auword
mentioning total number of subsystems, having same dimensions equal todim
(uword
). By default,dim
is 2. - In the second case,
dim
is auvec
containing dimensions of every subsystem. These form is needed if different subsystems have different dimensions. - Indices in
subsys
andctrl
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
const mat& U = gates.X; // \sigma_x gate mat CU1 = make_ctrl(U, {1}, {2}, 2); // make two-party controlled X gate // where 1st party is control and // second party is target. // Here, n = 2 and // dim = 2 (by default) mat CU2 = make_ctrl(U, {1}, {2}, {2, 2}); //same as above // explicitly written dimensions
std::tuple<uword, vec, field<MATRIX_TYPE> > result = measure(cx_mat A, Ks)
std::tuple<uword, vec, field<MATRIX_TYPE> > result = measure(mat A, Ks)
std::tuple<uword, vec, field<MATRIX_TYPE> > result = measure(cx_mat A, Ks, subsys, dim)
std::tuple<uword, vec, field<MATRIX_TYPE> > result = measure(mat A, Ks, subsys, dim)
- To measure a quantum state
A
using a set of Kraus or projection operatorsKs
. Returnsstd::tuple
of: 1. result of the measurement (uword
), 2. vector of outcome probabilities (vec
), and 3.field
of post-measurement normalized states (field<cx_mat>
orfield<mat>
). -
A
has be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). -
Ks
can be astd::vector
or afield
of Kraus or projection operators (eithercx_mat
,mat
,cx_vec
orvec
). It can also be acx_mat
ormat
, where each column will be treated as projection operators. - First two functions measure the whole quantum state
A
, and the dimension of the operators inKs
must match the dimension ofA
. - Last two functions partially measure the subsystems of the state
A
. The indices of measured subsystems are specified insubsys
(uvec
). The dimension of the operators inKs
must match the dimension of subsystems specified insubsys
. - All Kraus or projection operators must have same dimensions.
-
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Note:
MATRIX_TYPE
is deduced from the element types ofA
andKs
. For simplicity useauto
to deduce return type. - Example:
cx_mat A1 = randRho(2); // 2x2 random density matrix std::vector
Ks = {spm.basis2(0,1), spm.basis2(1,1)}; // std::vector of projection operators in \sigma_x direction auto result1 = measure(A1, Ks); // measurement std::get<0>(A1); // measurement result std::get<1>(A1); // outcome probabilities std::get<2>(A1); // post measurement normalised states cx_mat A2 = randRho(8); //8x8 random density matrix auto result2 = measure(A2, Ks, {2}, {2,2,2}); measure the 2nd party
std::tuple<uword, vec> result = measure_comp(A)
std::tuple<uword, vec> result = measure_comp(A, subsys, dim)
- To measure a quantum state
A
in the computational basis. Returnsstd::tuple
of: 1. result of the measurement (uword
) and 2. vector of outcome probabilities (vec
). -
A
has be a square matrix (mat
orcx_mat
) or a column vector (vec
orcx_vec
). - The first function measures the whole quantum state, where as the last function partially measures the subsystems of the state
A
, where the indices of measured subsystems are specified insubsys
. -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem. - Indices in
subsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. - Example:
cx_mat A1 = randRho(2); // 2x2 random density matrix auto result1 = measure_comp(A1); // measurement std::get<0>(A1); // measurement result std::get<1>(A1); // outcome probabilities cx_mat A2 = randRho(8); //8x8 random density matrix auto result2 = measure_comp(A2, {2}, {2,2,2}); measure the 2nd party
Classes for Quantum Discord like features
- Note: These features depend on NLopt.
- Note: If you want to use old API's for discord like function, define
QICLIB_USE_OLD_DISCORD
macro before includingQIClib
header. See preprocessor macros in QIClib for details. Old API's for discord like functions are not maintained anymore.
discord_space<MATRIX_TYPE>
deficit_space<MATRIX_TYPE>
discord_space
provides computational space for calculating quantum discord (actual as well as constrained-regular, as discussed in Phys. Rev. A 92, 062301 (2015), Sec. III.A, Case 4) for quantum states when measurement is done over a qubit or qutrit system,deficit_space
does the same for one-way quantum work deficit. Both have same syntaxes, so for the demonstration purpose, we will talk aboutdiscord_space
only.- Works for real or complex density matrices (
mat
orcx_mat
).MATRIX_TYPE
denotes the the data type of the density matrix i.e.,mat
orcx_mat
. - Constructors:
discord_space<MATRIX_TYPE>(A, subsys, dim)
discord_space<MATRIX_TYPE>(A, subsys)
-
A
is a square matrix of typeMATRIX_TYPE
. -
subsys
is a unsigned integer type (uword
), which denotes the index of measured subsystem. Indices forsubsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. -
dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem.dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem.
-
- Member functions:
-
.result()
: Computes quantum discord, and returns the result. This function will keep the value cached in the memory. Further use of this function will return the cached value, rather than computing discord all over again. -
.result_reg()
: Computes constrained-regular quantum discord, and returns the result. This function will keep the value cached in the memory. Further use of this function will return the cached value, rather than computing constrained-regular quantum discord all over again. -
.compute()
: Computes quantum discord whenever called. This function will rewrite the cached result to the new one. One can use.result()
to get the new value (see the following example). -
.compute_reg()
: Computes constrained-regular quantum discord whenever called. This function will rewrite the cached result to the new one. One can use.result_reg()
to get the new value (see the following example). -
.reset()
: This will reset the state ofdiscord_space
to the default settings. All cached values will be forgotten. -
.reset(subsys)
: This will reset the state ofdiscord_space
to the default settings. All cached values will be forgotten.subsys
is a unsigned integer type (uword
), which denotes the index of new measured subsystem. Indices forsubsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on. -
.reset(A, subsys, dim)
: This will reset the state ofdiscord_space
to the default settings. All cached values will be forgotten.A
is the new density matrix (square matrix) of typeMATRIX_TYPE
.subsys
is a unsigned integer type (uword
), which denotes the index of new measured subsystem. Indices forsubsys
start from 1, i.e., first party has the index 1, second party has the index 2 and so on.dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem.dim
is optional. It can be either unsigned integer type (uword
) oruvec
containing dimensions of every subsystem. When it is unsigned integer type, all subsystems are supposed to have same dimensions (equal todim
). By default, it is 2. If different subsystems have different dimensions, usedim
as auvec
containing dimensions of every subsystem.
-
- Helper member functions: These functions are there to change the settings of the optimization processes done
by NLopt, to fine tune the result. In general, users can overlook
these functions, and default settings will be used.
-
.use_global_opt(bool a = true)
: Set whether global optimization will be performed (true
) or not (false
). -
.global_algorithm(nlopt::algorithm a = nlopt::GN_DIRECT_L_RAND)
: Set global optimization algorithm. -
.global_xtol(double a)
: Set global optimization xtol. By default, it is4e-2
for qubit systems, and0.25
for qutrit systems. -
.global_ftol(double a = 0)
: Set global optimization ftol. -
.local_algorithm(nlopt::algorithm a = nlopt::LN_COBYLA)
: Set local optimization algorithm. -
.local_xtol(double a)
: Set local optimization xtol. -
.local_ftol(double a = 0)
: Set local optimization ftol. -
.angle_range(const vec& a)
: Set the ranges of angles (parameters of unitary matrices) as multiples of π. For qubit systems, default is{1, 2}
, and for qutrit systems, default is{2, 2, 2, 2, 2}
. -
.initial_angle(const vec& a)
: Set the initial values of angles as multiples of π. For qubit systems, default is{0.1, 0.1}
, and for qutrit systems, default is{0.1, 0.1, 0.1, 0.1, 0.1}
.
-
- Example:
cx_mat A = randRho(8); // 8x8 density matrix (3-qubit) // create discord_space, we measure the 2nd party to compute discord discord_space
DSpace(A, {2}); // calculate discord double DResult = DSpace.result(); // change local optimization algorithm, // then compute the discord, // and get the result in one line ---> double DResult = DSpace.local_algorithm(nlopt::LN_SBPLX).compute().result(). cx_mat B = randRho(12); // new 2x3x2 density matrix // using same discord_space for new density matrix, // measurement on 2nd party (qutrit) DSpace.reset(B, {2}, {2, 3, 2}); double new_DResult = Dspace.result();
Frequently asked questions
- What are the basic dependencies of QIClib?
- How do I use QIClib in my project?
See getting started section. - How do I report bugs?
See this. - How do I use XYZ function properly?
See API documentation. If you still have concerns, see this. - Can you implement certain features, which are useful for my work?
Yes, see this. - Instead of using other popular C++ linear algebra libraries, why did QIClib choose Armadillo?
- Armadillo is fast, efficient and reliable.
- It has nice API, which is deliberately similar to Matlab.
- It supports modern C++11 features, like move semantics or initialiser list initialization, which indeed increase efficiency and usability.
- It has rapid developement process.
- It can make use of high performance multi-threaded LAPACK and BLAS replacements like OpenBLAS, Intel MKL, or AMD ACML.
- I know C++98, but do not know much about C++11. Can I use QIClib?
Yes. Though QIClib is written in C++11 standard, you can still do C++98 style coding with QIClib functions. You just need a C++11 compliant compiler and make sure that you add necessary compiler flag to enable C++11 features, e.g., in gcc or clang add-std=c++11
flag during compilation. - Can I use C++11
auto
with QIClib functions?
Though use of C++11auto
is not recommended with Armadillo expressions, due to the extensive use of template meta-programming, every QIClib functions return by value, so use ofauto
is safe there. In fact, use ofauto
is recommended with QIClib functions and objects, as it will always guarantee move operations. But again, care should be taken whenauto
is used with Armadillo expressions. See the following example:
cx_mat A = randn<cx_mat>(8,8); A *= A.t(); A /= trace(A); auto B = A; // OK, no temporary expression auto C = TrX(A,{1},{2,2,2}); // OK, QIClib function auto D = powm_sym(A,3); // OK, QIClib function auto E = A * A; // NOT OK!! temporary expression auto F = A + B + D ; // NOT OK!! temporary expression auto G = A * A.t(); // NOT OK!! temporary expression vec V = {0,1,2,3,4}; for(auto&& i : V) // OK, no temporary exression { // do something } for(auto&& i : V+V) // NOT OK!! temporary expression { // do something } auto& S1 = spm.S(1); // OK and recommended const cx_mat& S2 = spm.S(2); // also OK
- Does QIClib use C++14 features?
No, only C++11 features have been used. C++14 features like auto return type deductions for functions have been avoided by using template meta-programming. But users are requested to use latest C++14/17 features, which increase efficiency and usability. - Does QIClib use multi-threaded algorithms for computations?
Yes and No. There are several ways to develop multi-threaded or parallel applications using QIClib.- Using high performance multi-threaded LAPACK and BLAS replacements like OpenBLAS, Intel MKL, or AMD ACML.
- Loop parallelization using OpenMP or others similar libraries.
- TrX, Tx, sysperm, apply,
apply_ctrl, make_ctrl, measure,
and measure_comp have optional multi-threaded algorithms if
OpenMP is enabled in compiler argument, i.e.,
-fopenmp
in gcc or clang. For this, defineQICLIB_USE_OPENMP
macro before before includingQIClib
header. One can individually enable multi-threading in those mentioned functions. For this, see preprocessor macros in QIClib for details.
Helper preprocessor macros
QIClib can be configured by defining following macros before including
QIClib
header.
QICLIB_MAXQDIT_COUNT | Maximum number of qudits that can be handled by QIClib. By default, it is 40. | |
QICLIB_FLOAT_PRECISION | Precision for float . By default, it is
100.0 * std::numeric_limits<float>::epsilon() . | |
QICLIB_DOUBLE_PRECISION | Precision for double . By default, it is
100.0 * std::numeric_limits<double>::epsilon() . | |
QICLIB_NO_INIT_MESSAGE | Disable printing of messages by Init
class. | |
QICLIB_NO_SPM | Disable instantiation of SPM
class. | |
QICLIB_NO_GATES | Disable instantiation of GATES
class. | |
QICLIB_DONT_USE_NLOPT | QIClib will not use NLopt dependent features. | |
QICLIB_USE_OLD_DISCORD | QIClib will use old discord syntaxes (before version 1.0.0). | |
QICLIB_USE_OPENMP | QIClib will use multi-threaded algorithms for TrX, Tx, sysperm, apply, apply_ctrl, make_ctrl, measure, and measure_comp if OpenMP is enabled. | |
QICLIB_USE_OPENMP_TRX | QIClib will use multi-threaded algorithm for TrX if OpenMP is enabled. | |
QICLIB_USE_OPENMP_TX | QIClib will use multi-threaded algorithm for Tx if OpenMP is enabled. | |
QICLIB_USE_OPENMP_SYSPERM | QIClib will use multi-threaded algorithm for sysperm if OpenMP is enabled. | |
QICLIB_USE_OPENMP_APPLY | QIClib will use multi-threaded algorithms for apply and apply_ctrl if OpenMP is enabled. | |
QICLIB_USE_OPENMP_MAKE_CTRL | QIClib will use multi-threaded algorithm for make_ctrl if OpenMP is enabled. | |
QICLIB_USE_OPENMP_MEASURE | QIClib will use multi-threaded algorithms for measure and measure_comp if OpenMP is enabled. |
API Additions
Version 1.0
- Bug fix in
tsallis_prob
. - Added
gram_schmidt
. - Added
dense_to_sparse
,sparse_to_dense
. - Added
discord_space
,deficit_space
. - Added
is_Normal
. - Added
rel_entropy
,rel_entropy_prob
. - Added coherence measures,
l1_coh
andrel_entropy_coh
. - Added
schmidt_full
. - Added macro features to fine tune the library behavior.
std::runtime_error
exception foreig_sym/eig_gen
decomposition.std::runtime_error
exception forqr
decomposition.- Added
randPerm
. - Added
make_ctrl
. - Default template parameter of
mket
,mproj
is nowdouble
. - Optional multi-threaded algorithm for TrX, Tx, sysperm, apply, apply_ctrl, make_ctrl, measure, and measure_comp.
- Added
purify
,std_to_HS
, andHS_to_std
. - Added
measure
andmeasure_comp
. - Added random number/matrix generators.
- Added
is_diagonalizable
. - Faster
is_equal
,is_Hermitian
,is_Unitary
,is_pure
,is_valid_state
. - Fixed a bug in discord like functions.
Version 0.0.3
Go to top
Version 0.0.2
Go to top