Schrödinger time evolution
The Schrödinger equation as one of the basic postulates of quantum mechanics describes the dynamics of a quantum state in a closed quantum system. In Dirac notation the Schrödinger equation and its adjoint equation read
\[i\hbar\frac{\mathrm{d}}{\mathrm{d} t} |\Psi(t)\rangle = H |\Psi(t)\rangle\]
\[- i\hbar\frac{\mathrm{d}}{\mathrm{d} t} \langle \Psi(t)| = \langle\Psi(t)| H\]
Both versions are implemented and are chosen automatically depending on the type of the provided initial state (Ket
or Bra
):
timeevolution.schroedinger(tspan, psi0, H)
The Schrödinger equation solver requires the arguments tspan
, which is a vector containing the times, the initial state psi0
as Ket
or Bra
and the Hamiltonian H
.
Additionally, one can pass an output function fout
as keyword argument. This can be convenient if one directly wants to compute a value that depends on the states, e.g. an expectation value, instead of the states themselves. Consider, for example, a time evolution according to a Schrödinger equation where for all times we want to compute the expectation value of the operator A
. We can do this by:
tout, psi_t = timeevolution.schroedinger(tspan, psi0, H)
exp_val = expect(A, psi_t)
or equivalently:
exp(t, psi) = expect(A, psi)
tout, exp_val = timeevolution.schroedinger(tspan, psi0, H; fout=exp)
Although the method using fout
might seem more complicated, it can be very useful for large systems to save memory since instead of all the states we only store one complex number per time step. Note, that fout
must always be defined with the arguments (t, psi)
. If fout
is given, all variables are assigned within fout
and the call to timeevolution.schroedinger
returns nothing
.
We can also calculate the time evolution for a Hamiltonian that is time-dependent. In that case, we need to use the function timeevolution.schroedinger_dynamic(tspan, psi0, f::Function)
. As you can see, this function requires the same arguments as timeevolution.schroedinger
, but a function f
instead of a Hamiltonian.