ABACUS/src/LIEBLIN/ln_Psi_ME.cc

82 lines
2.8 KiB
C++

/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c) J.-S. Caux.
-----------------------------------------------------------
File: ln_Psi_ME.cc
Purpose: Computes the matrix element of \Psi (x = 0)
***********************************************************/
#include "ABACUS.h"
using namespace std;
using namespace ABACUS;
namespace ABACUS {
complex<DP> Fn_V_Psi (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
{
// lstate has one particle less than rstate
complex<DP> result_num = 1.0;
complex<DP> result_den = 1.0;
for (int m = 0; m < lstate.N; ++m)
result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
for (int m = 0; m < rstate.N; ++m)
result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
return(result_num/result_den);
}
complex<DP> ln_Psi_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
{
// Computes the log of the annihilation operator matrix element between lstate and rstate.
if (lstate.N + 1 != rstate.N) ABACUSerror("Wrong particle numbers in left and right states for Psi FF.");
SQMat_DP U_Psi (0.0, lstate.N);
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
Vect_DP Fn_Prod (0.0, lstate.N); // product_{m} (\mu_m - \lambdaoc_j)/product_{m neq j} (\lambdaoc_m - \lambdaoc_j)
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == N))
int p = rstate.N - 1;
for (int a = 0; a < lstate.N; ++a) {
Vplus[a] = Fn_V_Psi (a, lstate, rstate);
Fn_Prod[a] = (lstate.lambdaoc[a] - rstate.lambdaoc[a])/(rstate.lambdaoc[rstate.N - 1] - rstate.lambdaoc[a]);
for (int m = 0; m < lstate.N; ++m)
if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
rKern[a] = rstate.Kernel (a, p);
}
for (int a = 0; a < lstate.N; ++a)
for (int b = 0; b < lstate.N; ++b)
U_Psi[a][b] = (a == b ? 2.0 * imag(Vplus[a]) : 0.0) + Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
complex<DP> ln_det_U_Psi = lndet_LU_dstry(U_Psi);
complex<DP> ln_prod_lambdaocsq_plus_one = 0.0;
for (int a = 0; a < rstate.N - 1; ++a)
for (int b = a; b < rstate.N; ++b)
ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b])
* (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
complex<DP> ln_prod_lambdaoca_min_mub = 0.0;
for (int a = 0; a < rstate.N; ++a)
for (int b = 0; b < lstate.N; ++b)
ln_prod_lambdaoca_min_mub += log(complex<DP>(rstate.lambdaoc[a] - lstate.lambdaoc[b]));
return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub
- 0.5 * (lstate.lnnorm + rstate.lnnorm));
}
} // namespace ABACUS