# filter_diagonal_terms

### filter_diagonal_terms(op)

Filters out the terms of an operator that are diagonal in the occupation-number basis.

This removes every term from the provided
[`BosonOperator`](qiskit_bosons.operators.BosonOperator.html.md#qiskit_bosons.operators.BosonOperator) that is a product of number operators
($b^\dagger_i b_i$). This includes the constant term (a product of zero number operators),
single number operators, as well as higher-order products such as
$n_i n_j = b^\dagger_i b^\dagger_j b_j b_i$. A mode may repeat, so products such as
$b^\dagger_i b^\dagger_i b_i b_i = n_i (n_i - 1)$ are diagonal, too.

#### HINT
A diagonal term only multiplies each Fock state by a phase. Filtering such terms is therefore
only appropriate when that phase is irrelevant to what you compute, for example when only
the sampled occupations of a time-evolved state matter. It is *not* a general simplification:
on a superposition of Fock states, the phases differ between its components.

#### CAUTION
The provided operator *must* be normal-ordered! This is an underlying assumption of the
implementation that is *not* being verified. See
[`normal_ordered()`](qiskit_bosons.operators.BosonOperator.html.md#qiskit_bosons.operators.BosonOperator.normal_ordered) for how to get an operator
of that form.

#### NOTE
The operator is modified *in place*. If it tracks group indices (see
[`groups`](qiskit_bosons.operators.BosonOperator.html.md#qiskit_bosons.operators.BosonOperator.groups)), surviving terms retain their
relative grouping but the group indices are reassigned to a contiguous range starting from 0.
You must therefore *not* rely on the specific group index of any term being preserved across
a call to this function.

```pycon
>>> from qiskit_bosons.operators import BosonOperator
>>> from qiskit_bosons.operators.terms.filtering import filter_diagonal_terms
>>> op = BosonOperator.from_dict(
...     {
...         (): 1.0,  # constant (diagonal)
...         ((True, 0), (False, 0)): 2.0,  # n_0 (diagonal)
...         ((True, 0), (True, 1), (False, 1), (False, 0)): 3.0,  # n_0 n_1 (diagonal)
...         ((True, 0), (False, 1)): 4.0,  # b†_0 b_1 (off-diagonal)
...     }
... )
>>> filter_diagonal_terms(op)
>>> list(op.iter_terms())
[([(True, 0), (False, 1)], (4+0j))]
```

* **Parameters:**
  **op** – the normal-ordered operator whose diagonal terms to filter out.
