Fourier Transform Product state

How do I use this algorithm? What does that parameter do?
Post Reply
dorf
Posts: 32
Joined: 16 Feb 2021, 16:34

Fourier Transform Product state

Post by dorf »

Within some approximation a system has the ground state \(|\tilde{\psi}_0 \rangle\) and an excited state \(|\tilde{\psi}_1 \rangle = \hat{O}|\tilde{\psi}_0 \rangle \) that is connected via the operator \(\hat{O}\), which is known.
I now did a DMRG calculation for that system, obtaining the real ground state \(|\psi_0 \rangle\). As a first guess, I want to try to apply this operator to the real ground state (knowing that the operator is not the 'real' operator anymore) and then compare the spectrum in k-space. Performing a calculation on L sites I want to calculate the energy of the Fourier transformed, excited MPS \(|\psi_1 \rangle_k = \sum_{i=0}^{L-1} e^{ikr_i}\hat{O}_i|\psi_0 \rangle\).

What's the most efficient way to compute these energies? I can apply \(\hat{O}\) using mps.apply_local_op(), but the '+' operator is not overloaded for the mps class, so I wonder if there's a method to construct \(|\psi_0 \rangle_k \), or whether I have to calculate the energy for all the different combinations of the summands in \(|\psi_1 \rangle_k \) and \( \langle\psi_1 |_k \).

Concerning the energy calculation of \(|\psi_1 \rangle_k \), I haven't found an 'energy()' method in the mps-class. Should I use the mps.expectation_value() method, and if yes, is there some predefined Energy operator that I can pass as a string (like 'Sx' or 'Sp'), or is there a better way?
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Fourier Transform Product state

Post by Johannes »

The MPS does not know about the Hamiltonian, so it can't have an "energy" per se. Instead, you have a model you ran DMRG with, and you can compute the energy from the MPO of that model as E = model.H_MPO.expectation_value(psi) giving you the value
\(E = \langle \psi | H |\psi \rangle\).
(For a NearestNeighborModel, you can also use E = np.sum(model.bond_energies()).)


From the context, I infer that the \(\hat O_i\) you talk about is an onsite operator.
In that case, I would actually suggest to write \(\hat O_k \equiv \frac{1}{\sqrt{L}} \sum_i e^{ik r_i} \hat{O}_i \) as an MPO and apply it to the state. (Double-check if this is the normalization you want!)
You can try something along these lines:

Code: Select all

from tenpy.networks.terms import TermList
from tenpy.networks.mpo import MPOGraph

def get_op_k(k, op, sites, bc):
    L = len(sites)
    x = np.arange(L)
    Sk_terms = TermList([[(op, i)] for i in range(L)], np.exp(1.j*k*x)/np.sqrt(L))
    return MPOGraph.from_term_list(Sk_terms, sites, bc).build_MPO()

psi0, model = ... # from DMRG

options = {'compression_method': 'SVD', 'trunc_params: {'chi_max': 100}}
for k in np.linspace(0, 2*np.pi, L, False):
    psi_k = psi0.copy()
    O_k = get_op_k(k, 'Sp', psi.sites, psi.bc)  # assuming your local `O` is just `Sp`
    O_k.apply(psi_k, options)
    E_k = model.H_MPO.expectation_value(O_k)
    print(f"k={k:.3f}: E_k={E_k:.8f}")
For the options, see apply.
Post Reply