MajoranaOp¶
- class MajoranaOp(data, num_modes=None, *, copy=True, validate=True)[source]¶
Bases:
SparseLabelOpN-mode Majorana operator.
A
MajoranaOprepresents a weighted sum of Majorana fermion operator terms. These terms are encoded as sparse labels, which are strings consisting of a space-separated list of expressions. Each expression must look like_<index>, where the<index>is a non-negative integer representing the index of the mode on which the Majorana operator is applied. The maximum value ofindexis bound bynum_modes. Note that, when converting from aFermionicOpthere are two modes per spin orbital, i.e.num_modesis2 * FermionicOp.num_spin_orbitals - 1Initialization
A
MajoranaOpis initialized with a dictionary, mapping terms to their respective coefficients:from qiskit_nature.second_q.operators import MajoranaOp op = MajoranaOp( { "_0 _1": .25j, "_1 _0": -.25j, "_2 _3": -.25j, "_3 _2": .25j, }, num_modes=4, )
By default, this way of initializing will create a full copy of the dictionary of coefficients. If you have very restricted memory resources available, or would like to avoid the additional copy, the dictionary will be stored by reference if you disable
copylike so:some_big_data = { "_0 _1": .25j, "_1 _0": -.25j, # ... } op = MajoranaOp( some_big_data, num_modes=4, copy=False, )
Note
It is the users’ responsibility, that in the above scenario,
some_big_datais not changed after initialization of theMajoranaOp, since the operator contents are not guaranteed to remain unaffected by such changes.Construction from Fermionic operator
As an alternative to the manual construction above, a more convenient way of initializing a MajoranaOp is, to construct it from an existing FermionicOp:
from qiskit_nature.second_q.operators import FermionicOp, MajoranaOp f_op = FermionicOp({"+_0 -_1": 1}, num_spin_orbitals=2) m_op = MajoranaOp.from_fermionic_op(f_op)
Note that each
FerminonicOp-term consisting of \(n\) expressions will result in aMajoranaOp-term consisting of \(2^n\) expressions. The conversion uses the convention that\[a_i = \frac{1}{2}(\gamma_{2i} + i \gamma_{2i+1}), \quad a_i^\dagger = \frac{1}{2}(\gamma_{2i} - i \gamma_{2i+1}) \,,\]where \(a_i\) and \(a_i^\dagger\) are the Fermionic annihilation and creation operators and \(\gamma_i\) the Majorana operators.
Construction from a ``PolynomialTensor``
Using the
from_polynomial_tensor()constructor method, aMajoranaOpcan be constructed from aPolynomialTensor. In this case, the underscore character_is the only allowed character in the keys of thePolynomialTensor. For example,p_t = PolynomialTensor( { "_": np.arange(1, 3), "__": np.arange(1, 5).reshape((2, 2)), } ) op = MajoranaOp.from_polynomial_tensor(p_t) # op is then MajoranaOp({'_0': 1, '_1': 2, '_0 _0': 1, '_0 _1': 2, '_1 _0': 3, '_1 _1': 4}, num_modes=2)
Algebra
This class supports the following basic arithmetic operations: addition, subtraction, scalar multiplication, operator multiplication, and adjoint. For example,
Addition
MajoranaOp({"_1": 1}, num_modes=2) + MajoranaOp({"_0": 1}, num_modes=2)
Sum
sum(MajoranaOp({label: 1}, num_modes=4) for label in ["_0", "_1", "_2 _3"])
Scalar multiplication
0.5 * MajoranaOp({"_1": 1}, num_modes=2)
Operator multiplication
op1 = MajoranaOp({"_0 _1": 1}, num_modes=3) op2 = MajoranaOp({"_0 _1 _2": 1}, num_modes=3) print(op1 @ op2)
Tensor multiplication
op = MajoranaOp({"_0 _1": 1}, num_modes=2) print(op ^ op)
Adjoint
MajoranaOp({"_0 _1": 1j}, num_modes=2).adjoint()
Note
Since Majorana operators are self-adjoined, the adjoint of a
MajoranaOpis the original operator with all strings reversed, e.g."_0 _1"becomes"_1 _0"in the example above, and coefficients become complex conjugated.Iteration
Instances of
MajoranaOpare iterable. Iterating aMajoranaOpyields(term, coefficient)pairs describing the terms contained in the operator.- num_modes¶
the number of modes on which this operator acts. This is considered a lower bound, which means that mathematical operations acting on two or more operators will result in a new operator with the maximum number of modes of any of the involved operators. When converting from a
FermionicOp, this is twice the number of spin orbitals.- Type:
int | None
Note
MajoranaOpcan containqiskit.circuit.ParameterExpressionobjects as coefficients. However, aMajoranaOpcontaining parameters does not support the following methods:is_hermitian
- Parameters:
data (Mapping[str, _TCoeff]) – the operator data, mapping string-based keys to numerical values.
num_modes (int | None) – the number of modes on which this operator acts.
copy (bool) – when set to False the
datawill not be copied and the dictionary will be stored by reference rather than by value (which is the default;copy=True). Note, that this requires you to not change the contents of the dictionary after constructing the operator. This also impliesvalidate=False. Use with care!validate (bool) – when set to False the
datakeys will not be validated. Note, that the SparseLabelOp base class, makes no assumption about the data keys, so will not perform any validation by itself. Only concrete subclasses are encouraged to implement a key validation method. Disable this setting with care!
- Raises:
QiskitNatureError – when an invalid key is encountered during validation.
Attributes
- atol = 1e-08¶
- register_length¶
- rtol = 1e-05¶
Methods
- adjoint()¶
Return the adjoint of the Operator.
- Return type:
Self
- argsort(*, weight=False)¶
Returns the keys which sort this operator.
- Parameters:
weight (bool) – when True, the returned keys will sort this operator according to the coefficient weights of the stored terms; when False, the keys will sort the operator by its keys (i.e. lexicographically).
- Returns:
The sequence of keys which sort this operator.
- Return type:
- assign_parameters(parameters)¶
Assign parameters to new parameters or values.
- Parameters:
parameters (Mapping[ParameterExpression, complex | ParameterExpression]) – The mapping from parameters to new parameters or values.
- Returns:
A new operator with the parameters assigned.
- Return type:
- chop(atol=None)¶
Chops the real and imaginary parts of the operator coefficients.
This function separately chops the real and imaginary parts of all coefficients to the provided tolerance. Parameters are chopped only if they are exactly zero.
- compose(other, qargs=None, front=False)[source]¶
Returns the operator composition with another operator.
- Parameters:
other (MajoranaOp) – the other operator.
qargs – UNUSED.
front (bool) – If True composition uses right operator multiplication, otherwise left multiplication is used (the default).
- Returns:
The operator resulting from the composition.
- Return type:
Note
Composition (
&) by default is defined as left matrix multiplication for matrix operators, while@(equivalent todot()) is defined as right matrix multiplication. This means thatA & B == A.compose(B)is equivalent toB @ A == B.dot(A)whenAandBare of the same type.Setting the
front=Truekeyword argument changes this to right matrix multiplication which is equivalent to thedot()methodA.dot(B) == A.compose(B, front=True).
- conjugate()¶
Returns the conjugate of the
SparseLabelOp.- Returns:
The complex conjugate of the starting
SparseLabelOp.- Return type:
- dot(other, qargs=None)¶
Return the right multiplied operator self * other.
- Parameters:
other (Operator) – an operator object.
qargs (list or None) – a list of subsystem positions to apply other on. If None apply on all subsystems (default: None).
- Returns:
The right matrix multiplied Operator.
- Return type:
Operator
Note
The dot product can be obtained using the
@binary operator. Hencea.dot(b)is equivalent toa @ b.
- equiv(other, *, atol=None, rtol=None)¶
Check equivalence of two
SparseLabelOpinstances up to an accepted tolerance.- Parameters:
other (SparseLabelOp) – the second
SparseLabelOpto compare with this instance.atol (float | None) – Absolute numerical tolerance. The default behavior is to use
self.atol.rtol (float | None) – Relative numerical tolerance. The default behavior is to use
self.rtol.
- Returns:
True if operators are equivalent, False if not.
- Raises:
ValueError – Raised if either operator contains parameters
- Return type:
- expand(other)[source]¶
Returns the reverse-order tensor product with another operator.
- Parameters:
other (MajoranaOp) – the other operator.
- Returns:
The operator resulting from the tensor product, \(othr \otimes self\).
- Return type:
- classmethod from_fermionic_op(op, *, simplify=True)[source]¶
Constructs the operator from a
FermionicOp.- Parameters:
op (FermionicOp) – the
FermionicOpto convert.simplify (bool) – whether to index order and simplify the resulting operator.
- Returns:
The converted
MajoranaOp.- Return type:
- classmethod from_polynomial_tensor(tensor)[source]¶
Constructs the operator from a
PolynomialTensor.- Parameters:
tensor (PolynomialTensor) – the
PolynomialTensorto be expanded.- Returns:
The constructed operator.
- Return type:
- classmethod from_terms(terms)[source]¶
Constructs a new
SparseLabelOpfrom a sequence returned byterms().
- get(k[, d]) D[k] if k in D, else d. d defaults to None.¶
- index_order()[source]¶
Convert to the equivalent operator with the terms of each label ordered by index.
Returns a new operator (the original operator is not modified).
Note
You can use this method to achieve the most aggressive simplification.
simplify()does not reorder the terms. For instance, using onlysimplify()will reduce_2 _0 _1 _0 _0to_2 _0 _1but cannot deduce this label to be identical to_0 _1 _2. Calling this method will reorder the former label to_0 _0 _0 _1 _2, after whichsimplify()will be able to correctly collapse these two labels into one.- Returns:
The index ordered operator.
- Return type:
- induced_norm(order=1)¶
Returns the p-norm induced by the operator coefficients.
If the operator is represented as a sum of terms
\[\sum_i w_i H_i\]then the induced \(p\)-norm is
\[\left(\sum_i |w_i|^p \right)^{1/p}\]This is the standard \(p\)-norm of the operator coefficients considered as a vector (see https://en.wikipedia.org/wiki/Norm_(mathematics)#p-norm). Note that this method does not normal-order or simplify the operator before computing the norm; performing either of those operations can affect the result.
- Parameters:
order (int) – Order \(p\) of the norm. The default value is 1.
- Returns:
The induced norm.
- Return type:
- Raises:
ValueError – Operator contains parameters.
- Return type:
- is_hermitian(atol=None)[source]¶
Checks whether the operator is hermitian.
- Parameters:
atol (float | None) – Absolute numerical tolerance. The default behavior is to use
self.atol.- Returns:
True if the operator is hermitian up to numerical tolerance, False otherwise.
- Raises:
ValueError – Operator contains parameters.
- Return type:
- is_zero(tol=None)¶
Returns true if operator length is zero or all coefficients have value zero.
- items() a set-like object providing a view on D's items¶
- keys() a set-like object providing a view on D's keys¶
- classmethod one()¶
Constructs a unity-operator.
- Returns:
The unity-operator of the given length.
- Return type:
- parameters()¶
Returns a list of the parameters in the operator.
- Returns:
A list of the parameters in the operator.
- Return type:
- permute_indices(permutation)¶
Permutes the indices of the operator.
This method applies the provided index permutation to all labels of this operator. The provided permutation must be a sequence of integers whose length is equal to the
register_lengthof the operator. The integer at any given index of the sequence indicates the new index which that location will be permuted to. For example:op = SparseLabelOp({"+_0 -_1 +_2 -_3": 1.0}) permuted_op = op.permute_indices([3, 1, 0, 2]) assert permuted_op == SparseLabelOp({"+_3 -_1 +_0 -_2": 1.0})
Warning
This permutation utility is very powerful. Be mindful of the implications such a permutation might have on other components of the stack. To name an example, the builtin two-qubit reduction of the
ParityMappermight not yield the expected results when used on permuted operator.- Parameters:
permutation (Sequence[int]) – a sequence of integers indicating the permutation to be applied. See above for an example.
- Returns:
A new operator instance with the permuted indices.
- Raises:
ValueError – if the length of the
permutationargument does not equalregister_length.- Return type:
- power(n)¶
Return the composition of an operator with itself n times.
- Parameters:
n (int) – the number of times to compose with self (n>0).
- Returns:
the n-times composed operator.
- Return type:
Clifford
- Raises:
QiskitError – if the input and output dimensions of the operator are not equal, or the power is not a positive integer.
- round(decimals=0)¶
Rounds the operator coefficients to a specified number of decimal places.
- Parameters:
decimals (int) – the number of decimal places to round coefficients to. By default this will round to the nearest integer value.
- Returns:
The rounded operator.
- Return type:
- simplify(atol=None)[source]¶
Simplify the operator.
The simplifications implemented by this method should be: - to eliminate terms whose coefficients are close (w.r.t.
atol) to 0. - to combine the coefficients which correspond to equivalent terms (see also the note below)Note
simplify()should be used to simplify terms whose coefficients are close to zero, up to the specified numerical tolerance. It still differs slightly fromchop()because that will chop real and imaginary part components individually.Note
The meaning of “equivalence” between multiple terms depends on the specific operator subclass. As a restriction this method is required to preserve the order of appearance of the different components within a term. This avoids some possibly unexpected edge cases. However, this also means that some equivalencies cannot be detected. Check for other methods of a specific subclass which may affect the order of terms and can allow for further simplifications to be implemented.
This method returns a new operator (the original operator is not modified).
- Parameters:
atol (float | None) – Absolute numerical tolerance. The default behavior is to use
self.atol.- Returns:
The simplified operator.
- Return type:
- sort(*, weight=False)¶
Returns a new sorted operator.
- Parameters:
weight (bool) – when True, the returned keys will sort this operator according to the coefficient weights of the stored terms; when False, the keys will sort the operator by its keys (i.e. lexicographically).
- Returns:
A new operator instance with its contents sorted.
- Return type:
- tensor(other)[source]¶
Returns the tensor product with another SparseLabelOp.
- Parameters:
other (MajoranaOp) – the other SparseLabelOp.
- Returns:
The operator resulting from the tensor product, \(self \otimes other\).
- Return type:
Note
The tensor product can be obtained using the
^binary operator. Hencea.tensor(b)is equivalent toa ^ b.
- terms()[source]¶
Provides an iterator analogous to
items()but with the labels already split into pairs of operation characters and indices.- Yields:
A tuple with two items; the first one being a list of pairs of the form (‘’, int) where the empty string is for compatibility with other
SparseLabelOpand the integer corresponds to the mode index on which the operator gets applied; the second item of the returned tuple is the coefficient of this term.- Return type:
Iterator[tuple[list[tuple[str, int]], complex | ParameterExpression]]
- transpose()[source]¶
Returns the transpose of the operator.
- Returns:
The transpose of the operator.
- Return type:
- values() an object providing a view on D's values¶
- classmethod zero()¶
Constructs a zero-operator.
- Returns:
The zero-operator of the given length.
- Return type: