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_lindblad computes 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 solve method (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.ket_bra(x, y)[source]
Parameters:
  • x (ndarray)

  • y (ndarray)

Return type:

ndarray

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 solve method (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