qtools
- qmetro.qtools.choi_from_krauses(krauses)[source]
Get Choi matrix of a channel defined using its Kraus operators.
For channel Phi: H_in -> H_out returned matrix acts on tensor product H_out (x) H_in.
- Parameters:
krauses (list[np.ndarray]) – List of Kraus operators.
- Returns:
choi – Choi matrix.
- Return type:
np.ndarray
- qmetro.qtools.choi_from_lindblad(lindblad, dlindblad, t, dim=None, lind_kwargs=None)[source]
Calculates Choi matrix and its derivative of a channel simulating evolution with a given Lindbladian for time t.
Lindbladian - L is a function, that for input density matrix returns its derivative over time e.g. lindblad(rho) = drho/dt. For example for rotation of Bloch ball around z-axis with angular velocity omega:
L(rho) = 0.5j * omega * (rho sigma_z - sigma_z rho),
where sigma_z is a Z Pauli matrix. If omega is an estimated parameter, then the derivative of Lindbladian over this parameter - dL is a function:
dL(rho) = 0.5j * (rho sigma_z - sigma_z rho).
choi_from_lindbladcomputes Choi matrix and its derivative over the estimated parameter for continuous time evolution with a Lindbladian constant in time. Computations are done algebraically, without numerical integration.- Parameters:
lindblad (Callable[..., np.ndarray] | tuple[np.ndarray, list[np.ndarray]]) – Argument representing Lindbladian. It can be: - A function L(rho, a0, a1, …) returning derivative drho/dt for input state rho and additional keyword arguments a0, a1,… In this case additional parameter dim representing dimension of rho has to be provided. - A tuple (H, Ls) where H is a Hamiltonian divided by hbar (np.ndarray) and Ls are jump operators (list[np.ndarray]).
dlindblad (Callable[[np.ndarray], np.ndarray] | tuple[np.ndarray, list[np.ndarray]] | np.ndarray) – Argument representing Lindbladian’s derivative. It can be: - A function dL(rho, b0, b1, …) returning derivative of drho/dt over paramter. - A tuple (dH, dLs) where dH and dLs are derivatives of H and Ls. - An array dH and dLs are assumed to be zero.
dim (int) – Dimension of Hilbert space on which Lindbladian acts
t (float) – Evolution time
lind_kwargs (Mapping[str, Any] | None = None) – Additional keyword arguments passed to lindblad and dlindblad
- Returns:
choi – Choi matrix
dchoi – Derivative of Choi matrix over some parameter
- Return type:
tuple[ndarray, ndarray]
- qmetro.qtools.comb_variables(dims, hermitian=True, trace_constraint=1)[source]
Construct a sequence of CVXPY variables that represent quantum combs satisfying causality constraints.
Each element in the returned combs list represents a quantum comb matrix acting on progressively larger subsystems of a composite Hilbert space, where subsystems alternate as input (odd-indexed, starting from 1) and output (even-indexed) spaces.
- Parameters:
dims (tuple of int) – Dimensions of each Hilbert space H_1, H_2, …, H_2N in the composite system. The number of spaces (length of dims) must be even, with N pairs of input-output spaces.
hermitian (bool, optional) – If True, each matrix in combs is constrained to be Hermitian, by default True.
trace_constraint (float or None, optional) – Specifies the trace constraint on the first comb operator. If None, a trace variable is used instead of a fixed trace, by default 1.
- Returns:
- A tuple containing:
- combslist of cp.Variable
List of CVXPY variables representing the quantum comb operators.
- constraintslist of cp.Constraint
List of CVXPY constraints on the comb operators ensuring causality.
- trace_var or trace_constraintcp.Variable or float
If trace_constraint is None, returns a trace variable for the constraint. Otherwise, returns the specified trace_constraint value.
- Return type:
tuple
- Raises:
ValueError – If the length of dims is not even, as quantum comb spaces must have matching input-output pairs.
Notes
- Element combs[i] is a Choi-Jamiolkowski operator acting on
H_2i+2 (x) … (x)H_2 (x) H_2i+1 (x) … H_1, so it belongs to set Comb[(H_1, H_2), …, (H_2i+1, H_2i+2)]
- The full comb is the last element combs[N-1] Comb[(H_1, H_2), …,
(H_2N-1, H_2N)]
- If trace_constraint is not None, it represents the trace of
the initial operator scaled by input space dimensions. This is not the overall comb trace, which includes all input dimensions.
- The function does not assume positivity for the combs. A positivity
constraint can be added externally if needed.
Examples
>>> dims = (2, 2, 2, 2) >>> combs, constraints, trace_constraint = comb_variables(dims) >>> len(combs) 2 >>> len(constraints) 2
- qmetro.qtools.dchoi_from_krauses(krauses, dkrauses)[source]
Get derivative of a Choi matrix of a channel defined using its Kraus operators and their derivatives.
For channel Phi: H_in -> H_out returnde matrix acts on tensor product H_out (x) H_in.
- Parameters:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Returns:
dchoi – Derivative of a Choi matrix.
- Return type:
np.ndarray
- qmetro.qtools.depolarization_krauses(p=None, noise_first=True, eta=None)[source]
Computes Kraus operators and their derivatives for a qubit channel where:
the signal is rotating Bloch sphere around the z-axis,
noise shrinks uniformly the whole Bloch ball.
See more details in the documentation.
- Parameters:
p (float | None, optional) – Probability that the input state will remain unchanged.
noise_first (bool, optional) – Whether noise is before signal, by default True.
eta (float | None, optional) – Alternative method of determining the noise strength that when provided is used instead of p (either p or eta argument has to be provided). In this parametrisation eta is the factor by which Bloch sphere gets shrunken.
- Returns:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Raises:
ValueError – When poth p and eta are provided.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.dkrauses_from_choi(choi, dchoi, dims, eps=1e-07)[source]
Calculates Kraus operators and derivaties of a channel with a given Choi and derivative.
- Parameters:
choi (np.ndarray) – Choi-Jamiolkowski matrix of a channel : Lin(dout x din). It has to be a positive semi-definite matrix.
dchoi (np.ndarray) – Derivative of aChoi-Jamiolkowski matrix of a channel.
dims (tuple[int, int]) – Tuple [din, dout],`din`, dout are input/output dimensions of a channel
eps (float, optional) – Eigenvectors of choi with eigenvalues smaller than eps are ignored.
- Returns:
krauses (list[np.ndarray]) – Kraus operators of a channel (arrays of dimensions dout x din).
dkrauses (list[np.ndarray]) – Derivatives of Kraus operators of a channel (arrays of dimensions dout x din).
- Return type:
tuple[list[ndarray], list[ndarray]]
Notes
Normalization convention: choi trace is dimension of input space
- qmetro.qtools.get_sld(rho, drho, return_qfi=False, **kwargs)[source]
Computes symmetric logarithmic derivative (SLD) of a parametrized state.
- Parameters:
rho (np.ndarray) – Density matrix.
drho (np.ndarray) – Derivative of density matrix.
return_qfi (bool, optional) – Whether to return also a quantum Fisher information (QFI) of the state, by default False.
**kwargs – Additional keyword arguments passed to the CVXPY
solvemethod (see docs).
- Returns:
SLD matrix or a pair (SLD, QFI) if return_qfi is True.
- Return type:
np.ndarray | tuple[float, np.ndarray]
- qmetro.qtools.hc(x)[source]
Hermitian conjugation of a numpy matrix or a cvxpy expression.
- Parameters:
x (np.ndarray | cp.Expression) – Matrix.
- Returns:
x.conjugate().T
- Return type:
np.ndarray | cp.Expression
- qmetro.qtools.krauses_from_choi(choi, dims, eps=1e-07, return_eigensystem=False)[source]
Calculates Kraus operators of a channel with a given Choi.
- Parameters:
choi (np.ndarray) – Choi-Jamiolkowski matrix of a channel : Lin(dout (x) din)
dims (tuple[int, int]) – Tuple [din, dout],`din`, dout are input/output dimensions of a channel
eps (float, optional) – Eigenvectors of choi with eigenvalues smaller than eps are ignored.
return_eigensystem (bool, optional) – If true, returns additionally eigenvalues and eigenvectors.
- Returns:
krauses (list[np.ndarray] | tuple[list[np.ndarray], np.ndarray,)
np.ndarray] – Kraus operators of a channel (arrays of dimensions dout x din) or if return_eigensystem=True a tuple (Kraus operators, eigenvalues, eigenvectors) where i-th eigenvector is eigenvectors[:, i].
- Return type:
list[ndarray] | tuple[list[ndarray], ndarray, ndarray]
Notes
Normalization convention: Trace of the Choi matrix is equal to the dimension of the input space.
- qmetro.qtools.krauses_kron(krauses1, dkrauses1, krauses2, dkrauses2)[source]
Computes the Kraus representation of the Kronecker product of two quantum channels and their derivatives.
This function creates a representation of the Kronecker product of two quantum channels, including the combined Kraus operators and their derivatives.
- Parameters:
krauses1 (list of np.ndarray) – List of Kraus operators for the first channel.
dkrauses1 (list of np.ndarray) – List of derivatives of Kraus operators for the first channel.
krauses2 (list of np.ndarray) – List of Kraus operators for the second channel.
dkrauses2 (list of np.ndarray) – List of derivatives of Kraus operators for the second channel.
- Returns:
krauses12 (list of np.ndarray) – The Kraus operators of the Kronecker product channel.
dkrauses12 (list of np.ndarray) – The derivatives of the Kraus operators for the Kronecker product channel.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.krauses_sequential(krauses1, dkrauses1, krauses2, dkrauses2)[source]
Computes the Kraus representation of the sequential composition of two quantum channels and their derivatives.
This function creates a representation of the sequential composition of two quantum channels (krauses and their derivatives of a resulting channel). krauses1 go before krauses2
- Parameters:
krauses1 (list of np.ndarray) – List of Kraus operators for the first channel.
dkrauses1 (list of np.ndarray) – List of derivatives of Kraus operators for the first channel.
krauses2 (list of np.ndarray) – List of Kraus operators for the second channel.
dkrauses2 (list of np.ndarray) – List of derivatives of Kraus operators for the second channel.
- Returns:
krauses12 (list of np.ndarray) – The Kraus operators of the Kronecker product channel.
dkrauses12 (list of np.ndarray) – The derivatives of the Kraus operators for the Kronecker product channel.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.minimize_alpha(krauses, dkrauses, **kwargs)[source]
Minimize the norm of alpha over all Kraus representations for a given channel [12, 27].
Given a list of Kraus operators and their derivatives, this function calculates the minimum norm of alpha over all possible Kraus representations for the input channel.
- Parameters:
krauses (list[np.ndarray]) – List of Kraus operators, each represented as a 2D NumPy array.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators, each represented as a 2D NumPy array.
**kwargs –
Additional keyword arguments passed to the CVXPY
solvemethod (see docs).
- Returns:
The minimum value of norm of alpha over all Kraus representations.
- Return type:
float
- qmetro.qtools.par_amp_damping_krauses(p, noise_first=True)[source]
Computes Kraus operators and their derivatives for a qubit channel where:
the signal is rotating Bloch sphere around the z-axis,
noise models decay from state
|1⟩to|0⟩.
See more details in the documentation.
- Parameters:
p (float) – Noise parametrization. For p = 1 there is no noise for p = 0 the noise is maximal.
noise_first (bool, optional) – Whether the noise is before the signal, by default True.
- Returns:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.par_dephasing_krauses(p=None, noise_first=True, eps=None, rot_like=False)[source]
Computes Kraus operators and their derivatives for a qubit channel where:
the signal is rotating Bloch sphere around the z-axis,
noise shrinks the xy-plane preserving the z-axis.
See more details in the documentation.
- Parameters:
p (float | None, optional) – Probability that the input state will remain unchanged.
noise_first (bool, optional) – Whether noise is before signal, by default True.
eps (float | None, optional) –
Alternative way of determining the noise strength:
p = cos(eps/2)**2,
that when provided is used instead of p (p argument is ignored).
rot_like (bool, optional) –
If True then Kraus operators of noise are:
exp(-1j/2 * eps * sigma_z) / sqrt(2), exp(+1j/2 * eps * sigma_z) / sqrt(2),
where p = cos(eps/2)**2. By default False.
- Returns:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Raises:
ValueError – When both p and eps are provided.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.parallel_krauses(krauses, dkrauses, n)[source]
Returns Kraus operators and their derivatives for n parallel channels.
- Parameters:
krauses (list[np.ndarray]) – Kraus operators of single channel.
dkrauses (list[np.ndarray]) – Derivatives of Kraus operators of single channel.
n (int) – Number of parallel channels.
- Returns:
krauses (list[np.ndarray]) – Kraus operators of n channels.
dkrauses (list[np.ndarray]) – Derivatives of Kraus operators of n channels.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.per_amp_damping_krauses(p, noise_first=True)[source]
Computes Kraus operators and their derivatives for a qubit channel where:
the signal is rotating Bloch sphere around the z-axis,
noise models decay from state
|+⟩to|-⟩.
See more details in the documentation.
- Parameters:
p (float) – Noise parametrization. For p = 1 there is no noise for p = 0 the noise is maximal.
noise_first (bool, optional) – Whether noise is before signal, by default True.
- Returns:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.per_dephasing_krauses(p, noise_first=True)[source]
Computes Kraus operators and their derivatives for a qubit channel where:
the signal is rotating Bloch sphere around the z-axis,
noise shrinks the yz-plane preserving the x-axis.
See more details in the documentation.
- Parameters:
p (float) – Probability that the input state will remain unchanged.
noise_first (bool, optional) – Whether noise is before signal, by default True.
- Returns:
krauses (list[np.ndarray]) – List of Kraus operators.
dkrauses (list[np.ndarray]) – List of derivatives of Kraus operators.
- Return type:
tuple[list[ndarray], list[ndarray]]
- qmetro.qtools.povm_from_sld(sld)[source]
Calculates optimal measurement POVM from SLD matrix.
- Parameters:
sld (np.ndarray) – Symmetric logarithmic derivative (SLD) matrix
- Returns:
List of optimal measurement operators: projections on eigenvectors of SLD matrix.
- Return type:
list[np.ndarray]
- qmetro.qtools.swap_operator(dims, i1, i2)[source]
Construct a swap operator matrix for a tensor product space, swapping two specified subsystems.
This function returns a matrix that, when applied to a vector or matrix in the tensor product space H_1 x H_2 x … x H_N, swaps the specified subsystems with indices i1 and i2. The resulting space ordering will be:
Original structure: H_1 x … x H_i1 x … x H_i2 x … H_N
New structure: H_1 x … x H_i2 x … x H_i1 x … H_N
If v is a vector in the original structure, swap_operator @ v gives the vector in the swapped structure. If M is a matrix in the original structure, swap_operator @ M @ swap_operator.T gives the matrix in the swapped structure.
- Parameters:
dims (tuple of int) – Dimensions of each subsystem H_1, …, H_N in the tensor product space.
i1 (int) – Index of the first subsystem to swap.
i2 (int) – Index of the second subsystem to swap.
- Returns:
The swap operator matrix that swaps subsystems i1 and i2 in the tensor product space.
- Return type:
np.ndarray
Notes
The swap operator constructs the necessary index mappings by decomposing the tensor product space indices and swapping the basis states of the specified subsystems.
Examples
>>> dims = (2, 2, 2) >>> i1, i2 = 0, 1 >>> swap_operator(dims, i1, i2) array([...]) # Swap operator matrix for a 3-qubit system