---
title: FermionicTrotterization (latest version)
description: API reference for qiskit_fermions.transpiler.passes.FermionicTrotterization in the latest version of qiskit-fermions
source: https://quantum.cloud.ibm.com/docs/en/api/qiskit-fermions/transpiler-passes-fermionic-trotterization
---

# FermionicTrotterization

*class* `FermionicTrotterization(synthesis, *, apply=True, filter=None)`

Bases: [`GenericPass`](/docs/api/qiskit/qiskit.passmanager.GenericPass)\[[`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit), [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit)]

A transpilation pass Trotterizing [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") gates in fermionic space.

An [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") gate carries the synthesis method with which it gets decomposed in fermionic space (see [`Evolution.synthesis`](/docs/api/qiskit-fermions/circuit-library-evolution#synthesis "qiskit_fermions.circuit.library.Evolution.synthesis")). Setting it per gate means threading the choice through everything that constructs one – including [`UCC`](/docs/api/qiskit-fermions/circuit-library-ucc "qiskit_fermions.circuit.library.UCC") and [`UCJ`](/docs/api/qiskit-fermions/circuit-library-ucj "qiskit_fermions.circuit.library.UCJ"), which build their own internally. This pass applies one method to every [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") in a circuit instead, so the choice can be made once for a whole transpilation pipeline:

```python
pm.optimization = FermionicPassManager(
    [FermionicTrotterization(FermionicSuzukiTrotter(order=2, reps=4))]
)
```

Each selected gate is replaced by the factors its method emits, so the pass both chooses the formula and carries it out. Nodes that are not [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") gates are left untouched, as are those rejected by an optional [`filter`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.filter "qiskit_fermions.transpiler.passes.FermionicTrotterization.filter").

> **Note**
>
> Running the pass again is harmless: the factors a synthesis method emits are [`Evolution.atomic`](/docs/api/qiskit-fermions/circuit-library-evolution#atomic "qiskit_fermions.circuit.library.Evolution.atomic"), and an atomic gate is a terminal factor which this pass leaves in place rather than splitting further. The same exemption makes the pass a fixed point over the output of [`QDriftTrotterization`](/docs/api/qiskit-fermions/transpiler-passes-q-drift-trotterization "qiskit_fermions.transpiler.passes.QDriftTrotterization"), whose sampled gates are atomic because the random draw *is* the Trotterization it performs.

> **Note**
>
> Set [`apply`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.apply "qiskit_fermions.transpiler.passes.FermionicTrotterization.apply") to `False` to only *select* the method and leave the expansion to something else, such as Qiskit’s [`Decompose`](/docs/api/qiskit/qiskit.transpiler.passes.Decompose) or a [`decompose()`](/docs/api/qiskit-fermions/circuit-fermionic-circuit#decompose "qiskit_fermions.circuit.FermionicCircuit.decompose") call. Be aware that a gate which is never expanded reaches the fermion-to-qubit stage whole, where it is mapped without [`Evolution.synthesis`](/docs/api/qiskit-fermions/circuit-library-evolution#synthesis "qiskit_fermions.circuit.library.Evolution.synthesis") ever being read – and every synthesis method then produces identical output.

> **Caution**
>
> Not every synthesis method suits every operator. An [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") whose operator groups all mutually commute (the diagonal-Coulomb operators of a [`UCJ`](/docs/api/qiskit-fermions/circuit-library-ucj "qiskit_fermions.circuit.library.UCJ"), for example) is synthesized exactly at any order, so a higher order only adds depth. Use [`filter`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.filter "qiskit_fermions.transpiler.passes.FermionicTrotterization.filter") to restrict the pass to the gates that benefit.
>
> Expanding an operator that carries no [`groups`](/docs/api/qiskit-fermions/operators-operator-trait#groups "qiskit_fermions.operators.OperatorTrait.groups") splits it term by term, and a lone $a^\dagger_i a_j$ is not Hermitian, so its exponential is not unitary. Nothing complains until the mapped operator reaches [`PauliEvolutionGate`](/docs/api/qiskit/qiskit.circuit.library.PauliEvolutionGate), which raises `ValueError: Operator contains complex coefficients, which are not supported`. Assigning conjugate-paired groups is what makes each factor Hermitian.

Initializing this transpiler pass can be done with the arguments listed below.

**Parameters**

- **synthesis** ([*FermionicEvolutionSynthesis*](/docs/api/qiskit-fermions/circuit-library-synthesis-fermionic-evolution-synthesis "qiskit_fermions.circuit.library.synthesis.FermionicEvolutionSynthesis")) – the fermion-to-fermion synthesis method to apply to the [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") gates of the circuit.
- **apply** ([*bool*](https://docs.python.org/3/builtins/functions.html#bool)) – whether to expand each selected gate into the factors `synthesis` produces. When `False`, the gate is only tagged with `synthesis` and something else has to expand it later. See [`apply`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.apply "qiskit_fermions.transpiler.passes.FermionicTrotterization.apply").
- **filter** (*Callable\[\[DAGOpNode],* [*bool*](https://docs.python.org/3/builtins/functions.html#bool)*] | None*) – an optional predicate deciding which [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") nodes to apply `synthesis` to. It is called with the [`DAGOpNode`](/docs/api/qiskit/qiskit.dagcircuit.DAGOpNode) and the node is left untouched unless it returns `True`. If `None` (the default), every [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") node is selected.

## Attributes

### synthesis

The fermion-to-fermion synthesis method applied to the selected gates.

### apply

Whether to expand each selected gate into the factors [`synthesis`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis "qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis") produces.

When this is `False`, the pass only *selects* the method: it tags each selected gate with [`synthesis`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis "qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis") and leaves the expansion to whatever builds the gate’s definition later, such as Qiskit’s [`Decompose`](/docs/api/qiskit/qiskit.transpiler.passes.Decompose) or a [`decompose()`](/docs/api/qiskit-fermions/circuit-fermionic-circuit#decompose "qiskit_fermions.circuit.FermionicCircuit.decompose") call. Note that a gate which is never expanded reaches the fermion-to-qubit stage whole, where it is mapped without [`Evolution.synthesis`](/docs/api/qiskit-fermions/circuit-library-evolution#synthesis "qiskit_fermions.circuit.library.Evolution.synthesis") ever being read, and every synthesis method then produces identical output.

### filter

The predicate selecting which [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") nodes to apply [`synthesis`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis "qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis") to.

## Methods

### run

`run(dag)`

Runs this transpilation pass.

Every [`Evolution`](/docs/api/qiskit-fermions/circuit-library-evolution "qiskit_fermions.circuit.library.Evolution") node accepted by [`filter`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.filter "qiskit_fermions.transpiler.passes.FermionicTrotterization.filter") is replaced by the factors that [`synthesis`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis "qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis") produces, or (when [`apply`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.apply "qiskit_fermions.transpiler.passes.FermionicTrotterization.apply") is `False`) by an equivalent gate merely carrying [`synthesis`](#qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis "qiskit_fermions.transpiler.passes.FermionicTrotterization.synthesis"). All other nodes are left untouched. The input DAG is modified in place.

**Parameters**

**dag** ([*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit)) – the input circuit with fermion-based instructions. Only [`DAGOpNode`](/docs/api/qiskit/qiskit.dagcircuit.DAGOpNode) with [`FermionicGate`](/docs/api/qiskit-fermions/circuit-fermionic-gate "qiskit_fermions.circuit.FermionicGate") instances as their [`op`](/docs/api/qiskit/qiskit.dagcircuit.DAGOpNode#op) are supported.

**Returns**

The output circuit which is still acting on a fermionic register.

**Return type**

[*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit)

**Inherited Methods**

### execute

`execute(passmanager_ir, state, callback=None)`

Execute optimization task for input Qiskit IR.

**Parameters**

- **passmanager\_ir** (*IR*) – Qiskit IR to optimize.
- **state** ([*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState)) – State associated with workflow execution by the pass manager itself.
- **callback** ([*Callable*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)*\[\[*[*Task*](/docs/api/qiskit/qiskit.passmanager.Task)*, IR\_OUT,* [*PropertySet*](/docs/api/qiskit/qiskit.passmanager.PropertySet)*,* [*float*](https://docs.python.org/3/builtins/functions.html#float)*,* [*int*](https://docs.python.org/3/builtins/functions.html#int)*], None] | None*) – A callback function which is called per execution of optimization task.

**Returns**

Optimized Qiskit IR and state of the workflow.

**Return type**

[tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)\[*IR\_OUT*, [*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState)]

### name

`name()`

Name of the pass.

**Return type**

[str](https://docs.python.org/3/builtins/stdtypes.html#str)

### update\_status

`update_status(state, run_state)`

Update workflow status.

**Parameters**

- **state** ([*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState)) – Pass manager state to update.
- **run\_state** (*RunState*) – Completion status of current task.

**Returns**

Updated pass manager state.

**Return type**

[*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState)
