1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2019 QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 #include <stdexcept>
14 
15 #include "config/stdlib/math.hpp"
16 #include "SmoothFunctions.hpp"
17 
18 namespace qmcplusplus
19 {
20 
21 template<typename T>
smoothing(smoothing_functions func_id,T x,T & dx,T & d2x)22 T smoothing(smoothing_functions func_id, T x, T& dx, T& d2x)
23 {
24   if (x < 0)
25   {
26     dx = d2x = T(0);
27     return T(1);
28   }
29   else if (x >= 1)
30   {
31     dx = d2x = T(0);
32     return T(0);
33   }
34   else if (func_id == smoothing_functions::LEKS2018)
35   {
36     /// 1/2 - 1/2 tanh(alpha * (x - 1/2))
37     const T cone(1), chalf(0.5), alpha(2);
38     const T tanh_x    = std::tanh((x - chalf) * alpha);
39     const T dtanhx_dx = cone - tanh_x * tanh_x;
40 
41     dx  = -chalf * alpha * dtanhx_dx;
42     d2x = alpha * alpha * tanh_x * dtanhx_dx;
43     return chalf * (cone - tanh_x);
44   }
45   else if (func_id == smoothing_functions::COSCOS)
46   {
47     /// (1+cos(PI*(1-cos(PI*x))/2))/2
48     const T chalf(0.5), cone(1), pihalf(M_PI * chalf), pipihalf(M_PI * M_PI * chalf);
49     T s, c, scos, ccos;
50     qmcplusplus::sincos(T(M_PI) * x, &s, &c);
51     qmcplusplus::sincos(pihalf * (cone - c), &scos, &ccos);
52 
53     dx  = -chalf * pipihalf * scos * s;
54     d2x = -pihalf * pipihalf * (ccos * pihalf * s * s + scos * c);
55     return chalf * (cone + ccos);
56   }
57   else if (func_id == smoothing_functions::LINEAR)
58   {
59     /// 1-x
60     dx  = T(-1);
61     d2x = T(0);
62     return T(1) - x;
63   }
64   else
65     throw std::runtime_error("Unknown smooth function!");
66 }
67 
68 template float smoothing(smoothing_functions func_id, float x, float& dx, float& d2x);
69 template double smoothing(smoothing_functions func_id, double x, double& dx, double& d2x);
70 
71 } // namespace qmcplusplus
72 
73 
74