In many problems, the system under study is not in a well-defined initial state, but at a well-defined temperature.
In such a case, we need either a density operator or an ensemble of wave functions to describe our system.
The most straight-forward expression of a thermal state uses a thermalized density operator
Here, β = 1 / kBT is the inverse of the typical thermal excitation energy (kB is Boltzmann's constant, T the temperature), and H is the system Hamiltonian.
This page is supposed to give you an overview over some of the more common methods of constructing the thermal density operator. It is a less technical and extended version of the tutorial that accompagnied a particular demo for the C++ version of Wavepacket (MorseOscillator/Thermal).
There are basically two different ways to construct the thermal state: We can either attempt to construct the density operator directly, or we can represent the thermal state with an ensemble of wave functions.
If we have the eigenstates of the Hamiltonian, we can easily express the exponential. We find
Hence, the construction goes as follows:
If you happen to perform the calculations in the basis of energy eigenstates, the thermal density operator is represented by a matrix where only the diagonals are given by the exponential terms. Then the direct construction is the trivial way to go. This method is for example used in the Matlab version of Wavepacket, where we routinely use the energy representation for open systems.
If you happen to work in any other basis, you should avoid this construction. Piecing the density operator together like this is cumbersome, and you need a diagonalization of the Hamiltonian to even start, which scales with the cube of the number of basis functions. In this case, you rather want to relax a simple initial guess for a density operator.
It can easily be verified that the thermal density operator without the trace normalization is the solution of the initial-value problem
at time t=β.
Furthermore, note that this equation has the form of a Liouville-von-Neumann equation (LvNE) with two important specialties:
There are efficient solvers for imaginary-time equations based on Chebychev polynomials. If you can set up such an equation and solver with not too much effort, this approach is the way to go.
The C++-version of Wavepacket allows a relatively smooth setup and solution of such a LvNE, so this is the preferred mechanism there.
Density operators are rather unwieldy entities. Given a basis of N functions, a density operator is represented in this basis by an NxN matrix with N2 entries. Propagation is also rather slow, with efforts (depending on the Hamiltonian) in the range between N2 for a diagonal operator and N3 for a general operator in matrix representation. We can conclude that a density operator requires a lot of storage and is slow to propagate.
Contrast this with a wavefunction. It is represented by an N-dimensional vector (N entries), and the propagation effort scales between N and N2. If we could represent the thermal density operator by an ensemble of few wave functions, we could speed up the computations considerably.
So where is the catch? In fact, there are some:
While slightly different in the details, these wavefunction approaches have some common ground. The basic idea is to represent the (unnormalized) thermal density operator in a form like
where the cn are some coefficients, and the ψn form the ensemble of wave functions that represent the density operator. Without loss of generality, we can require the wavefunctions to be normalized, since the normalization can be absorbed in the coefficients cn. All operations on the density operator that we do in a quantum simulation fall into two categories:
Put together, every quantity of the density operator that we may ever be interested can be written as
,
where A is some operator, and U is some time evolution operator from time t0 to time t. (Note that more complex expressions are possible, but do not change the following arguments.)
Now, let us transform this equation a little. We take some orthonormal basis for the trace, use the resolution of identity and other bracket rules, and obtain
This suggests a simple scheme for replacing the density operator by a wavefunction ensemble
One particular expectation value that we need to calculate is the normalization factor as
.
Now we only need to find a suitable wavefunction representation of the density operator.
One trivial representation of the Hamiltonian is given by the energy eigenstates as already written some sections before,
The coefficients are the exponentials, and the wave functions are the energy eigenstates. Hence, all you have to do is get the eigenstates, usually from a diagonalization of the Hamiltonian, and follow the procedure outlined in the previous section. The C++ wavepacket demo MolVibration/OH/Thermal demonstrates this feature.
A few pros and cons with regard to this representation:
Altogether we can note that the use of eigenstates of the Hamiltonian is a conservative, but systematic way of creating the wavefunction ensemble. It gives us hard guarantees on the convergence, but these are only useful for sufficiently low temperatures and sufficiently small systems.
For higher temperatures or larger systems we need a less systematic "shotgun approach" that samples the relevant state space mor aggressively. The most prominent is the random wavefunctions approach discussed next.
The basic idea of this approach is to sample the state space randomly, but with a strong bias towards "allowed" states whose energy is on the order of the thermal excitation energy 1/β or less.
This approach has been used for example with Kosloff's optimized spin bath approach (see here or with MCTDH (see here and here. If you plan to apply random thermal wavefunctions to MCTDH, see also our own work for caveats.
For completeness, let us start with the notation to be used for the random wavefunctions. We denote a random number, wavefunction, vector etc. by a tilde over the symbol, such as . Note that a random number is not a number, it is in essence a probability distribution. To get a real number out of a random number, we need to form an expectation value, denoted as
.
For example, we could have a random number that is uniformly distributed over the interval
[0,1]
. Then the expectation value would be 0.5, the expectation value
would be 0.25 and so on. For all but the simplest cases, calculating the exact expectation value is a major effort, and we instead approximate it by sampling: We draw n numbers randomly using the given probability distribution, and approximate the expectation value with the mean of all these numbers.
For more information, see a good book or at least the Wikipedia article on probability theory; the notation described here will be applied in the following.
The theory is largely identical to the general wavefunction ensemble approach, but with some expectation values instead of a summation over multiple states. We start by representing the unit operator with a random wavefunction
.
We come to the construction of such a random wavefunction in a second. With the help of this representation, we can represent the unnormalized thermal density as
.
Now we can use that the calculation of the expectation value and the calculation of scalar products commutes, and repeat the derivation for the general wavefunction ensemble approach to finally obtain
.
So the general procedure as a slight deviation is then
See the corresponding C++ wavepacket demo for a simple working example.
So the question is how to construct a random wavefunction with the property
For this, we first pick an arbitrary orthonormal basis, and expand our random wave function in this basis. We end up with a set of random coefficients whose distribution we need to determine. We get:
,
from which follows the requirement for the coefficients as
.
By far the simplest way to setup such coefficients is to choose for each coefficient one of the values +1 or -1 randomly.
To assemble the wavefunction from these coefficients, note that whenever you do numerical simulations (well, within Wavepacket at least), you always represent a wavefunction as a vector in an orthogonal basis. Thus, just combine your random coefficients into a Matlab vector (Matlab version) or CTensor (C++ version), and you are done. For the Matlab version, you only need to observe that the DVR representation is not normalized, so you should ideally set up the initial wave function in the FBR and transform back.
So what are the good and bad things about random thermal wavefunctions?