Trotterized Hamiltonian simulation

Trotterization approximates Hamiltonian time evolution by applying exponentials of simpler terms:

\( H=\sum_{j=1}^{m}h_j, \qquad U(t)=e^{-iHt}. \)

Zixy Hamiltonians

Zixy stores a Hamiltonian as a sum of coefficient-weighted Pauli strings:

\( H=\sum_{j=1}^{m}a_jP_j, \qquad P_j\in\{I,X,Y,Z\}^{\otimes n}. \)

import zixy.qubit.pauli as zqp

pauli_string = zqp.String.from_str("Z0 X1", 2)
hamiltonian = zqp.RealTermSum.from_str(
    "(-0.5, Z0 X1), (-0.1, X0 Z1), (-0.2, Y0 Y1)"
)
  • zqp.String represents one tensor product of Pauli operators.

  • zqp.RealTermSum represents a Hermitian Pauli Hamiltonian by pairing those strings with real coefficients.

  • trotter_first_order converts every non-identity term into a Pauli exponential.

Pauli exponentials

pauli_exp constructs a Guppy function implementing a Pauli-string exponential:

\( U_P(\theta)=e^{-i\theta P/2}. \)

from guppyalgos.primitives.pauli.pauli_exp import cntrl_pauli_exp, pauli_exp

pauli_gadget = pauli_exp(pauli_string, n_qubits=2)
controlled_pauli_gadget = cntrl_pauli_exp(pauli_string, n_qubits=2)

The input may contain any tensor product of \(I\), \(X\), \(Y\), and \(Z\). Only its non-identity support participates in the parity ladder:

Pauli

Basis change before the parity ladder

\(I\)

None; this qubit is omitted from the ladder.

\(X\)

\(H\) maps \(X\) to \(Z\).

\(Y\)

Apply \(S^\dagger\), then \(H\), to map \(Y\) to \(Z\).

\(Z\)

None; it is already in the required basis.

For \(P = Z_0X_1\), the ordinary gadget is:

A Pauli gadget for Z on q_0 and X on q_1. A Hadamard changes q_1 to the Z basis, a pair of controlled-NOT gates surrounds an RZ rotation on q_1, and a final Hadamard restores the original basis.

The controlled form uses the same basis changes and parity ladder, but the external qubit controls the central rotation:

\( C(U_P)=|0\rangle\!\langle 0|\otimes I +|1\rangle\!\langle 1|\otimes U_P(\theta). \)

A controlled Pauli gadget for Z on q_0 and X on q_1. The parity ladder surrounds an RZ rotation on q_1 controlled by an external control qubit.

  • Basis changes map every non-identity Pauli to the Z basis.

  • A CX ladder computes the joint parity onto its target qubit.

  • pauli_exp applies R_Z to the parity target.

  • cntrl_pauli_exp replaces it with CR_Z, leaving the target operation inactive when the external control is zero.

  • The CX ladder and basis changes are then uncomputed.

  • The uncontrolled factory rejects an identity string. The controlled factory preserves its observable relative phase by rotating the control qubit.

Choose the circuit construction

The Pauli string fixes the operator, but it does not fix the circuit used for the parity computation or terminal rotation. These inputs can be selected when the gadget is built:

Input

Default

Other supported use

pauli_string

Required zqp.String

Any \(I/X/Y/Z\) tensor product; pauli_exp requires at least one non-identity Pauli.

n_qubits

Required integer

May be larger than the Pauli support, provided every Pauli index is in range.

cx_ladder

CXLadderLog

CXLadderLinear, or another implementation of the Ladder protocol.

rz_method

rz

Any compatible (qubit, angle) -> None guppy function, including an RUS \(R_Z\) construction.

controlled_rz_method

crz

For cntrl_pauli_exp, any compatible (control, target, angle) -> None guppy function.

For example, this keeps the same \(e^{-i\theta P/2}\) operation while choosing a linear CX ladder and a repeat-until-success rotation:

from guppyalgos.primitives.rotations import (
    dummy_theta_resource_state, repeat_until_success_rz,
)
from guppyalgos.primitives.subroutines.ladders import CXLadderLinear

rus_rz = repeat_until_success_rz(dummy_theta_resource_state)
rus_pauli_gadget = pauli_exp(
    pauli_string,
    n_qubits=2,
    cx_ladder=CXLadderLinear,
    rz_method=rus_rz,
)

The RUS implementation changes how the central \(R_Z\) is synthesized. The basis changes, parity ladder, angle convention, and resulting Pauli exponential remain the same.

See the Pauli-exponential notebook for a complete executable example and alternative rotation implementations.

Constructing the Trotter simulation

A first-order Trotter simulation applies the Zixy term exponentials sequentially, then repeats the resulting step:

\( e^{-iHt} \approx \left(\prod_{j=1}^{m}e^{-ih_jt/r}\right)^r, \qquad \text{error}=O\!\left(\frac{t^2}{r}\right). \)

from guppyalgos.algorithms.time_evolution.trotter import ham_sim_trotter, trotter_first_order

n_state_qubits = len(hamiltonian.qubits)
trotter_step = trotter_first_order(hamiltonian, n_state_qubits)
simulation = ham_sim_trotter(
    trotter_step, n_steps=10, time_step=0.01,
    n_state_qubits=n_state_qubits,
)

The Hamiltonian and product-formula order determine the sequence of Pauli exponentials. The ladder and rotation inputs are passed to every term, so one choice changes the complete Trotter step consistently.

Builder

Input Hamiltonian or schedule

Result

trotter_first_order

zqp.RealTermSum

One forward pass through the non-identity terms.

cntrl_trotter_first_order

zqp.RealTermSum

Controlled forward pass; retains identity terms as relative phases.

trotter_higher_order

zqp.RealTermSum and even order >= 2

Symmetric Suzuki formula; higher orders recursively reduce product-formula error.

cntrl_trotter_higher_order

Same inputs plus controlled rotation methods

Controlled symmetric Suzuki formula.

trotter_from_sequence

Terms and (term_index, time_factor) pairs

Custom ordering, repeated terms, and signed time factors.

For example, a second-order step applies half steps forward and backward,

\[ S_2(t)= \prod_{j=1}^{m}e^{-i h_jt/2} \prod_{j=m}^{1}e^{-i h_jt/2}, \]

and is built with:

from guppyalgos.algorithms.time_evolution.trotter import trotter_higher_order

second_order_step = trotter_higher_order(
    hamiltonian,
    n_state_qubits,
    order=2,
    cx_ladder=CXLadderLinear,
)

At runtime, each term receives an angle equal to its coefficient multiplied by the sequence factor and time_step. Negative sequence factors implement backward evolution. ham_sim_trotter then repeats the completed step n_steps times.

See the Trotter Hamiltonian-simulation notebook for the complete construction, execution, and accuracy comparison.

Continue with Phase estimation to use controlled Trotter steps in QPE.