The Machinery · Topic 25 of 41 · The Workbench: before the tools

The Hamiltonian and time evolution

What is a Hamiltonian, and how does a table of numbers turn into a gate?

  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07
  8. 08
  9. 09
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
About this section: The Workbench: before the tools

Everything above is mathematics you can do on paper. This part is the other half: what a researcher does on a computer to see how a superconducting qubit behaves. Two free programs do most of it, QuTiP for how a system changes in time and scqubits for the levels of a circuit, and both are taught here from the beginning. This first group builds what they are made of: a state as a list of numbers, the one equation that moves it, and the oscillator that a resonator is. Every number in the part was produced by QuTiP 5.2.0 or scqubits 4.3.1, every example prints what the page says it prints, and each topic has an explorer you can move; all of them are on one page, the Workbench. If you only want to install the programs, start at topic 33.

See it

|0⟩ |1⟩ B the state turns about B at a steady rate e^(−iHt) H = ½ B · σ a 2 × 2 table of energies, one number per axis 5 GHz = 2π × 5 = 31.4 rad per ns the factor 2π is the unit trap a gate = H switched on for a time t 20 MHz drive on σx: a π rotation takes 25 ns
A Hamiltonian is a rotation waiting for a clock. For one qubit it is a field B; the state turns about the direction of B at a rate equal to its size. Switch it on for the right time and you have a gate.

Try it: set a field and watch a qubit turn

Choose a starting state, set the three components of the field in GHz, and press play. The violet trail is the path of the Bloch vector, and the readout says how often it goes round. Put all the field on Z and nothing happens to |0⟩ (an eigenstate only gains a phase); put it on X and |0⟩ rolls over to |1⟩ and back.

Honest limits: this is one qubit with a field that does not change in time, the case where the answer is exact. A drive that varies with time, like a real microwave pulse, is the next topic.

The intuition

The Hamiltonian is the table of numbers that says how much energy each state has and how the states are mixed. The rule for time is one line, the Schrödinger equation: the state changes at a rate that is the Hamiltonian applied to the state (with a factor of i and of 1/ħ that, in the units used here, disappear). If the state is one of the Hamiltonian’s own eigenstates, applying H just multiplies it by a number, the energy, and the state only picks up a phase that nobody can see. If it is a superposition of two eigenstates, each part picks up its own phase, the phases drift apart at a rate set by the energy gap, and on the Bloch sphere that drift is a turn about the axis that joins the two eigenstates.

A gate is that turn, stopped at the right moment. A drive that gives the qubit a field along X turns |0⟩ toward |1⟩; leave it on for the time that makes half a turn and you have an X gate. This is exactly how a microwave pulse implements a gate on a superconducting chip, and why the length and strength of the pulse are what a lab calibrates (the circuits lesson lets you recalibrate one blind).

The unit trap. Qubit frequencies are quoted in gigahertz, but the Schrödinger equation wants an angular rate, radians per unit time. One cycle is 2π radians, so a 5 GHz qubit advances its phase by 31.4 radians every nanosecond. A program that is handed 5 and told the unit is radians per nanosecond simulates a qubit of 5/2π = 0.796 GHz, with no error message, and everything it does looks fine except that it is 6.3 times slower than the device. Every number in this part is in GHz and ns, and every conversion to a solver is written out.

Why simulations avoid the lab frame. A 5 GHz qubit turns five times per nanosecond, and a gate takes tens of nanoseconds, so a program that follows the fast turning has to take a hundred steps per gate just to keep up. The next topic removes the fast rotation by changing to a frame that turns with it. That change of frame is what the “rotating-wave approximation” is about.

The mathematics

The equation. In units where ħ = 1 (so that energies are angular frequencies),

i d|ψ⟩/dt = H|ψ⟩

When H does not depend on time the solution is |ψ(t)⟩ = U(t)|ψ(0)⟩ with U(t) = e−iHt, defined by the power series of the exponential. H is Hermitian, so U is unitary: U†U = I, and the norm of the state never changes. If H = Σk Ek|k⟩⟨k| then

U(t) = Σk e−iEkt |k⟩⟨k|

which is how a numerical solver does it for a fixed H: diagonalise once, then every time is a sum of phases. That is exact, with no step size.

One qubit. Write H = ½ B·σ = ½(Bxσx + Byσy + Bzσz), with B in rad per ns. Because (n·σ)² = I for a unit vector n,

e−iθ(n·σ)/2 = cos(θ/2) I − i sin(θ/2) (n·σ), θ = |B| t, n = B/|B|

This is a rotation of the Bloch sphere by the angle θ about the axis n. The Bloch vector r obeys dr/dt = B × r, a vector turning about B at angular speed |B|, so its period is 2π/|B| (1/|B| if B is quoted in GHz). The two energy levels are ±|B|/2, and the gap |B| is the rotation rate.

A π pulse. With H = (Ω/2)σx the probability of finding |1⟩ after starting in |0⟩ is sin²(Ωt/2), so a rotation by π needs t = π/Ω. For a Rabi rate Ω/2π = 20 MHz, Ω = 0.12566 rad per ns and t = 25 ns. A solver started from |0⟩ returns the excited-state probabilities 0, 0.5, 1, 0.5 and 0 at 0, 12.5, 25, 37.5 and 50 ns.

Try it in Python. sesolve solves this equation, for a time-independent or a time-dependent H; e_ops asks it to return expectation values of operators instead of whole states. Run on QuTiP 5.2.0, 25 October 2026:

import numpy as np
import qutip as qt

# A drive that rotates the qubit at 20 MHz. QuTiP wants rad per ns, so multiply a frequency by 2*pi.
Omega = 2 * np.pi * 0.020                    # rad/ns
H = 0.5 * Omega * qt.sigmax()
times = np.array([0.0, 12.5, 25.0, 37.5, 50.0])   # ns
res = qt.sesolve(H, qt.basis(2, 0), times, e_ops=[qt.num(2)])
print(np.round(res.expect[0], 4))            # probability of finding |1>: 0, 1/2, 1, 1/2, 0

# The unit trap: a "5 GHz" qubit handed to a solver that reads its input as rad/ns
given = 5.0
print(given / (2 * np.pi))                   # the qubit you actually simulated, in GHz
[0.  0.5 1.  0.5 0. ]
0.7957747154594768
People keep asking: Where is ℏ, and what units does QuTiP use?

QuTiP has no built-in ℏ or h and no fixed units. A Hamiltonian is in whatever units its coefficients are written in, and the list of times must be in the matching inverse unit. This part sets ℏ = 1, so each entry of a Hamiltonian is an angular frequency (radians per nanosecond) and times are in nanoseconds. A frequency typed in GHz without the 2π therefore gives a qubit 2π times too slow, which is the 0.796 GHz of the example above.

This is a question QuTiP users have asked on the project’s user group more than once (for example under the title What are the energy/time/temperature… units used in QuTiP?), and the answer there is the same: you choose the units, and you keep them consistent.

Where it actually matters

Every gate, and every Hamiltonian-simulation claim A gate on hardware is a Hamiltonian switched on for a calibrated time, so the physical model of any gate is this topic with a particular B(t). The same equation is what a quantum computer is asked to solve in the chemistry and materials claims of topic 17, where H is a molecule rather than a field, and what phase estimation (topic 12) reads out. Two failures that look like physics and are not: a factor of 2π between a lab’s numbers and the code, and a half (the ½ in H = ½B·σ) dropped between a Rabi frequency and a field. Both give a clean-looking wrong answer, which is why the examples here print a number you can check by hand.