quairkit.qinfo.qinfo¶
-
quairkit.qinfo.qinfo.channel_repr_convert(representation, source, target, tol=
1e-06
)¶ Convert the given representation of a channel to the target implementation.
- Parameters:¶
- representation : ndarray | Tensor | List[Tensor] | List[ndarray]¶
Input representation.
- source : str¶
Input form, should be
'choi'
,'kraus'
or'stinespring'
.- target : str¶
Target form, should be
'choi'
,'kraus'
or'stinespring'
.- tol : float¶
Error tolerance for the conversion from Choi, \(10^{-6}\) by default.
- Raises:¶
ValueError – Unsupported channel representation: require Choi, Kraus or Stinespring.
- Returns:¶
Quantum channel by the target implementation.
- Return type:¶
ndarray | Tensor
Examples
# Convert Choi to Kraus representation bell = torch.tensor([1, 0, 0, 1], dtype=torch.complex64) / torch.sqrt(torch.tensor(2)) choi = torch.outer(bell, bell.conj()) kraus_ops = channel_repr_convert(choi, 'choi', 'kraus') print(f'The Kraus operators are:\n{kraus_ops}')
The Kraus operators are: tensor([[-0.7071+0.j, 0.0000+0.j], [ 0.0000+0.j, -0.7071+0.j]])
Examples
# Convert Kraus to Stinespring representation p = 0.1 k0 = torch.tensor([[1, 0], [0, torch.sqrt(torch.tensor(1 - p))]], dtype=torch.complex64) k1 = torch.tensor([[0, torch.sqrt(torch.tensor(p))], [0, 0]], dtype=torch.complex64) stinespring = channel_repr_convert([k0, k1], 'kraus', 'stinespring') print(f'The Stinespring representation is:\n{stinespring}')
The Stinespring representation is: tensor([[1.0000+0.j, 0.0000+0.j], [0.0000+0.j, 0.3162+0.j], [0.0000+0.j, 0.9487+0.j], [0.0000+0.j, 0.0000+0.j]])
Examples
# Convert Stinespring to Choi representation stine = torch.zeros((4, 2), dtype=torch.complex64) stine[:2, :2] = torch.eye(2) # Valid isometry (V†V = I) choi = channel_repr_convert(stine, 'stinespring', 'choi') print(f'The Choi representation is:\n{choi}')
The Choi representation is: tensor([[1.+0.j, 0.+0.j, 0.+0.j, 0.+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, 0.+0.j, 0.+0.j, 0.+0.j]])
Note
choi -> kraus currently has the error of order 1e-6 caused by eigh.
- Raises:¶
NotImplementedError – Does not support the conversion of input data type.
-
quairkit.qinfo.qinfo.create_choi_repr(linear_map, input_dim, input_dtype=
None
)¶ Create the Choi representation of a linear map with input checks.
This function verifies if the map is linear and if the output is a square matrix.
Examples
def identity_map(matrix: torch.Tensor) -> torch.Tensor: return matrix choi = create_choi_repr(identity_map, input_dim=2) print(f'The Choi representation of identity is:\n{choi}')
The Choi representation of identity is: tensor([[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.+0.j, 0.+0.j], [1.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]])
- Raises:¶
RuntimeWarning – If linear_map is not linear or the output is not a square matrix.
-
quairkit.qinfo.qinfo.decomp_1qubit(unitary, return_global=
False
)¶ Decompose a single-qubit unitary operator into Z-Y-Z rotation angles.
- Parameters:¶
- Returns:¶
A tuple containing the angles (beta, gamma, delta) or (alpha, beta, gamma, delta) if return_global is True. The type of the tuple elements matches the input type.
- Return type:¶
Tuple[ndarray, …] | Tuple[Tensor, …]
Examples
angles = decomp_1qubit(h()) print(f'The angles are:\n{angles}')
The angles are: (tensor(0.), tensor(1.5708), tensor(3.1416))
- Raises:¶
ValueError – Raises a ValueError if the input matrix is not a batch of 2x2 unitary matrices.
- quairkit.qinfo.qinfo.decomp_ctrl_1qubit(unitary)¶
Decompose a controlled single-qubit unitary operator into its components.
- Parameters:¶
- unitary : ndarray | Tensor¶
A 2x2 unitary matrix representing the single-qubit gate, as either a numpy ndarray or a torch Tensor.
- Returns:¶
A tuple containing the global phase alpha and the matrices A, B, C, which are components of the decomposition. The type of the tuple elements matches the input type.
- Return type:¶
Tuple[ndarray, …] | Tuple[Tensor, …]
Examples
# Decompose X gate alpha, A, B, C = decomp_ctrl_1qubit(x()) print(f'The matrices are:\n{alpha, A, B, C }')
The matrices are: (tensor(0.), tensor([[ 0.7071+0.j, -0.7071+0.j], [ 0.7071+0.j, 0.7071+0.j]]), tensor([[ 0.7071+0.j, 0.7071+0.j], [-0.7071+0.j, 0.7071+0.j]]), tensor([[1.-0.j, 0.+0.j], [0.+0.j, 1.+0.j]]))
Examples
# Decompose random unitary alpha, A, B, C = decomp_ctrl_1qubit(random_unitary(1)) print(f'The matrices are:\n{alpha, A, B, C }')
The matrices are: (tensor(-0.3577), tensor([[ 0.1966+0.9432j, -0.0546-0.2620j], [ 0.0546-0.2620j, 0.1966-0.9432j]]), tensor([[ 0.3154-0.9104j, 0.0876+0.2529j], [-0.0876+0.2529j, 0.3154+0.9104j]]), tensor([[0.9918-0.1277j, 0.0000+0.0000j], [0.0000+0.0000j, 0.9918+0.1277j]]))
- Raises:¶
ValueError – Raises a ValueError if the input matrix is not a 2x2 unitary matrix.
-
quairkit.qinfo.qinfo.diamond_norm(channel_repr, dim_io=
None
, **kwargs)¶ Calculate the diamond norm of input.
- Parameters:¶
- Raises:¶
RuntimeError – channel_repr must be Channel or torch.Tensor.
TypeError – “dim_io” should be “int” or “tuple”.
Warning
channel_repr is not in Choi representation, and is converted into ChoiRepr.
Examples
def depolarizing_choi(p: float) -> torch.Tensor: bell = bell_state(2).density_matrix return (1 - p) * bell + p / 3 * (torch.kron(x(), x()) + torch.kron(y(), y()) + torch.kron(z(), z())) / 2 choi = depolarizing_choi(0.5) dn = diamond_norm(choi, dim_io=2) print(f'The diamond norm of this channel is:\n{dn}')
The diamond norm of this channel is: 0.7500035113999476
- quairkit.qinfo.qinfo.gate_fidelity(U, V)¶
Calculate the fidelity between gates.
\[F(U, V) = |\text{tr}(UV^\dagger)|/2^n\]\(U\) is a \(2^n\times 2^n\) unitary gate.
Examples
xy_fidelity = gate_fidelity(x(), y()) print(f'The fidelity of X and Y is:\n{xy_fidelity}')
The fidelity of X and Y is: 0.0
- quairkit.qinfo.qinfo.general_state_fidelity(rho, sigma)¶
Calculate the fidelity measure of two general states.
\[F_*(\rho, \sigma) = F(\rho, \sigma) + \sqrt{(1 - \text{tr}[\rho])(1 - \text{tr}[\sigma])}\]where \(F(\rho, \sigma)\) is the state fidelity without square.
- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
A subnormalized quantum state.
- sigma : ndarray | Tensor | PureState | MixedState¶
A subnormalized quantum state.
- Returns:¶
The general state fidelity of the input subnormalized states.
- Return type:¶
ndarray | Tensor
Examples
fidelity = general_state_fidelity(bell_state(2), zero_state(2)) print(f'The fidelity of Bell state and zero state is:\n{fidelity}')
The fidelity of Bell state and zero state is: 0.70710688829422
- quairkit.qinfo.qinfo.link(JE, JF)¶
Calculate the link product of two Choi matrices of quantum channels.
- Parameters:¶
- JE : Tuple[ndarray | Tensor, str, List[int] | int, List[int] | int]¶
Tuple containing the Choi representation of channel E, its label, input dimensions, and output dimensions.
- JF : Tuple[ndarray | Tensor, str, List[int] | int, List[int] | int]¶
Tuple containing the Choi representation of channel F, its label, input dimensions, and output dimensions.
- Returns:¶
The resulting Choi matrix after the link product, its label, and input/output dimensions.
- Return type:¶
Tuple[ndarray | Tensor, str, List[int], List[int]]
Note
The identification convention for input label is exemplified by “AB->CD”, where the same letter in different cases (uppercase vs lowercase) is recognized as the same system, and an apostrophe indicates a different system. When input and output dimensions are specified as an int, it implies that each system has the same dimensionality.
Examples
def identity_choi(dim: int) -> torch.Tensor: bell = eye(dim).flatten().to(torch.complex64) return torch.outer(bell, bell.conj()) / dim JE = (identity_choi(2), "A->B", [2], [2]) JF = (identity_choi(2), "B->C", [2], [2]) J_result, label, dim_in, dim_out = link(JE, JF) print(f'The resulting Choi matrix after the link product is {J_result}.\n' f'Its label is {label}.\n' f'Input/output dimensions are:{dim_in} and {dim_out}.')
The resulting Choi matrix after the link product is tensor([[0.2500+0.j, 0.0000+0.j, 0.0000+0.j, 0.2500+0.j], [0.0000+0.j, 0.0000+0.j, 0.0000+0.j, 0.0000+0.j], [0.0000+0.j, 0.0000+0.j, 0.0000+0.j, 0.0000+0.j], [0.2500+0.j, 0.0000+0.j, 0.0000+0.j, 0.2500+0.j]]). Its label is A->C. Input/output dimensions are: [2] and [2].
- quairkit.qinfo.qinfo.logarithmic_negativity(density_op)¶
Calculate the Logarithmic Negativity \(E_N = ||\rho^{T_A}||\) of the input quantum state.
- Parameters:¶
- density_op : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- Returns:¶
The Logarithmic Negativity of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
log_neg = logarithmic_negativity(bell_state(2)) print(f'The logarithmic negativity of Bell state is:\n{log_neg}')
The logarithmic negativity of Bell state is: 1.0
-
quairkit.qinfo.qinfo.mana(matrix, input_str, out_dim=
None
)¶ Compute the mana of states or channels.
- Parameters:¶
- matrix : ndarray | Tensor | PureState | MixedState¶
Quantum state or channel, when “channel”, it should be the choi matrix of channel.
- input_str : str¶
“state” or “channel”.
- out_dim : int | None¶
Output system dimension, only need to compute mana of channel.
- Returns:¶
The output mana.
- Return type:¶
ndarray | Tensor | PureState | MixedState
Examples
bell_mana = mana(bell_state(2), input_str="state") print(f'The mana of Bell state is:\n{bell_mana}')
The mana of Bell state is: tensor([0.6813], dtype=torch.float64)
Examples
choi_matrix = eye(4) / 2 mana_chan = mana(choi_matrix, input_str="channel", out_dim=2) print(f'The mana of a Choi channel is:\n{mana_chan}')
The mana of a Choi channel is: tensor([0.], dtype=torch.float64)
- quairkit.qinfo.qinfo.mutual_information(state, dim_A, dim_B)¶
Compute the mutual information of a bipartite state.
- Parameters:¶
- state : ndarray | Tensor | PureState | MixedState¶
Input bipartite quantum state with system AB.
- dim_A : int¶
Dimension of system A.
- dim_B : int¶
Dimension of system B.
- Returns:¶
The mutual information of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
mi = mutual_information(bell_state(2), dim_A=2, dim_B=2) print(f'The mutual information of Bell state is:\n{mi}')
The mutual information of Bell state is: 2.0
- quairkit.qinfo.qinfo.negativity(density_op)¶
Compute the Negativity \(N = ||\frac{\rho^{T_A}-1}{2}||\) of the input quantum state.
- Parameters:¶
- density_op : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- Returns:¶
The Negativity of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
neg = negativity(bell_state(2)) print(f'The negativity of Bell state is:\n{neg}')
The negativity of Bell state is: 0.4999999701976776
- quairkit.qinfo.qinfo.pauli_str_convertor(observable)¶
Concatenate the input observable with coefficient 1.
For example, if the input
observable
is[['z0,x1'], ['z1']]
, then this function returns the observable[[1, 'z0,x1'], [1, 'z1']]
.- Parameters:¶
- observable : List¶
The observable to be concatenated with coefficient 1.
- Returns:¶
The observable with coefficient 1.
- Return type:¶
List
Examples
pauli_terms = [['Z0,X1'], ['Y2']] converted = pauli_str_convertor(pauli_terms) print(f'The converted result is:\n{converted}')
The converted result is: [[1, 'Z0,X1'], [1, 'Y2']]
- quairkit.qinfo.qinfo.purity(rho)¶
Calculate the purity of a quantum state.
\[P = \text{tr}(\rho^2)\]- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- Returns:¶
The purity of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
max_mixed = purity(eye(2) / 2) print(f'The purity of 1-qubit maximal mixed state is:\n{max_mixed}')
The purity of 1-qubit maximal mixed state is: 0.5
-
quairkit.qinfo.qinfo.relative_entropy(rho, sigma, base=
2
)¶ Calculate the relative entropy of two quantum states.
\[S(\rho \| \sigma)=\text{tr} \rho(\log \rho-\log \sigma)\]- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- sigma : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- base : int | None¶
The base of logarithm. Defaults to 2.
- Returns:¶
Relative entropy between input quantum states.
- Return type:¶
ndarray | Tensor
Examples
rel_ent = relative_entropy(bell_state(2), eye(4) / 4) print(f'The relative entropy between 2-qubit maximal mixed state and Bell state is:\n{rel_ent}')
The relative entropy between 2-qubit maximal mixed state and Bell state is: 1.999999761581421
- quairkit.qinfo.qinfo.stab_nullity(unitary)¶
Tool for calculation of unitary-stabilizer nullity.
- Parameters:¶
- unitary : ndarray | Tensor¶
A batch of unitary matrices.
- Returns:¶
Unitary-stabilizer nullity for each unitary matrix.
- Return type:¶
ndarray | Tensor
Examples
unitary_stabilizer_nullity = stab_nullity(h().to(torch.complex128)) print(f'The unitary-stabilizer nullity for Hadamard gate is:\n{unitary_stabilizer_nullity}')
The unitary-stabilizer nullity for Hadamard gate is: tensor([0.])
- quairkit.qinfo.qinfo.stab_renyi(density, alpha)¶
Tool for calculation of stabilizer Renyi entropy.
- Parameters:¶
- density : ndarray | Tensor | PureState | MixedState¶
A batch of density matrices.
- alpha : ndarray | Tensor | Iterable[float] | float¶
The Renyi entropy exponent.
- Returns:¶
Stabilizer Renyi entropy for each density matrix.
- Return type:¶
ndarray | Tensor
Examples
stabilizer_renyi_entropy = stab_renyi(zero_state(1), alpha=2) print(f'The stabilizer Renyi entropy for zero state with alpha=2 is:\n{stabilizer_renyi_entropy}')
The stabilizer Renyi entropy for zero state with alpha=2 is: (tensor([2.3842e-07]),)
- quairkit.qinfo.qinfo.state_fidelity(rho, sigma)¶
Calculate the fidelity of two quantum states, no extra square is taken.
\[F(\rho, \sigma) = \text{tr}(\sqrt{\sqrt{\rho}\sigma\sqrt{\rho}})\]- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
A quantum state.
- sigma : ndarray | Tensor | PureState | MixedState¶
A quantum state.
- Returns:¶
The fidelity between the input quantum states.
- Return type:¶
ndarray | Tensor
Note
The fidelity equation is based on Equation (9.53) in Quantum Computation & Quantum Information, 10th edition.
Examples
fidelity = state_fidelity(bell_state(2), eye(4)/4) print(f'The state fidelity between Bell state and maximal mixed state is:\n{fidelity}')
The state fidelity between Bell state and maximal mixed state is: 0.5000725984573364
- quairkit.qinfo.qinfo.trace_distance(rho, sigma)¶
Calculate the trace distance of two quantum states.
\[D(\rho, \sigma) = \frac{1}{2}\text{tr}|\rho-\sigma|\]- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
A quantum state.
- sigma : ndarray | Tensor | PureState | MixedState¶
A quantum state.
- Returns:¶
The trace distance between the input quantum states.
- Return type:¶
ndarray | Tensor
Examples
tr_dist = trace_distance(bell_state(2), eye(4)/4) print(f'The trace distance between Bell state and maximal mixed state is:\n{tr_dist}')
The trace distance between Bell state and maximal mixed state is: 0.75
-
quairkit.qinfo.qinfo.von_neumann_entropy(rho, base=
2
)¶ Calculate the von Neumann entropy of a quantum state.
\[S = -\text{tr}(\rho \log_\text{base}(\rho))\]- Parameters:¶
- rho : ndarray | Tensor | PureState | MixedState¶
Density matrix form of the quantum state.
- base : ndarray | Tensor | Iterable[float] | float | int | None¶
The base of logarithm. Defaults to 2.
- Returns:¶
The von Neumann entropy of the input quantum state.
- Return type:¶
ndarray | Tensor
Examples
ent = von_neumann_entropy(completely_mixed_computational(1)) print(f'The von neumann entropy of 1-qubit maximal mixed state is:\n{ent}')
The von neumann entropy of 1-qubit maximal mixed state is: 1.0