82 lines
2.8 KiB
C++
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
|