Skip to content

qiu-hamiltonian-simulation

Circuits of the time evolution e^(-i t H / hbar) under a time-independent potential V(x) or kinetic energy T(p), given as qiu-signals signals on axes of 2**n samples. A potential acts diagonally on the position amplitudes of a register, a kinetic energy on its momentum amplitudes, between Fourier transforms.

Quadratic potentials and kinetic energies, e.g. harmonic potentials, free particles or paraxial diffraction, are applied exactly by the direct phase circuits of qiu-quantum-computing. Arbitrary ones of one sign, sampled or algebraic, are applied by its sample-based phase propagator, sliced into small phases. The Fourier transforms are its QFT circuits.

In the monorepo, the direct momentum-domain evolution is the free-space propagator of the Qiskit backend of the lens experiments in wave_optics_propagation, which runs the simulation loop of qiu-classical-simulation.

Installation

pip install qiu-hamiltonian-simulation

Inside the monorepo, it is installed with the other workspace packages by uv sync --all-packages.

Quick start

The free evolution of a Gaussian wave packet of mass 1 over the time t = 0.2, applied in the momentum domain and compared with NumPy's FFT:

import numpy as np
from qiu_signals.algebraic_signal import QuadraticSignal
from qiu_signals.integer_axis import IndexOrdering
from qiu_signals.physical_axis import MomentumAxis, PositionAxis
from qiskit.quantum_info import Statevector
from qiu_hamiltonian_simulation.time_independent.direct import (
    MomentumDomainEvolutionQuadratic,
)

hbar, mass, t = 1.0, 1.0, 0.2
x_axis = PositionAxis(size=16, delta_x=0.5, ordering=IndexOrdering.CENTERED)
p_axis = MomentumAxis.from_position_axis(x_axis, hbar=hbar)  # FFT ordering

kinetic = QuadraticSignal(p_axis, alpha=1 / (2 * mass))
evolution = MomentumDomainEvolutionQuadratic((-t / hbar) * kinetic)

packet = np.exp(-(x_axis.values**2))
psi = Statevector(packet / np.linalg.norm(packet))
out = psi.evolve(evolution)

momentum_amplitudes = np.fft.fft(psi.data, norm="ortho")
expected = np.fft.ifft(
    np.exp(-1j * t / hbar * kinetic.data) * momentum_amplitudes, norm="ortho"
)
assert np.allclose(out.data, expected)

Where next