35 #ifndef MADNESS_MRA_GFIT_H__INCLUDED
36 #define MADNESS_MRA_GFIT_H__INCLUDED
46 template<
typename T, std::
size_t NDIM>
70 static GFit BSHFit(
double mu,
double lo,
double hi,
double eps,
bool prnt=
false) {
72 if (
NDIM==3) bsh_fit(mu,lo,hi,eps,fit.coeffs_,fit.exponents_,prnt);
73 else bsh_fit_ndim(
NDIM,mu,lo,hi,eps,fit.coeffs_,fit.exponents_,prnt);
88 slater_fit(gamma,lo,hi,eps,fit.coeffs_,fit.exponents_,prnt);
102 Tensor<T>
coeffs()
const {
return coeffs_;}
108 double L,
bool discardG0)
const {
109 double tcut = 0.25/L/L;
113 for (
int i=0; i<e.dim(0); ++i) {
123 for (
int i=0; i<e.dim(0); ++i) {
130 for (
int i=icut+1; i<e.dim(0); ++i) {
134 e = e(
Slice(0,icut));
145 template<
typename funcT>
146 GFit(
const funcT&
f) {
154 Tensor<T> exponents_;
165 static void bsh_fit(
double mu,
double lo,
double hi,
double eps,
166 Tensor<double>& pcoeff, Tensor<double>& pexpnt,
bool prnt) {
168 if (mu < 0.0)
throw "cannot handle negative mu in bsh_fit";
180 if (eps >= 1e-2) TT = 5;
181 else if (eps >= 1e-4) TT = 10;
182 else if (eps >= 1e-6) TT = 14;
183 else if (eps >= 1e-8) TT = 18;
184 else if (eps >= 1e-10) TT = 22;
185 else if (eps >= 1e-12) TT = 26;
189 slo = -0.5*
log(4.0*TT/(mu*mu));
192 slo =
log(eps/hi) - 1.0;
194 shi = 0.5*
log(TT/(lo*lo));
195 if (shi <= slo)
throw "bsh_fit: logic error in slo,shi";
198 double h = 1.0/(0.2-.50*
log10(eps));
205 h =
floor(64.0*h)/64.0;
210 slo =
floor(slo/h)*h;
212 long npt = long((shi-slo)/h+0.5);
217 Tensor<double> coeff(npt), expnt(npt);
219 for (
int i=0; i<npt; ++i) {
220 double s = slo + h*(npt-i);
223 expnt[i] =
exp(2.0*s);
230 expnt[0] =
exp(2.0*s);
231 coeff=coeff(Slice(0,0));
232 expnt=expnt(Slice(0,0));
233 print(
"only one term in gfit",s,coeff[0],expnt[0]);
247 double mid = lo + (hi-lo)*0.5;
249 for (i=npt-1; i>0; --i) {
250 double cnew = coeff[i]*
exp(-(expnt[i]-expnt[i-1])*mid*mid);
251 double errlo = coeff[i]*
exp(-expnt[i]*lo*lo) -
252 cnew*
exp(-expnt[i-1]*lo*lo);
253 double errhi = coeff[i]*
exp(-expnt[i]*hi*hi) -
254 cnew*
exp(-expnt[i-1]*hi*hi);
255 if (
std::max(std::abs(errlo),std::abs(errhi)) > 0.03*eps)
break;
257 coeff[i-1] = coeff[i-1] + cnew;
259 coeff = coeff(Slice(0,npt-1));
260 expnt = expnt(Slice(0,npt-1));
282 Tensor<double> q(4), qg(4);
283 double range =
sqrt(-
log(1e-6)/expnt[nmom-1]);
284 if (prnt)
print(
"exponent(nmom-1)",expnt[nmom-1],
"has range", range);
286 bsh_spherical_moments(mu, range, q);
287 Tensor<double> M(nmom,nmom);
288 for (
int i=nmom; i<npt; ++i) {
289 Tensor<double> qt(4);
290 gaussian_spherical_moments(expnt[i], range, qt);
294 q = q(Slice(1,nmom));
295 qg = qg(Slice(1,nmom));
299 print(
"moments", qg);
302 for (
int j=0; j<nmom; ++j) {
303 Tensor<double> qt(4);
304 gaussian_spherical_moments(expnt[j], range, qt);
305 if (nmom != 4) qt = qt(Slice(1,nmom));
306 for (
int i=0; i<nmom; ++i) {
310 Tensor<double> ncoeff;
314 print(
"old coeffs", coeff(Slice(0,nmom-1)));
315 print(
"new coeffs", ncoeff);
318 coeff(Slice(0,nmom-1)) = ncoeff;
322 for (
int i=0; i<npt; ++i)
323 std::cout << i <<
" " << coeff[i] <<
" " << expnt[i] << std::endl;
328 std::cout <<
" x value abserr relerr" << std::endl;
329 std::cout <<
" ------------ ------- -------- -------- " << std::endl;
330 double step =
exp(
log(hi/lo)/(npt+1));
331 for (
int i=0; i<=npt; ++i) {
332 double r = lo*(
pow(step,i+0.5));
335 for (
int j=0; j<coeff.dim(0); ++j)
336 test += coeff[j]*
exp(-r*r*expnt[j]);
338 if (exact) err = (exact-
test)/exact;
339 printf(
" %.6e %8.1e %8.1e %8.1e\n",r, exact, exact-test, err);
352 static void slater_fit(
double gamma,
double lo,
double hi,
double eps,
353 Tensor<double>& pcoeff, Tensor<double>& pexpnt,
bool prnt) {
357 if (eps >= 1e-2) TT = 5;
358 else if (eps >= 1e-4) TT = 10;
359 else if (eps >= 1e-6) TT = 14;
360 else if (eps >= 1e-8) TT = 18;
361 else if (eps >= 1e-10) TT = 22;
362 else if (eps >= 1e-12) TT = 26;
366 double slo=0.5 *
log(eps) - 1.0;
367 double shi=
log(TT/(lo*lo))*0.5;
370 double h = 1.0/(0.2-.5*
log10(eps));
377 h =
floor(64.0*h)/64.0;
381 slo =
floor(slo/h)*h;
383 long npt = long((shi-slo)/h+0.5);
385 Tensor<double> coeff(npt), expnt(npt);
387 for (
int i=0; i<npt; ++i) {
388 const double s = slo + h*(npt-i);
389 coeff[i] = h*
exp(-gamma*gamma*
exp(2.0*s) + s);
391 expnt[i] = 0.25*
exp(-2.0*s);
403 double mid = lo + (hi-lo)*0.5;
405 for (i=npt-1; i>0; --i) {
406 double cnew = coeff[i]*
exp(-(expnt[i]-expnt[i-1])*mid*mid);
407 double errlo = coeff[i]*
exp(-expnt[i]*lo*lo) -
408 cnew*
exp(-expnt[i-1]*lo*lo);
409 double errhi = coeff[i]*
exp(-expnt[i]*hi*hi) -
410 cnew*
exp(-expnt[i-1]*hi*hi);
411 if (
std::max(std::abs(errlo),std::abs(errhi)) > 0.03*eps)
break;
413 coeff[i-1] = coeff[i-1] + cnew;
415 coeff = coeff(Slice(0,npt-1));
416 expnt = expnt(Slice(0,npt-1));
421 std::cout <<
"weights and roots for a Slater function with gamma=" << gamma << std::endl;
422 for (
int i=0; i<npt; ++i)
423 std::cout << i <<
" " << coeff[i] <<
" " << expnt[i] << std::endl;
428 std::cout <<
" x value abserr relerr" << std::endl;
429 std::cout <<
" ------------ ------- -------- -------- " << std::endl;
430 double step =
exp(
log(hi/lo)/(npt+1));
431 for (
int i=0; i<=npt; ++i) {
432 double r = lo*(
pow(step,i+0.5));
433 double exact =
exp(-gamma*r);
435 for (
int j=0; j<coeff.dim(0); ++j)
436 test += coeff[j]*
exp(-r*r*expnt[j]);
438 if (exact) err = (exact-
test)/exact;
439 printf(
" %.6e %8.1e %8.1e %8.1e\n",r, exact, exact-test, err);
446 void static bsh_fit_ndim(
int ndim,
double mu,
double lo,
double hi,
double eps,
447 Tensor<double>& pcoeff, Tensor<double>& pexpnt,
bool prnt) {
462 slo = -0.5*
log(4.0*100.0/(mu*mu));
463 slo = -0.5*
log(4.0*(slo*ndim - 2.0*slo + 100.0)/(mu*mu));
466 slo =
log(eps/hi) - 1.0;
468 shi = 0.5*
log(100.0/(lo*lo));
471 double h = 1.0/(0.2-.50*
log10(eps));
478 h =
floor(64.0*h)/64.0;
483 slo =
floor(slo/h)*h;
485 long npt = long((shi-slo)/h+0.5);
488 std::cout <<
"bsh: mu " << mu <<
" lo " << lo <<
" hi " << hi
489 <<
" eps " << eps <<
" slo " << slo <<
" shi " << shi
490 <<
" npt " << npt <<
" h " << h << std::endl;
494 Tensor<double> coeff(npt), expnt(npt);
496 for (
int i=0; i<npt; ++i) {
497 double s = slo + h*(npt-i);
499 double p =
exp(2.0*s);
501 if (c*
exp(-p*lo*lo) > eps) {
512 expnt[0] =
exp(2.0*s);
513 coeff=coeff(Slice(0,0));
514 expnt=expnt(Slice(0,0));
515 print(
"only one term in gfit",s,coeff[0],expnt[0]);
527 double mid = lo + (hi-lo)*0.5;
529 for (i=npt-1; i>0; --i) {
530 double cnew = coeff[i]*
exp(-(expnt[i]-expnt[i-1])*mid*mid);
531 double errlo = coeff[i]*
exp(-expnt[i]*lo*lo) -
532 cnew*
exp(-expnt[i-1]*lo*lo);
533 double errhi = coeff[i]*
exp(-expnt[i]*hi*hi) -
534 cnew*
exp(-expnt[i-1]*hi*hi);
535 if (
std::max(std::abs(errlo),std::abs(errhi)) > 0.03*eps)
break;
537 coeff[i-1] = coeff[i-1] + cnew;
542 coeff = coeff(Slice(0,npt-1));
543 expnt = expnt(Slice(0,npt-1));
547 for (
int i=0; i<npt; ++i)
548 std::cout << i <<
" " << coeff[i] <<
" " << expnt[i] << std::endl;
551 std::cout <<
" x value" << std::endl;
552 std::cout <<
" ------------ ---------------------" << std::endl;
553 double step =
exp(
log(hi/lo)/(npt+1));
554 for (
int i=0; i<=npt; ++i) {
555 double r = lo*(
pow(step,i+0.5));
557 for (
int j=0; j<coeff.dim(0); ++j)
558 test += coeff[j]*
exp(-r*r*expnt[j]);
559 printf(
" %.6e %20.10e\n",r, test);
568 static void gaussian_spherical_moments(
double alpha,
double R, Tensor<double>& q) {
569 q[0] = -(-0.1e1 +
exp(-alpha * R*R)) / alpha / 0.2
e1;
571 *
erf(R *
sqrt(alpha)) * alpha *
exp(alpha * R*R))
572 *
pow(alpha, -0.5
e1 / 0.2
e1) *
exp(-alpha * R*R) / 0.4e1;
573 q[2] = -(-0.1e1 +
exp(-alpha * R*R) +
exp(-alpha * R*R) * alpha * R*R)
574 *
pow(alpha, -0.2
e1) / 0.2e1;
576 *
exp(alpha * R*R) + 0.6e1 * R *
pow(alpha, 0.5
e1 / 0.2
e1)
578 *
pow(alpha, -0.9
e1 / 0.2
e1) *
exp(-alpha * R*R) / 0.8e1;
582 static void bsh_spherical_moments(
double mu,
double R, Tensor<double>& q) {
592 *
exp(-mu * R) / 0.4e1;
593 q[2] = -(-0.2e1 *
exp(mu * R) + 0.2e1 + 0.2e1 * mu * R + R*R *
595 q[3] = -(-0.6e1 *
exp(mu * R) + 0.6e1 + 0.6e1 * mu * R + 0.3e1 * R*R
606 #endif // MADNESS_MRA_GFIT_H__INCLUDED
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:339
const mpreal exp(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2234
const double pi
Mathematical constant pi.
Definition: constants.h:44
const mpreal erf(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2457
const mpreal log(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2213
static GFit SlaterFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the Slater function
Definition: gfit.h:86
FLOAT e1(FLOAT z)
Definition: y1.cc:144
const mpreal pow(const mpreal &a, const unsigned int b, mp_rnd_t rnd_mode=mpreal::default_rnd)
Definition: mpreal.h:2788
const int NDIM
Definition: tdse1.cc:44
Defines common mathematical and physical constants.
NDIM & f
Definition: mra.h:2179
Tensor< T > coeffs() const
return the coefficients of the fit
Definition: gfit.h:102
FLOAT fit(const FLOAT &x, const vector< FLOAT > &p)
Definition: y.cc:326
const mpreal ceil(const mpreal &v)
Definition: mpreal.h:2596
Defines and implements most of Tensor.
Tensor< T > exponents() const
return the exponents of the fit
Definition: gfit.h:105
#define max(a, b)
Definition: lda.h:53
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:70
static GFit GeneralFit()
return a fit for a general isotropic function
Definition: gfit.h:96
const mpreal log10(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2227
void truncate_periodic_expansion(Tensor< double > &c, Tensor< double > &e, double L, bool discardG0) const
Definition: gfit.h:107
Namespace for mathematical applications.
Definition: muParser.cpp:47
tensorT sqrt(const tensorT &s, double tol=1e-8)
Computes matrix square root (not used any more?)
Definition: DFcode/moldft.cc:446
const mpreal gamma(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2429
static GFit CoulombFit(double lo, double hi, double eps, bool prnt=false)
return a fit for the Coulomb function
Definition: gfit.h:55
void test(World &world, bool doloadbal=false)
Definition: dataloadbal.cc:225
void print(const A &a)
Print a single item to std::cout terminating with new line.
Definition: print.h:122
GFit()
default ctor does nothing
Definition: gfit.h:52
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
A slice defines a sub-range or patch of a dimension.
Definition: slice.h:103
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
const double c
Definition: gfit.cc:200
const mpreal floor(const mpreal &v)
Definition: mpreal.h:2604