mimiqcircuits.operations.noisechannel.kraus¶
Functions
|
Check if a number is a power of 2. |
Classes
|
Kraus(kmatrices). |
- class mimiqcircuits.operations.noisechannel.kraus.Kraus(E, rtol=1e-12)[source]¶
Bases:
krauschannelKraus(kmatrices).
Custom N-qubit Kraus channel specified by a list of 2^N x 2^N Kraus matrices.
A Kraus channel is defined by:
\[\mathcal{E}(\rho) = \sum_k E_k \rho E_k^\dagger,\]where \(E_k\) are Kraus matrices that need to fulfill \(\sum_k E_k^\dagger E_k = I\).
If the Kraus matrices are all proportional to unitaries, use
MixedUnitary()instead.The Kraus matrices are defined in the computational basis in the usual textbook order (the first qubit corresponds to the left-most qubit). For 1 qubit, we have \(|0\rangle\), \(|1\rangle\). For 2 qubits, we have \(|00\rangle\), \(|01\rangle\), \(|10\rangle\), \(|11\rangle\).
Note
Currently, only 1 and 2-qubit custom Kraus channels are supported.
A Kraus channel becomes loss-aware simply by including one or more
LossyOperatorbranches inE. In that case,hasloss()returnsTrueandlossoperators(),survivaloperators(), andlosseffect()can be used to inspect the leakage structure.The entries of a
LossyOperatorare amplitudes, not probabilities. The corresponding loss probabilities appear inlosseffect(), which sums \(L_k^\dagger L_k\) over all lossy branches \(L_k\).See also
MixedUnitaryGateCustomLossyOperatorOperator- Parameters:
kmatrices (list) – List of \(2^N \times 2^N\) complex matrices. The number of qubits is equal to \(N\).
Examples
>>> from mimiqcircuits import * >>> from symengine import * >>> c = Circuit() >>> c.push(Kraus([Matrix([[1, 0], [0, sqrt(0.9)]]), Matrix([[0, sqrt(0.1)], [0, 0]])]), 0) 1-qubit circuit with 1 instruction: └── Kraus(Operator([[1, 0], [0, 0.948683298050514]]), Operator([[0, 0.316227766016838], [0, 0]])) @ q[0]
Kraus Matrices
>>> g=Kraus([Matrix([[1, 0], [0, sqrt(0.9)]]), Matrix([[0, sqrt(0.1)], [0, 0]])]) >>> g.krausmatrices() [[1.0, 0] [0, 0.948683298050514] , [0, 0.316227766016838] [0, 0] ]
# Example 2: Kraus with Projector0 and Projector1
>>> c = Circuit() >>> c.push(Kraus([Projector0(), Projector1()]), 0) 1-qubit circuit with 1 instruction: └── Kraus(P₀(1), P₁(1)) @ q[0]
# Example 3: Kraus with a matrix and Projector1
>>> c = Circuit() >>> c.push(Kraus([Matrix([[1, 0], [0, 0]]), Projector1()]), 0) 1-qubit circuit with 1 instruction: └── Kraus(Operator([[1, 0], [0, 0]]), P₁(1)) @ q[0]
# Example 4: Loss-aware Kraus with a LossyOperator branch
>>> lossy = LossyOperator(Matrix([[0, 0], [0, sqrt(0.2)]])) >>> survival = Operator(Matrix([[1, 0], [0, sqrt(0.8)]])) >>> lk = Kraus([survival, lossy]) >>> lk.hasloss() True >>> lk.lossoperators() [1-qubit LossyOperator (lossy=(1,)): ├── 0 0 └── 0 0.447213595499958] >>> lk.survivaloperators() [1-qubit Operator: ├── 1 0 └── 0 0.894427190999916] >>> lk.losseffect() 1-qubit Operator: ├── 0.0 + 0.0*I 0.0 + 0.0*I └── 0.0 + 0.0*I 0.2 + 0.0*I
# Example 5: Symbolic Kraus evaluation
>>> x = Symbol("x") >>> g = Kraus([Projector0(), Projector1(x)]) >>> g Kraus(P₀(1), P₁(x)) >>> g.evaluate({x: 1}) Kraus(P₀(1), P₁(1))
- evaluate(values)[source]¶
Evaluates symbolic parameters in Kraus matrices using a dictionary of values.
- losseffect(tol=1e-12)[source]¶
Compute the loss-probability operator over all lossy branches.
This returns the operator
\[\Lambda = \sum_k L_k^\dagger L_k,\]where \(L_k\) runs over the
LossyOperatorbranches of the channel.\(\Lambda\) is a positive semidefinite operator whose diagonal entries give the loss probabilities for each computational basis state. For a basis state \(|i\rangle\),
\[\langle i|\Lambda|i\rangle\]is the probability that \(|i\rangle\) leaks out of the computational subspace. For a general state \(|\psi\rangle\), the total loss probability is \(\langle\psi|\Lambda|\psi\rangle\).
Note
The entries of
LossyOperatorare amplitudes, not probabilities.losseffect()converts them into probabilities by summing \(L_k^\dagger L_k\).The survival and lossy operators together satisfy
\[\sum_k S_k^\dagger S_k + \Lambda = I,\]where \(S_k\) are the non-lossy branches.
If the channel has no lossy operators, the zero matrix is returned.
See also
Examples
>>> from mimiqcircuits import * >>> from symengine import Matrix, sqrt >>> g = Kraus([Matrix([[1, 0], [0, sqrt(0.9)]]), ... LossyOperator(Matrix([[0, 0], [0, sqrt(0.1)]]))]) >>> g.losseffect() 1-qubit Operator: ├── 0.0 + 0.0*I 0.0 + 0.0*I └── 0.0 + 0.0*I 0.1 + 0.0*I