35#ifndef MADNESS_MRA_GFIT_H__INCLUDED
36#define MADNESS_MRA_GFIT_H__INCLUDED
44#include "../constants.h"
45#include "../tensor/basetensor.h"
46#include "../tensor/slice.h"
47#include "../tensor/tensor.h"
48#include "../tensor/tensor_lapack.h"
49#include "../world/madness_exception.h"
50#include "../world/print.h"
58template<
typename T, std::
size_t NDIM>
70 MADNESS_CHECK_THROW(hi>0,
"hi must be positive in gfit: U need to set it manually in operator.h");
85 print(
"Operator type not implemented: ",
type);
119 static GFit BSHFit(
double mu,
double lo,
double hi,
double eps,
bool prnt=
false) {
121 bool fix_interval=
false;
142 static GFit SlaterFit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
147 auto exact = [&gamma](
const double r) ->
double {
return exp(-gamma * r); };
162 static GFit GaussFit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
167 fit.exponents_=gamma;
170 auto exact = [&gamma](
const double r) ->
double {
return exp(-gamma * r*r); };
185 static GFit F12Fit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
188 fit.coeffs_*=(0.5/gamma);
191 auto exact=[&gamma](
const double r) ->
double {
return 0.5/gamma*(1.0-exp(-gamma*r));};
206 static GFit F12sqFit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
209 fit.coeffs_*=(0.25/(gamma*gamma));
212 auto exact=[&gamma](
const double r) ->
double {
return std::pow(0.5/gamma*(1.0-exp(-gamma*r)),2.0);};
229 static GFit FGFit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
230 GFit bshfit,coulombfit;
234 bool fix_interval=
true;
240 auto diffcoefficients=(coulombfit.
coeffs() - bshfit.
coeffs());
248 auto exact=[&gamma](
const double r) ->
double {
return 0.5/gamma*(1.0-exp(-gamma*r))/r;};
263 static GFit F2GFit(
double gamma,
double lo,
double hi,
double eps,
bool prnt=
false) {
264 GFit bshfit,coulombfit,bsh2fit;
268 bool fix_interval=
true;
284 double fourmu2=4.0*gamma*gamma;
285 f2gfit.
coeffs_=fourpi/fourmu2*coefficients;
290 auto exact=[&gamma](
const double r) ->
double {
291 return 0.25/(gamma*gamma)*(1.0-2.0*exp(-gamma*r)+exp(-2.0*gamma*r))/r;
320 const long first_prunable = 1) {
321 double mid =
lo + (hi-
lo)*0.5;
322 long npt=coeff.
size();
324 for (i=npt-1; i>=std::max(first_prunable, 1L); --i) {
325 double cnew = coeff[i]*exp(-(expnt[i]-expnt[i-1])*mid*mid);
326 double errlo = coeff[i]*exp(-expnt[i]*
lo*
lo) -
327 cnew*exp(-expnt[i-1]*
lo*
lo);
328 double errhi = coeff[i]*exp(-expnt[i]*hi*hi) -
329 cnew*exp(-expnt[i-1]*hi*hi);
332 coeff[i-1] = coeff[i-1] + cnew;
334 coeff = coeff(
Slice(0,npt-1));
335 expnt = expnt(
Slice(0,npt-1));
357 const std::array<LatticeRange, NDIM>& lattice_ranges,
359 double lo,
double hi_fin,
double eps) {
360 const bool infinite_any = std::any_of(lattice_ranges.begin(), lattice_ranges.end(), [](
const auto&
b) { return b.infinite(); });
361 const bool infinite_all = std::all_of(lattice_ranges.begin(), lattice_ranges.end(), [](
const auto&
b) { return b.infinite(); });
362 if (!infinite_any)
return;
366 double max_infinite_width = 0;
367 for (std::size_t
d = 0;
d !=
NDIM; ++
d)
368 if (lattice_ranges[
d].infinite()) max_infinite_width = std::max(max_infinite_width, cell_width(
long(
d)));
369 const double tcut = 0.25 / (max_infinite_width * max_infinite_width);
373 for (
long i = 0; i <
e.dim(0); ++i) {
374 if (
e(i) < tcut) { icut = i;
break; }
376 if (icut < 0)
return;
395 template<
typename funcT>
405 template<
typename opT>
408 std::cout <<
"weights and roots" << std::endl;
409 for (
int i=0; i<
coeffs_.size(); ++i)
413 std::cout <<
" x value abserr relerr" << std::endl;
414 std::cout <<
" ------------ ------- -------- -------- " << std::endl;
415 double step = exp(log(hi/
lo)/(npt+1));
416 for (
int i=0; i<=npt; ++i) {
417 double r =
lo*(
pow(step,i+0.5));
421 for (
int j=0; j<
coeffs_.dim(0); ++j)
447 if (
mu < 0.0)
throw "cannot handle negative mu in bsh_fit";
451 if ((
mu > 0) and (not fix_interval)) {
462 if (eps >= 1
e-2) TT = 5;
463 else if (eps >= 1
e-4) TT = 10;
464 else if (eps >= 1
e-6) TT = 14;
465 else if (eps >= 1
e-8) TT = 18;
466 else if (eps >= 1
e-10) TT = 22;
467 else if (eps >= 1
e-12) TT = 26;
470 if ((
mu > 0) and (not fix_interval)) {
472 slo = -0.5*log(4.0*TT/(
mu*
mu));
475 slo = log(eps/hi) - 1.0;
477 shi = 0.5*log(TT/(
lo*
lo));
478 if (shi <= slo)
throw "bsh_fit: logic error in slo,shi";
481 double h = 1.0/(0.2-.50*log10(eps));
488 h = floor(64.0*
h)/64.0;
493 slo = floor(slo/
h)*
h;
495 long npt = long((shi-slo)/
h+0.5);
502 for (
int i=0; i<npt; ++i) {
503 double s = slo +
h*(npt-i);
506 expnt[i] = exp(2.0*s);
513 expnt[0] = exp(2.0*s);
514 coeff=coeff(
Slice(0,0));
515 expnt=expnt(
Slice(0,0));
516 print(
"only one term in gfit",s,coeff[0],expnt[0]);
529 if ((
mu == 0.0) and (not fix_interval)) {
554 double range = sqrt(-log(1
e-6)/expnt[nmom-1]);
555 if (prnt)
print(
"exponent(nmom-1)",expnt[nmom-1],
"has range", range);
559 for (
int i=nmom; i<npt; ++i) {
566 qg = qg(
Slice(1,nmom));
570 print(
"moments", qg);
573 for (
int j=0; j<nmom; ++j) {
576 if (nmom != 4) qt = qt(
Slice(1,nmom));
577 for (
int i=0; i<nmom; ++i) {
586 print(
"new coeffs", ncoeff);
589 coeff(
Slice(0,nmom-1)) = ncoeff;
608 if (eps >= 1
e-2) TT = 5;
609 else if (eps >= 1
e-4) TT = 10;
610 else if (eps >= 1
e-6) TT = 14;
611 else if (eps >= 1
e-8) TT = 18;
612 else if (eps >= 1
e-10) TT = 22;
613 else if (eps >= 1
e-12) TT = 26;
618 double slo=0.5 * log(eps) - 1.0;
619 double shi=log(TT/(
lo*
lo))*0.5;
622 double h = 1.0/(0.2-.5*log10(eps));
629 h = floor(64.0*
h)/64.0;
633 slo = floor(slo/
h)*
h;
635 long npt = long((shi-slo)/
h+0.5);
639 for (
int i=0; i<npt; ++i) {
640 const double s = slo +
h*(npt-i);
641 coeff[i] =
h*exp(-gamma*gamma*exp(2.0*s) + s);
643 expnt[i] = 0.25*exp(-2.0*s);
647 std::cout <<
"weights and roots for a Slater function with gamma=" << gamma << std::endl;
648 for (
int i=0; i<npt; ++i)
649 std::cout << i <<
" " << coeff[i] <<
" " << expnt[i] << std::endl;
654 std::cout <<
" x value abserr relerr" << std::endl;
655 std::cout <<
" ------------ ------- -------- -------- " << std::endl;
656 double step = exp(log(hi/
lo)/(npt+1));
657 for (
int i=0; i<=npt; ++i) {
658 double r =
lo*(
pow(step,i+0.5));
659 double exact = exp(-gamma*r);
661 for (
int j=0; j<coeff.dim(0); ++j)
662 test += coeff[j]*exp(-r*r*expnt[j]);
676 static void f12_fit(
double gamma,
double lo,
double hi,
double eps,
682 pcoeff(
Slice(1,-1,1))=-coeff(
_);
684 pexpnt(
Slice(1,-1,1))=expnt(
_);
695 static void f12sq_fit(
double gamma,
double lo,
double hi,
double eps,
699 slater_fit(2.0*gamma,
lo, hi, eps, coeff2, expnt2, prnt);
705 auto coeff=coeff2-2.0*coeff1;
707 pcoeff(
Slice(1,-1,1))=coeff(
_);
709 pexpnt(
Slice(1,-1,1))=expnt1(
_);
733 slo = -0.5*log(4.0*100.0/(
mu*
mu));
734 slo = -0.5*log(4.0*(slo*ndim - 2.0*slo + 100.0)/(
mu*
mu));
737 slo = log(eps/hi) - 1.0;
739 shi = 0.5*log(100.0/(
lo*
lo));
742 double h = 1.0/(0.2-.50*log10(eps));
749 h = floor(64.0*
h)/64.0;
754 slo = floor(slo/
h)*
h;
756 long npt = long((shi-slo)/
h+0.5);
759 std::cout <<
"bsh: mu " <<
mu <<
" lo " <<
lo <<
" hi " << hi
760 <<
" eps " << eps <<
" slo " << slo <<
" shi " << shi
761 <<
" npt " << npt <<
" h " <<
h << std::endl;
767 for (
int i=0; i<npt; ++i) {
768 double s = slo +
h*(npt-i);
770 double p = exp(2.0*s);
772 if (
c*exp(-
p*
lo*
lo) > eps) {
783 expnt[0] = exp(2.0*s);
784 coeff=coeff(
Slice(0,0));
785 expnt=expnt(
Slice(0,0));
786 print(
"only one term in gfit",s,coeff[0],expnt[0]);
798 double mid =
lo + (hi-
lo)*0.5;
800 for (i=npt-1; i>0; --i) {
801 double cnew = coeff[i]*exp(-(expnt[i]-expnt[i-1])*mid*mid);
802 double errlo = coeff[i]*exp(-expnt[i]*
lo*
lo) -
803 cnew*exp(-expnt[i-1]*
lo*
lo);
804 double errhi = coeff[i]*exp(-expnt[i]*hi*hi) -
805 cnew*exp(-expnt[i-1]*hi*hi);
808 coeff[i-1] = coeff[i-1] + cnew;
813 coeff = coeff(
Slice(0,npt-1));
814 expnt = expnt(
Slice(0,npt-1));
818 for (
int i=0; i<npt; ++i)
819 std::cout << i <<
" " << coeff[i] <<
" " << expnt[i] << std::endl;
822 std::cout <<
" x value" << std::endl;
823 std::cout <<
" ------------ ---------------------" << std::endl;
824 double step = exp(log(hi/
lo)/(npt+1));
825 for (
int i=0; i<=npt; ++i) {
826 double r =
lo*(
pow(step,i+0.5));
828 for (
int j=0; j<coeff.dim(0); ++j)
829 test += coeff[j]*exp(-r*r*expnt[j]);
830 printf(
" %.6e %20.10e\n",r,
test);
863 * exp(-
mu *
R) / 0.4e1;
864 q[2] = -(-0.2e1 * exp(
mu *
R) + 0.2e1 + 0.2e1 *
mu *
R +
R*
R *
866 q[3] = -(-0.6e1 * exp(
mu *
R) + 0.6e1 + 0.6e1 *
mu *
R + 0.3e1 *
R*
R
double q(double t)
Definition DKops.h:18
long size() const
Returns the number of elements in the tensor.
Definition basetensor.h:138
Tensor< T > coeffs() const
return the coefficients of the fit
Definition gfit.h:309
void print_accuracy(opT op, const double lo, const double hi) const
print coefficients and exponents, and values and errors
Definition gfit.h:406
Tensor< T > exponents() const
return the exponents of the fit
Definition gfit.h:312
static void prune_small_coefficients(const double eps, const double lo, const double hi, Tensor< double > &coeff, Tensor< double > &expnt, const long first_prunable=1)
Definition gfit.h:318
static GFit GaussFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a (trivial) fit for a single Gauss function
Definition gfit.h:162
GFit()=default
default ctor does nothing
static GFit F2GFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the F2G function
Definition gfit.h:263
GFit(const funcT &f)
ctor taking an isotropic function
Definition gfit.h:396
static void f12_fit(double gamma, double lo, double hi, double eps, Tensor< double > &pcoeff, Tensor< double > &pexpnt, bool prnt)
fit a correlation factor (1- exp(-mu r))
Definition gfit.h:676
static void slater_fit(double gamma, double lo, double hi, double eps, Tensor< double > &pcoeff, Tensor< double > &pexpnt, bool prnt)
fit a Slater function using a sum of Gaussians
Definition gfit.h:602
static void bsh_spherical_moments(double mu, double R, Tensor< double > &q)
Definition gfit.h:853
static GFit BSHFit(double mu, double lo, double hi, double eps, bool prnt=false)
return a fit for the bound-state Helmholtz function
Definition gfit.h:119
static GFit GeneralFit()
return a fit for a general isotropic function
Definition gfit.h:303
Tensor< T > exponents_
the exponents of the expansion f(x) = \sum_m coeffs[m] exp(-exponents[m] * x^2)
Definition gfit.h:433
static GFit FGFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the FG function
Definition gfit.h:229
static void f12sq_fit(double gamma, double lo, double hi, double eps, Tensor< double > &pcoeff, Tensor< double > &pexpnt, bool prnt)
fit a correlation factor f12^2 = (1- exp(-mu r))^2 = 1 - 2 exp(-mu r) + exp(-2 mu r)
Definition gfit.h:695
static GFit F12sqFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the F12^2 correlation factor
Definition gfit.h:206
static void bsh_fit(double mu, double lo, double hi, double eps, Tensor< double > &pcoeff, Tensor< double > &pexpnt, bool prnt, bool fix_interval)
fit the function exp(-mu r)/r
Definition gfit.h:444
static void gaussian_spherical_moments(double alpha, double R, Tensor< double > &q)
Definition gfit.h:839
static GFit F12Fit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the F12 correlation factor
Definition gfit.h:185
GFit & operator=(const GFit &other)
assignment operator
Definition gfit.h:95
static GFit SlaterFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the Slater function
Definition gfit.h:142
static GFit CoulombFit(double lo, double hi, double eps, bool prnt=false)
return a fit for the Coulomb function
Definition gfit.h:104
static void truncate_mixed_expansion(Tensor< double > &c, Tensor< double > &e, const std::array< LatticeRange, NDIM > &lattice_ranges, const Tensor< double > &cell_width, double lo, double hi_fin, double eps)
Truncate the fit of a kernel that is lattice-summed along some axes.
Definition gfit.h:356
static void bsh_fit_ndim(int ndim, double mu, double lo, double hi, double eps, Tensor< double > &pcoeff, Tensor< double > &pexpnt, bool prnt)
Definition gfit.h:717
GFit(const GFit &other)=default
copy constructor
GFit(OperatorInfo info)
Definition gfit.h:66
Tensor< T > coeffs_
the coefficients of the expansion f(x) = \sum_m coeffs[m] exp(-exponents[m] * x^2)
Definition gfit.h:430
A slice defines a sub-range or patch of a dimension.
Definition slice.h:103
A tensor is a multidimensional array.
Definition tensor.h:318
static const double R
Definition csqrt.cc:46
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
static double lo
Definition dirac-hatom.cc:23
static bool debug
Definition dirac-hatom.cc:16
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
static double pow(const double *a, const double *b)
Definition lda.h:74
#define MADNESS_CHECK(condition)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:182
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_CHECK_THROW(condition, msg)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:207
constexpr double pi
Mathematical constant .
Definition constants.h:48
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
static const Slice _(0,-1, 1)
OpType
operator types
Definition operatorinfo.h:11
@ OT_FG12
1-exp(-r)
Definition operatorinfo.h:18
@ OT_SLATER
1/r
Definition operatorinfo.h:15
@ OT_GAUSS
exp(-r)
Definition operatorinfo.h:16
@ OT_BSH
(1-exp(-r))^2/r = 1/r + exp(-2r)/r - 2 exp(-r)/r
Definition operatorinfo.h:21
@ OT_F12
exp(-r2)
Definition operatorinfo.h:17
@ OT_F212
(1-exp(-r))/r
Definition operatorinfo.h:19
@ OT_G12
indicates the identity
Definition operatorinfo.h:14
@ OT_F2G12
(1-exp(-r))^2
Definition operatorinfo.h:20
void gesv(const Tensor< T > &a, const Tensor< T > &b, Tensor< T > &x)
Solve Ax = b for general A using the LAPACK *gesv routines.
Definition lapack.cc:804
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:227
NDIM & f
Definition mra.h:2668
std::string type(const PairType &n)
Definition PNOParameters.h:18
static long abs(long a)
Definition tensor.h:219
const double mu
Definition navstokes_cosines.cc:95
static const double b
Definition nonlinschro.cc:119
static const double d
Definition nonlinschro.cc:121
static const double c
Definition relops.cc:10
Definition operatorinfo.h:58
double hi
Definition operatorinfo.h:67
double thresh
Definition operatorinfo.h:65
bool debug
Definition operatorinfo.h:69
OpType type
introspection
Definition operatorinfo.h:66
double mu
some introspection
Definition operatorinfo.h:63
double lo
Definition operatorinfo.h:64
void e()
Definition test_sig.cc:75
static const double alpha
Definition testcosine.cc:10
double(* exact)(double, double, double)
Definition testfuns.cc:6
std::vector< double > fit(size_t m, size_t n, const std::vector< double > N, const std::vector< double > &f)
Definition testfuns.cc:36
constexpr std::size_t NDIM
Definition testgconv.cc:54
double h(const coord_1d &r)
Definition testgconv.cc:175
void test()
Definition y.cc:696