mimiqcircuits.operations.operators.lossyoperator¶
Classes
|
N-qubit operator specified by a \(2^N \times 2^N\) matrix and a set of lossy qubit indices. |
- class mimiqcircuits.operations.operators.lossyoperator.LossyOperator(mat, lossy=None)[source]¶
Bases:
AbstractOperatorN-qubit operator specified by a \(2^N \times 2^N\) matrix and a set of lossy qubit indices.
Note
Only one and two qubit lossy operators are supported.
A
LossyOperatorrepresents a tagged custom operator used as a loss branch inside aKrauschannel. The matrix is expressed in the computational basis, exactly likeOperator, whilelossymarks which of the operator’s local qubits leak when this branch is selected.The
lossyindices are local to the operator and use1:Nnumbering, following the Julia implementation. They are not circuit-global qubit indices. When a surroundingKrauschannel is applied to circuit targets(q_1, ..., q_N), each local indexiinlossymaps to the corresponding physical targetq_i.A
Krauschannel that contains one or moreLossyOperatorbranches is a loss-aware channel. The helpersKraus.hasloss(),Kraus.lossoperators(),Kraus.survivaloperators(), andKraus.losseffect()inspect those branches.See also
AbstractOperator,Operator,Kraus- Parameters:
mat (symengine.Matrix | sympy.Matrix | np.ndarray) – The \(2^N \times 2^N\) matrix representing the operator.
lossy (int | tuple | list, optional) – One or more local qubit indices in
1:Nthat leak when this branch is selected. For one-qubit operators, the default is(1,). For multi-qubit operators, the lossy qubits must be specified explicitly.
Examples
>>> from mimiqcircuits import * >>> from symengine import Matrix, sqrt >>> op = LossyOperator(Matrix([[0, 1], [0, 0]])) >>> op 1-qubit LossyOperator (lossy=(1,)): ├── 0 1 └── 0 0
>>> c = Circuit() >>> c.push(Kraus([Matrix([[1, 0], [0, sqrt(0.9)]]), ... LossyOperator(Matrix([[0, sqrt(0.1)], [0, 0]]))]), 1) 2-qubit circuit with 1 instruction: └── Kraus(Operator([[1, 0], [0, 0.948683298050514]]), LossyOperator([[0, 0.316227766016838], [0, 0]]; lossy=(1,))) @ q[1]
- iswrapper()[source]¶
Check if the operator is a wrapper around another operator.
This method should be overridden in subclasses to return True if the operator is acting as a wrapper around another operation or object, and False otherwise.
- Returns:
Always returns False in the base class. Subclasses should override this method to provide the appropriate logic.
- Return type:
- property parnames¶
- unwrappedmatrix()[source]¶
Numeric matrix representation as a
numpy.ndarray[complex128].This is the Python analogue of Julia’s
unwrappedmatrix(::AbstractOperator): simulators and anything else that wants raw numbers (e.g. TensorWeaver) should call this instead ofmatrix(). It bypasses SymEngine entirely for gates that override_matrix_numeric()— seemimiqcircuits.numerics— and otherwise falls back to building the SymEngine matrix and casting it.Constant gates cache the result at class level.
- Raises:
UnexpectedSymbolics – If any parameter is still symbolic.
- Returns:
complex128matrix.- Return type:
- evaluate(values)[source]¶
Substitute the symbolic parameters of the operator with numerical values.
This method evaluates the operator’s symbolic parameters using the values provided in the dictionary d. If the operator has no parameters, it returns the same instance. Otherwise, it creates a new instance of the operator with updated numerical parameters.
- Parameters:
d (dict) – A dictionary where keys are symbolic parameter names and values are values for substitution.
Example
>>> from symengine import * >>> from mimiqcircuits import * >>> theta = symbols('theta') >>> op = GateRX(theta) >>> evaluated_op = op.evaluate({'theta': 0.5}) >>> print(evaluated_op) RX(0.5)