Transverse-Field Ising Model
Simulate the real-time dynamics of a 1D transverse-field Ising model (TFIM) by
Trotterizing its time-evolution operator — a landmark model of condensed-matter physics, a standard
benchmark for quantum simulation and variational algorithms. The reference implementation runs today on
the CPU statevector target (qpp-cpu); the GPU backends referenced below are on the roadmap and
not yet released.
What it is
The Ising model describes a row of spins (qubits) where neighbouring spins couple to one another, while the whole chain is immersed in a transverse magnetic field. Its Hamiltonian is:
H = -J · Σ<i> Z_i Z_{i+1} - h · Σ<i> X_i
The two terms play opposing roles:
| Term | Operator | Physical meaning |
|---|---|---|
| Coupling | −J · ZiZi+1 | Makes neighbouring spins want to align (ferromagnetic for J>0) — the source of "order". |
| Transverse field | −h · Xi | Flips spins along X, injecting quantum fluctuations — the source of "disorder". |
The crux is that X and Z do not commute: the field term constantly tries to flip spins that the
coupling has aligned, so order and fluctuation compete. The ratio h/J decides which wins.
Intuition — the tug-of-war between order and fluctuation
Think of h/J as a dial. When h/J ≈ 0 the coupling dominates and the ground
state is a neatly aligned ferromagnetic order. When h/J is large the field dominates
and each spin is independently pulled along X, the bulk magnetization washed out by fluctuations into a
disordered paramagnetic state. Between the two lies a critical point (h/J)c
where the system undergoes a quantum phase transition.
Why it matters — quantum phase transitions
Unlike classical phase transitions driven by heating, a quantum phase transition happens at
absolute zero, driven by quantum (not thermal) fluctuations, triggered purely by tuning
the Hamiltonian parameter h/J. The 1D TFIM is special because it is exactly solvable
(mapped to free fermions via the Jordan–Wigner transformation), with the critical point precisely at
(h/J)c = 1. Near the critical point the correlation length diverges, the energy gap
closes, and the system exhibits universal critical scaling.
Because the answer is known yet the problem is genuinely "hard", the TFIM is an ideal touchstone for testing quantum algorithms:
- Real-time dynamics. Evolve under
exp(−i·H·t)to watch excitations (such as domain walls) propagate — exactly what this page does. - VQE / ground state. Approximate the ground-state energy with a variational quantum eigensolver and check it point by point against the exact solution.
- Locating the transition. Sweep
h/Jand recover the critical point(h/J)c = 1from observables like the magnetization.
Why it works — Trotterized time evolution
We want to apply the time-evolution operator exp(−i·H·t), but the X and ZZ terms in
H do not commute, so we cannot simply "exponentiate them separately". The Trotter
decomposition gives a controlled approximation: slice the evolution into many small steps dt,
and within each step apply the field term and then the coupling term separately:
exp(−i·H·dt) ≈ exp(i·h·dt·ΣXi) · exp(i·J·dt·ΣZiZi+1)
Each individual term maps to a simple gate: the field term is a single-qubit rotation about X
(rx); the ZZ coupling can be implemented with a pair of CNOTs sandwiching an
rz. Repeating this small step n_steps times evolves the state forward to time
n_steps·dt. The smaller dt, the more accurate the approximation — at the cost of
more gates.
What it is good at — and its limits
- A trustworthy benchmark, because there is an exact solution to check against. Being able to compare point by point with the analytic result makes it the gold standard for validating simulators and hardware.
- The statevector grows exponentially with the number of spins. N spins need
2N complex amplitudes — precisely the motivation for the planned GPU statevector backend
(and multi-GPU sharding) on the roadmap; today the reference implementation runs on the
qpp-cpuCPU target. - Trotter error must be managed. A first-order decomposition has O(dt2) error per step; switching to a second-order (Suzuki–Trotter) step substantially lowers the discretization error.
- For low entanglement, there are shortcuts. For very long, weakly entangled chains, tensor-network methods are often more efficient than a dense statevector.
Building the Hamiltonian
Read it against the model above: spin.z(i) * spin.z(i+1) accumulates the ZZ couplings
along the open chain term by term, spin.x(i) accumulates the transverse field, and the
overall minus signs correspond to −J and −h, matching the formula one-to-one.
import qalgora
from qalgora import spin
import numpy as np
n_spins = 8
J, h = 1.0, 1.0
def tfim_hamiltonian(n, J, h):
H = 0
for i in range(n - 1): # ZZ couplings (open chain)
H -= J * spin.z(i) * spin.z(i + 1)
for i in range(n): # transverse field
H -= h * spin.x(i)
return H
hamiltonian = tfim_hamiltonian(n_spins, J, h)
Trotterized time evolution
Read it against the "Why it works" section above: rx(-2.0 * h * dt, q[i]) implements the
single-step evolution of the field term; the x.ctrl then rz(-2.0 * J * dt, ...)
then x.ctrl sandwich is the standard implementation of the ZZ coupling term.
evolve starts from a single flipped spin (a domain wall) and repeatedly applies the step to
evolve it forward.
@qalgora.kernel
def trotter_step(q: qalgora.qview, dt: float, J: float, h: float):
n = q.size()
# transverse-field term: exp(i h dt X_i)
for i in range(n):
rx(-2.0 * h * dt, q[i])
# coupling term: exp(i J dt Z_i Z_{i+1})
for i in range(n - 1):
x.ctrl(q[i], q[i + 1])
rz(-2.0 * J * dt, q[i + 1])
x.ctrl(q[i], q[i + 1])
@qalgora.kernel
def evolve(n: int, steps: int, dt: float, J: float, h: float):
q = qalgora.qvector(n)
x(q[0]) # start from a single flipped spin (domain wall)
for _ in range(steps):
trotter_step(q, dt, J, h)
Tracking the magnetization
Take the observable to be the average ⟨Z⟩ over the spins and use qalgora.observe to measure
its expectation value at each time slice; this lets you plot the magnetization evolving in time — the
spreading domain wall pulls the curve away from its initial value over time.
qalgora.set_target("qpp-cpu") # runnable today — CPU statevector reference implementation
# qalgora.set_target("gpu") # planned: GPU backend not yet released
dt, n_steps = 0.05, 100
magnetization = spin.z(0)
for i in range(1, n_spins):
magnetization += spin.z(i)
magnetization /= n_spins
times, mz = [], []
for step in range(n_steps):
res = qalgora.observe(evolve, magnetization, n_spins, step, dt, J, h)
times.append(step * dt)
mz.append(res.expectation())
print("final ⟨Z⟩ =", mz[-1])
gpu target would keep that state in GPU memory and apply each Trotter layer as a
batched tensor operation, so a 30-spin chain that crawls on CPU would run interactively on a single
GPU; a planned gpu-mqpu target would shard the state across multiple GPUs.
These GPU backends are on the roadmap and not yet released — the runnable reference implementation
uses the qpp-cpu CPU target.
Scaling up & next steps
- Increase
n_spinsand watch the CPUqpp-cpuwall-clock grow (the plannedgpubackend targets the 30+ spin regime). - Sweep
h/Jto locate the quantum phase transition in the steady-state magnetization. - Use a second-order (Suzuki–Trotter) step to cut the time-discretization error.
- For very long chains with low entanglement, a
tensornettarget is planned.
横场伊辛模型
通过对时间演化算符做特罗特(Trotter)分解,模拟一维横场伊辛模型 (TFIM) 的实时动力学——它既是凝聚态物理的标志性模型,也是量子模拟与变分算法的标准基准。参考实现今天即可在 CPU 态矢量后端(qpp-cpu)上运行;下文提到的 GPU 后端属于规划中·尚未发布。
它是什么
伊辛模型描述一排自旋(量子比特),相邻自旋之间相互耦合,同时整体浸没在一个横向磁场中。其哈密顿量为:
H = -J · Σ<i> Z_i Z_{i+1} - h · Σ<i> X_i
这里两项各司其职:
| 项 | 算符 | 物理含义 |
|---|---|---|
| 耦合项 | −J · ZiZi+1 | 让相邻自旋倾向于对齐(J>0 时铁磁),即"秩序"的来源。 |
| 横场项 | −h · Xi | 沿 X 方向翻转自旋,注入量子涨落,即"混乱"的来源。 |
关键在于 X 与 Z 不对易:横场项不断试图把已对齐的自旋翻转,于是秩序与涨落彼此竞争。比值 h/J 决定谁占上风。
直觉 秩序与涨落的拉锯
把 h/J 想成一个旋钮。当 h/J ≈ 0 时耦合项主宰,基态是所有自旋整齐排列的铁磁序。当 h/J 很大时横场主宰,每个自旋都被独立拉向 X 方向,整体磁化被涨落抹平成顺磁无序态。在两者之间,存在一个临界点 (h/J)c,系统在此发生量子相变。
为何重要 量子相变
与靠加热驱动的经典相变不同,量子相变发生在绝对零度,由量子涨落(而非热涨落)驱动,纯粹通过调节哈密顿量参数 h/J 触发。一维 TFIM 的特殊之处在于它精确可解(经 Jordan–Wigner 变换映为自由费米子),临界点恰为 (h/J)c = 1。在临界点附近,关联长度发散、能隙闭合,系统展现普适的临界标度。
正因为答案已知、又足够"难",TFIM 成了检验量子算法的理想试金石:
- 实时动力学。演化
exp(−i·H·t)来观察激发(如畴壁)如何传播——这正是本页所做的。 - VQE / 基态。用变分量子本征求解器逼近基态能量,可与精确解逐点核对。
- 相变定位。扫描
h/J,从磁化等可观测量中复现(h/J)c = 1这一临界点。
为何成立 特罗特时间演化
我们想施加时间演化算符 exp(−i·H·t),但 H 中的 X 与 ZZ 两类项互不对易,不能简单地"分开做指数"。特罗特分解给出一个受控近似:把演化切成许多小步 dt,在每一小步内先单独施加场项、再单独施加耦合项:
exp(−i·H·dt) ≈ exp(i·h·dt·ΣXi) · exp(i·J·dt·ΣZiZi+1)
每个单项都对应一个简单门:场项是单比特绕 X 的旋转 rx;ZZ 耦合项可用一对 CNOT 夹住一个 rz 来实现。重复这一小步 n_steps 次,就把状态向前演化到时刻 n_steps·dt。步长 dt 越小,近似越精确,代价是门数更多。
它擅长什么 又有何局限
- 它是可信的基准,因为有精确解可对照。能与解析结果逐点比对,使它成为检验模拟器与硬件的金标准。
- 态矢量随自旋数指数增长。N 个自旋需要 2N 个复数振幅,这正是规划中的 GPU 态矢量后端(乃至多 GPU 分片)的动机;当前参考实现运行于
qpp-cpuCPU 后端。 - 特罗特误差需要管理。一阶分解每步误差为 O(dt2);改用二阶(Suzuki–Trotter)步可显著压低离散化误差。
- 低纠缠时另有捷径。对纠缠较弱的超长链,张量网络方法往往比稠密态矢量更高效。
构建哈密顿量
请对照上文模型来读:spin.z(i) * spin.z(i+1) 逐项累加开链上的 ZZ 耦合,spin.x(i) 累加横场,整体的负号对应 −J 与 −h,与公式一一对应。
import qalgora
from qalgora import spin
import numpy as np
n_spins = 8
J, h = 1.0, 1.0
def tfim_hamiltonian(n, J, h):
H = 0
for i in range(n - 1): # ZZ couplings (open chain)
H -= J * spin.z(i) * spin.z(i + 1)
for i in range(n): # transverse field
H -= h * spin.x(i)
return H
hamiltonian = tfim_hamiltonian(n_spins, J, h)
特罗特(Trotter)时间演化
对照上文"为何成立"一节来读:rx(-2.0 * h * dt, q[i]) 实现场项的单步演化;而 x.ctrl 接 rz(-2.0 * J * dt, ...) 再接 x.ctrl 这组夹层正是 ZZ 耦合项的标准实现。evolve 从一个翻转的自旋(畴壁)出发,反复施加该步将其向前演化。
@qalgora.kernel
def trotter_step(q: qalgora.qview, dt: float, J: float, h: float):
n = q.size()
# transverse-field term: exp(i h dt X_i)
for i in range(n):
rx(-2.0 * h * dt, q[i])
# coupling term: exp(i J dt Z_i Z_{i+1})
for i in range(n - 1):
x.ctrl(q[i], q[i + 1])
rz(-2.0 * J * dt, q[i + 1])
x.ctrl(q[i], q[i + 1])
@qalgora.kernel
def evolve(n: int, steps: int, dt: float, J: float, h: float):
q = qalgora.qvector(n)
x(q[0]) # start from a single flipped spin (domain wall)
for _ in range(steps):
trotter_step(q, dt, J, h)
跟踪磁化强度
把可观测量取为各自旋 ⟨Z⟩ 的平均,用 qalgora.observe 在每个时间片测量它的期望值,便能画出磁化随时间的演化——畴壁的扩散会令该曲线随时间偏离初值。
qalgora.set_target("qpp-cpu") # 今天即可运行——CPU 态矢量参考实现
# qalgora.set_target("gpu") # 规划中:GPU 后端尚未发布
dt, n_steps = 0.05, 100
magnetization = spin.z(0)
for i in range(1, n_spins):
magnetization += spin.z(i)
magnetization /= n_spins
times, mz = [], []
for step in range(n_steps):
res = qalgora.observe(evolve, magnetization, n_spins, step, dt, J, h)
times.append(step * dt)
mz.append(res.expectation())
print("final ⟨Z⟩ =", mz[-1])
gpu 后端会将该状态保存在 GPU 显存中,并将每个特罗特层作为批量张量运算执行,使在 CPU 上需要漫长等待的 30 自旋链得以在单张 GPU 上流畅运行;规划中的 gpu-mqpu 后端则可将状态分布到多张 GPU 上。这些 GPU 后端属于规划中·尚未发布——可运行的参考实现使用 qpp-cpu CPU 后端。
扩展规模与后续步骤
- 增大
n_spins,观察qpp-cpu上实际运行时间的增长(规划中的gpu后端面向 30 以上自旋的规模)。 - 扫描
h/J的取值,在稳态磁化强度中定位量子相变点(一维 TFIM 的精确临界点为(h/J)c = 1)。 - 使用二阶(Suzuki–Trotter)步长来降低时间离散化误差。
- 对于低纠缠的超长链,规划提供
tensornet后端。