Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improve the documentation of SparseLabelOp.simplify #1261

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions qiskit_nature/second_q/operators/bosonic_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,20 +486,27 @@ def is_hermitian(self, atol: float | None = None) -> bool:
return all(np.isclose(coeff, 0.0, atol=atol) for coeff in diff.values())

def simplify(self, atol: float | None = None) -> BosonicOp:
"""Simplifies the terms of the BosonicOp
"""Simplify the operator.

Args:
atol: Absolute numerical tolerance. The default behavior is to use ``self.atol``.

Returns:
A new simplified BosonicOp (the original operator is not modified).
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

.. note::

:meth:`simplify` should be used to simplify terms whose coefficients are close to zero,
up to the specified numerical tolerance. It still differs slightly from :meth:`chop`
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. For example, check out :meth:`index_order`.

.. note::

:meth:`simplify` is not allowed to simplify the labels ``+_0 -_0`` or ``-_0 +_0``. The
Expand All @@ -508,6 +515,14 @@ def simplify(self, atol: float | None = None) -> BosonicOp:
:math:`1 + n`. As a consequence, the label ``+_0 -_0 -_1 +_0`` will remain untouched by
this method. This is in contrast to how :meth:`.FermionicOp.simplify` works,
because it exploits that :math:`n` can be either :math:`0` or :math:`1`.

This method returns a new operator (the original operator is not modified).

Args:
atol: Absolute numerical tolerance. The default behavior is to use ``self.atol``.

Returns:
The simplified operator.
"""
atol = self.atol if atol is None else atol

Expand Down
29 changes: 29 additions & 0 deletions qiskit_nature/second_q/operators/fermionic_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,35 @@ def is_hermitian(self, atol: float | None = None) -> bool:
return all(np.isclose(coeff, 0.0, atol=atol) for coeff in diff.values())

def simplify(self, atol: float | None = None) -> FermionicOp:
"""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

.. note::

:meth:`simplify` should be used to simplify terms whose coefficients are close to zero,
up to the specified numerical tolerance. It still differs slightly from :meth:`chop`
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. For example, check out :meth:`index_order`.

This method returns a new operator (the original operator is not modified).

Args:
atol: Absolute numerical tolerance. The default behavior is to use ``self.atol``.

Returns:
The simplified operator.
"""
atol = self.atol if atol is None else atol

data = defaultdict(complex) # type: dict[str, _TCoeff]
Expand Down
22 changes: 20 additions & 2 deletions qiskit_nature/second_q/operators/sparse_label_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,26 @@ def chop(self, atol: float | None = None) -> SparseLabelOp:
def simplify(self, atol: float | None = None) -> SparseLabelOp:
"""Simplify the operator.

Merges terms with same labels and eliminates terms with coefficients close to 0.
Returns a new operator (the original operator is not modified).
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

.. note::

:meth:`simplify` should be used to simplify terms whose coefficients are close to zero,
up to the specified numerical tolerance. It still differs slightly from :meth:`chop`
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).

Args:
atol: Absolute numerical tolerance. The default behavior is to use ``self.atol``.
Expand Down
29 changes: 29 additions & 0 deletions qiskit_nature/second_q/operators/vibrational_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,35 @@ def _index_order(
return new_label, coeff

def simplify(self, atol: float | None = None) -> VibrationalOp:
"""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

.. note::

:meth:`simplify` should be used to simplify terms whose coefficients are close to zero,
up to the specified numerical tolerance. It still differs slightly from :meth:`chop`
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. For example, check out :meth:`index_order`.

This method returns a new operator (the original operator is not modified).

Args:
atol: Absolute numerical tolerance. The default behavior is to use ``self.atol``.

Returns:
The simplified operator.
"""
atol = self.atol if atol is None else atol

data = defaultdict(complex) # type: dict[str, _TCoeff]
Expand Down