quairkit.qinfo.linalg¶
- quairkit.qinfo.linalg.abs_norm(mat)¶
Tool for calculation of matrix norm.
- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
matrix
- Returns:¶
norm of input matrix
- Return type:¶
float
Examples
abs_nor = abs_norm(eye(2) / 2) print(f'The abs norm is:\n{abs_nor}')
The abs norm is: 0.7071067690849304
-
quairkit.qinfo.linalg.block_enc_herm(mat, num_block_qubits=
1
)¶ Generate a (qubitized) block encoding of Hermitian
mat
.Examples
block_enc = block_enc_herm(x()) print(f'The block encoding of X is:\n{block_enc}')
The block encoding of X is: tensor([[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j], [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]])
-
quairkit.qinfo.linalg.create_matrix(linear_map, input_dim, input_dtype=
None
)¶ Create a matrix representation of a linear map without needing to specify the output dimension.
This function constructs a matrix representation for a given linear map and input dimension.
- Parameters:¶
- Returns:¶
A matrix representing the linear map.
- Raises:¶
RuntimeWarning – the input linear_map may not be linear.
- Return type:¶
ndarray | Tensor
Examples
def f(X): return X[0] + X[1] mat_repr = create_matrix(f, input_dim=2) print(f'The matrix representation is:\n{mat_repr}')
The matrix representation is: tensor([1.+0.j, 1.+0.j])
- quairkit.qinfo.linalg.dagger(mat)¶
Tool for calculation of matrix dagger.
- Parameters:¶
- mat : ndarray | Tensor¶
matrix
- Returns:¶
The dagger of matrix
- Return type:¶
ndarray | Tensor
Examples
dag = dagger(t()) print(f'The dagger of this matrix is:\n{dag}')
The dagger of this matrix is: tensor([[1.0000-0.0000j, 0.0000-0.0000j], [0.0000-0.0000j, 0.7071-0.7071j]])
- quairkit.qinfo.linalg.direct_sum(A, B)¶
Calculate the direct sum of A and B.
- Parameters:¶
- Returns:¶
A direct sum of A and B, with shape \((m + p) \times (n + q)\)
- Return type:¶
ndarray | Tensor
Examples
dir_sum = direct_sum(x(), y()) print(f'The direct sum is:\n{dir_sum}')
The direct sum is: tensor([[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], [0.+0.j, 0.+0.j, 0.+0.j, -0.-1.j], [0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j]])
- quairkit.qinfo.linalg.gradient(loss_function, var, n)¶
Compute the gradient of a given loss function with respect to its input variable.
Examples
def quadratic_loss(x: torch.Tensor) -> torch.Tensor: # loss function is: L(x) = x₁² + 2x₂² + 3x₃² return x[0]**2 + 2 * x[1]**2 + 3 * x[2]**3 var = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True) grad = gradient(quadratic_loss, var, n=1) print(f"Input variable is:\n{var}") print(f"Computed gradient is:\n{grad}")
Input variable is: tensor([[1.], [2.], [3.]], requires_grad=True) Computed gradient is: tensor([[ 2.], [ 8.], [81.]], grad_fn=<CopySlices>)
- quairkit.qinfo.linalg.hessian(loss_function, var)¶
Compute the Hessian matrix of a given loss function with respect to its input variables.
Examples
def quadratic_loss(x: torch.Tensor) -> torch.Tensor: # loss function is: L(x) = x₁² + 2x₂² + 3x₃² return x[0]**2 + 2 * x[1]**2 + 3 * x[2]**3 var = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True) hes = hessian(quadratic_loss, var) print(f"Input variable is:\n{var}") print(f"Computed Hessian is:\n{hes}")
Input variable is: tensor([[1.], [2.], [3.]], requires_grad=True) Computed Hessian is: tensor([[[ 2., 0., 0.], [ 0., 4., 0.], [ 0., 0., 54.]]])
-
quairkit.qinfo.linalg.herm_transform(fcn, mat, ignore_zero=
False
)¶ Function transformation for a Hermitian matrix.
- Parameters:¶
- fcn : Callable[[float], float]¶
A function \(f\) that can be expanded by Taylor series.
- mat : ndarray | Tensor | PureState | MixedState¶
Hermitian matrix \(H\).
- ignore_zero : bool | None¶
Whether to ignore eigenspaces with zero eigenvalue. Defaults to False.
- Returns:¶
\(f(H)\)
- Return type:¶
ndarray | Tensor
Examples
fH = herm_transform(math.exp, eye(2)) print(f'The result is:\n{fH}')
The result is: tensor([[2.7183+0.j, 0.0000+0.j], [0.0000+0.j, 2.7183+0.j]])
- quairkit.qinfo.linalg.kron_power(matrix, n)¶
Calculate the Kronecker product of identical matrices.
- Parameters:¶
- matrix : ndarray | Tensor | PureState | MixedState¶
The matrix to be powered.
- n : int¶
The number of identical matrices.
- Returns:¶
Kronecker product of n identical matrices.
- Return type:¶
ndarray | Tensor
Examples
kp = kron_power(x(), 2) print(f'The Kronecker product of 2 X is:\n{kp}')
The Kronecker product of 2 X is: tensor([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j], [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j], [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])
- quairkit.qinfo.linalg.logm(mat)¶
Calculate the logarithm of a matrix.
- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
Input matrix.
- Returns:¶
The matrix of natural base logarithms.
- Return type:¶
ndarray | Tensor
Examples
lgm = logm(x()) print(f'The log of X is:\n{lgm}')
The log of X is: tensor([[-1.8562e-16+1.5708j, 1.8562e-16-1.5708j], [ 1.8562e-16-1.5708j, -1.8562e-16+1.5708j]])
- quairkit.qinfo.linalg.nkron(matrix_1st, *args)¶
Calculate the Kronecker product of matrices.
- Parameters:¶
- matrix_1st : ndarray | Tensor | PureState | MixedState¶
The first matrix.
- args : ndarray | Tensor | PureState | MixedState¶
Other matrices.
- Returns:¶
Kronecker product of the given matrices.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
A = random_state(1) B = random_state(1) C = random_state(1) result = nkron(A, B, C) print(f'The result is:\n{result}')
The result is: ----------------------------------------------------- Backend: density_matrix System dimension: [2, 2, 2] System sequence: [0, 1, 2] [[ 0.02+0.j 0.01-0.01j -0.01+0.j -0.-0.01j 0.04+0.04j 0.05-0.01j -0.04-0.03j -0.04+0.02j] [ 0.01+0.01j 0.01-0.j -0.01-0.01j -0.01+0.j -0.01+0.05j 0.04+0.03j -0.-0.04j -0.03-0.02j] [-0.01-0.j -0.01+0.01j 0.02+0.j 0.01-0.02j -0.03-0.04j -0.04+0.j 0.06+0.06j 0.07-0.02j] [-0.-0.01j -0.01-0.j 0.01+0.02j 0.02-0.j 0.02-0.04j -0.02-0.03j -0.01+0.08j 0.05+0.05j] [ 0.04-0.04j -0.01-0.05j -0.03+0.04j 0.02+0.04j 0.21-0.j 0.1-0.16j -0.16+0.03j -0.06+0.14j] [ 0.05+0.01j 0.04-0.03j -0.04-0.j -0.02+0.03j 0.1+0.16j 0.18-0.j -0.11-0.11j -0.14+0.03j] [-0.04+0.03j -0.-0.04j 0.06-0.06j -0.01-0.08j -0.16-0.03j -0.11+0.11j 0.29-0.j 0.15-0.23j] [-0.04-0.02j -0.03+0.02j 0.07+0.02j 0.05-0.05j -0.06-0.14j -0.14-0.03j 0.15+0.23j 0.25-0.j ]] -----------------------------------------------------
- quairkit.qinfo.linalg.NKron(matrix_1st, *args)¶
Calculate the Kronecker product of matrices.
- Parameters:¶
- matrix_1st : ndarray | Tensor | PureState | MixedState¶
The first matrix.
- args : ndarray | Tensor | PureState | MixedState¶
Other matrices.
- Returns:¶
Kronecker product of the given matrices.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
A = random_state(1) B = random_state(1) C = random_state(1) result = nkron(A, B, C) print(f'The result is:\n{result}')
The result is: ----------------------------------------------------- Backend: density_matrix System dimension: [2, 2, 2] System sequence: [0, 1, 2] [[ 0.02+0.j 0.01-0.01j -0.01+0.j -0.-0.01j 0.04+0.04j 0.05-0.01j -0.04-0.03j -0.04+0.02j] [ 0.01+0.01j 0.01-0.j -0.01-0.01j -0.01+0.j -0.01+0.05j 0.04+0.03j -0.-0.04j -0.03-0.02j] [-0.01-0.j -0.01+0.01j 0.02+0.j 0.01-0.02j -0.03-0.04j -0.04+0.j 0.06+0.06j 0.07-0.02j] [-0.-0.01j -0.01-0.j 0.01+0.02j 0.02-0.j 0.02-0.04j -0.02-0.03j -0.01+0.08j 0.05+0.05j] [ 0.04-0.04j -0.01-0.05j -0.03+0.04j 0.02+0.04j 0.21-0.j 0.1-0.16j -0.16+0.03j -0.06+0.14j] [ 0.05+0.01j 0.04-0.03j -0.04-0.j -0.02+0.03j 0.1+0.16j 0.18-0.j -0.11-0.11j -0.14+0.03j] [-0.04+0.03j -0.-0.04j 0.06-0.06j -0.01-0.08j -0.16-0.03j -0.11+0.11j 0.29-0.j 0.15-0.23j] [-0.04-0.02j -0.03+0.02j 0.07+0.02j 0.05-0.05j -0.06-0.14j -0.14-0.03j 0.15+0.23j 0.25-0.j ]] -----------------------------------------------------
- quairkit.qinfo.linalg.p_norm(mat, p)¶
Calculate the Schatten p-norm of a matrix.
- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
matrix
- p : ndarray | Tensor | Iterable[float] | float¶
p-norm parameter
- Returns:¶
p-norm of input matrix
- Return type:¶
ndarray | Tensor
Examples
p_nor = p_norm(x(), p=2) print(f'The 2-norm of X is:\n{p_nor}')
The 2-norm of X is: 1.4142135381698608
-
quairkit.qinfo.linalg.partial_trace(state, trace_idx, system_dim=
2
)¶ Calculate the partial trace of the quantum state.
- Parameters:¶
- state : ndarray | Tensor | PureState | MixedState¶
Input quantum state.
- trace_idx : List[int] | int¶
The system indices to be traced out.
- system_dim : List[int] | int¶
The dimension of all systems. Defaults to the qubit case.
- Returns:¶
Partial trace of the quantum state with arbitrarily selected subsystem.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
pt = partial_trace(bell_state(2), 0, [2, 2]) print(f'The partial trace of Bell state is:\n{pt}')
The partial trace of Bell state is: ----------------------------------------------------- Backend: density_matrix System dimension: [2] System sequence: [0] [[0.5+0.j 0. +0.j] [0. +0.j 0.5+0.j]] -----------------------------------------------------
-
quairkit.qinfo.linalg.partial_trace_discontiguous(state, preserve_qubits=
None
)¶ Calculate the partial trace of the quantum state with arbitrarily selected subsystem.
- Parameters:¶
- state : ndarray | Tensor | PureState | MixedState¶
Input quantum state.
- preserve_qubits : List[int]¶
Remaining qubits; if None, all qubits are preserved.
- Returns:¶
Partial trace of the quantum state with arbitrarily selected subsystem.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
ptdis = partial_trace_discontiguous(bell_state(2), [0]) print(f'The partial trace of Bell state is:\n{ptdis}')
The partial trace of Bell state is: ----------------------------------------------------- Backend: density_matrix System dimension: [2] System sequence: [0] [[0.5+0.j 0. +0.j] [0. +0.j 0.5+0.j]] -----------------------------------------------------
-
quairkit.qinfo.linalg.partial_transpose(state, transpose_idx, system_dim=
2
)¶ Calculate the partial transpose \(\rho^{T_A}\) of the input quantum state.
- Parameters:¶
- state : ndarray | Tensor | PureState | MixedState¶
Input quantum state.
- transpose_idx : List[int] | int¶
The system indices to be transposed.
- system_dim : List[int] | int¶
The dimension of all systems. Defaults to the qubit case.
- Returns:¶
The partial transpose of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
pt = partial_transpose(bell_state(2), [0]) print(f'The partial transpose of Bell state is:\n{pt}')
The partial transpose of Bell state is: ----------------------------------------------------- Backend: density_matrix System dimension: [2, 2] System sequence: [0, 1] [[0.5+0.j 0. +0.j 0. +0.j 0. +0.j] [0. +0.j 0. +0.j 0.5+0.j 0. +0.j] [0. +0.j 0.5+0.j 0. +0.j 0. +0.j] [0. +0.j 0. +0.j 0. +0.j 0.5+0.j]] -----------------------------------------------------
- quairkit.qinfo.linalg.pauli_decomposition(mat)¶
Decompose the matrix by the Pauli basis.
- Parameters:¶
- mat : ndarray | Tensor¶
The matrix to be decomposed.
- Returns:¶
A list of coefficients corresponding to the Pauli basis.
- Return type:¶
ndarray | Tensor
Examples
pauli_dec = pauli_decomposition(random_state(1).density_matrix) print(f'The decomposition is:\n{pauli_dec}')
The decomposition is: tensor([ 0.7071+0.j, 0.5076+0.j, 0.4494+0.j, -0.0572+0.j])
-
quairkit.qinfo.linalg.permute_systems(state, perm_list, system_dim=
2
)¶ Permute quantum systems based on a permutation list.
- Parameters:¶
- state : ndarray | Tensor | PureState | MixedState¶
A matrix representation of a quantum state.
- perm_list : List[int]¶
The permutation list. For example, [0, 2, 1, 3] will swap the 2nd and 3rd subsystems.
- system_dim : List[int] | int¶
A list of dimension sizes of each subsystem.
- Returns:¶
The permuted matrix.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
result = permute_systems(random_state(3), [2, 1, 0]) print(f'The permuted matrix is:\n{result}')
The permuted matrix is: ----------------------------------------------------- Backend: density_matrix System dimension: [2, 2, 2] System sequence: [0, 1, 2] [[ 0.06+0.j -0.02+0.j -0.02-0.07j -0.03-0.j 0.06+0.01j -0.02+0.03j -0.01-0.06j 0.01+0.01j] [-0.02-0.j 0.13+0.j -0.05+0.01j -0.02-0.01j 0.06-0.06j -0.01-0.03j -0.+0.08j 0.03-0.03j] [-0.02+0.07j -0.05-0.01j 0.24+0.j 0.06+0.03j -0.09+0.05j 0.01-0.05j 0.04-0.05j -0.13+0.04j] [-0.03+0.j -0.02+0.01j 0.06-0.03j 0.1+0.j -0.07+0.02j 0.02-0.05j -0.01+0.01j -0.03+0.j ]] -----------------------------------------------------
-
quairkit.qinfo.linalg.prob_sample(distribution, shots=
1024
, binary=True
, proportional=False
)¶ Sample from a probability distribution.
- Parameters:¶
- Returns:¶
A dictionary containing the ordered sampled results and their counts.
- Return type:¶
Dict[str, int | float]
Examples
dist = torch.abs(haar_state_vector(3)) result = prob_sample(dist / torch.sum(dist)) print(f'The sample result is:\n{result}')
The sample result is: {'0': tensor([1024, 1024, 1024])}
-
quairkit.qinfo.linalg.schmidt_decompose(psi, sys_A=
None
)¶ Calculate the Schmidt decomposition of a quantum state.
For a state \(\lvert\psi\rangle=\sum_i c_i \lvert i_A\rangle\otimes\lvert i_B \rangle\).
- Parameters:¶
- psi : ndarray | Tensor | PureState | MixedState¶
State vector form of the quantum state, with shape \((2**n)\).
- sys_A : List[int]¶
Qubit indices to be included in subsystem A. By default, the first half of the qubits belong to subsystem A.
- Returns:¶
A one-dimensional array of Schmidt coefficients with shape (k).
A high-dimensional array of bases for subsystem A with shape (k, 2**m, 1).
A high-dimensional array of bases for subsystem B with shape (k, 2**m, 1).
- Return type:¶
A tuple containing
Examples
# Example usage (assuming a proper state vector 'psi'): c, u, v = schmidt_decompose(psi) print("Schmidt coefficients:", c) print("Subsystem A bases:", u) print("Subsystem B bases:", v)
Schmidt coefficients: tensor([...]) Subsystem A bases: tensor([...]) Subsystem B bases: tensor([...])
- quairkit.qinfo.linalg.sqrtm(mat)¶
Calculate the square root of a matrix.
- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
Input matrix.
- Returns:¶
The square root of the matrix.
- Return type:¶
ndarray | Tensor
Examples
sqrt = sqrtm(x()) print(f'The square root of X is:\n{sqrt}')
The square root of X is: tensor([[0.5000+0.5000j, 0.5000-0.5000j], [0.5000-0.5000j, 0.5000+0.5000j]])
-
quairkit.qinfo.linalg.trace(mat, axis1=
-2
, axis2=-1
)¶ Return the sum along the diagonals of the tensor.
If \(mat\) is a 2-D tensor, the sum along its diagonal is returned. For tensors with more than two dimensions, the axes specified by
axis1
andaxis2
determine the 2-D sub-tensors whose traces will be taken.- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
Input tensor from which the diagonal is taken.
- axis1 : int¶
The first axis for the 2-D sub-tensor. Defaults to -2.
- axis2 : int¶
The second axis for the 2-D sub-tensor. Defaults to -1.
- Returns:¶
The trace (sum along the diagonal) of the tensor.
- Return type:¶
ndarray | Tensor
Examples
tr = trace(x()) print(f'The trace of X is:\n{tr}')
The trace of X is: 0j
- quairkit.qinfo.linalg.trace_norm(mat)¶
Calculate the trace norm of a matrix.
- Parameters:¶
- mat : ndarray | Tensor | PureState | MixedState¶
matrix
- Returns:¶
Trace norm of the input matrix
- Return type:¶
ndarray | Tensor
Examples
tr_norm = trace_norm(x()) print(f'The trace norm of X is:\n{tr_norm}')
The trace norm of X is: 2.0