QMCPACK
ExpFitClass.h
Go to the documentation of this file.
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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #ifndef EXP_FIT_CLASS_H
18 #define EXP_FIT_CLASS_H
19 
20 #include <vector>
21 #include "OhmmsPETE/TinyVector.h"
23 
24 
25 namespace qmcplusplus
26 {
27 template<int M>
29 
30 template<int M>
32 {
33 private:
35  double sign;
36 
37 public:
38  inline void Fit(std::vector<double>& r, std::vector<double>& u);
39  inline void FitCusp(std::vector<double>& r, std::vector<double>& u, double cusp);
40  inline void eval(double r, double& u);
41  inline void eval(double r, double& u, double& du, double& d2u);
42  friend class ComplexExpFitClass<M>;
43 };
44 
45 template<int M>
46 void ExpFitClass<M>::FitCusp(std::vector<double>& r, std::vector<double>& u, double cusp)
47 {
48  int N = r.size();
49  sign = u[0] < 0.0 ? -1.0 : 1.0;
50  if (r.size() != u.size())
51  app_error() << "Different number of rows of basis functions than"
52  << " of data points in LinFit. Exitting.\n";
53  std::vector<TinyVector<double, M - 1>> F(N);
54  std::vector<double> log_u(N);
55  for (int i = 0; i < N; i++)
56  {
57  log_u[i] = std::log(sign * u[i]) - cusp * r[i];
58  double r2jp1 = r[i] * r[i];
59  F[i][0] = 1.0;
60  for (int j = 1; j < M - 1; j++)
61  {
62  F[i][j] = r2jp1;
63  r2jp1 *= r[i];
64  }
65  }
66  // Next, construct alpha matrix
67  Matrix<double> alpha(M - 1, M - 1), alphaInv(M - 1, M - 1);
68  alpha = 0.0;
69  for (int j = 0; j < M - 1; j++)
70  for (int k = 0; k < M - 1; k++)
71  {
72  alpha(k, j) = 0.0;
73  for (int i = 0; i < N; i++)
74  alpha(k, j) += F[i][j] * F[i][k];
75  }
76  // Next, construct beta vector
77  TinyVector<double, M - 1> beta;
78  beta = 0.0;
79  for (int k = 0; k < M - 1; k++)
80  for (int i = 0; i < N; i++)
81  beta[k] += log_u[i] * F[i][k];
82  // Now, invert alpha
83  for (int i = 0; i < M - 1; i++)
84  for (int j = 0; j < M - 1; j++)
85  alphaInv(i, j) = alpha(i, j);
86  double det = invert_matrix(alphaInv);
87  TinyVector<double, M - 1> c;
88  for (int i = 0; i < M - 1; i++)
89  {
90  c[i] = 0.0;
91  for (int j = 0; j < M - 1; j++)
92  c[i] += alphaInv(i, j) * beta[j];
93  }
94  Coefs[0] = c[0];
95  Coefs[1] = cusp;
96  for (int i = 2; i < M; i++)
97  Coefs[i] = c[i - 1];
98  dCoefs = 0.0;
99  d2Coefs = 0.0;
100  for (int i = 0; i < M - 1; i++)
101  dCoefs[i] = (double)(i + 1) * Coefs[i + 1];
102  for (int i = 0; i < M - 2; i++)
103  d2Coefs[i] = (double)(i + 1) * dCoefs[i + 1];
104 }
105 
106 template<int M>
107 void ExpFitClass<M>::Fit(std::vector<double>& r, std::vector<double>& u)
108 {
109  int N = r.size();
110  sign = u[0] < 0.0 ? -1.0 : 1.0;
111  if (r.size() != u.size())
112  app_error() << "Different number of rows of basis functions than"
113  << " of data points in LinFit. Exitting.\n";
114  std::vector<TinyVector<double, M>> F(N);
115  std::vector<double> log_u(N);
116  for (int i = 0; i < N; i++)
117  {
118  log_u[i] = std::log(sign * u[i]);
119  double r2j = 1.0;
120  for (int j = 0; j < M; j++)
121  {
122  F[i][j] = r2j;
123  r2j *= r[i];
124  }
125  }
126  // Next, construct alpha matrix
127  Matrix<double> alpha(M, M), alphaInv(M, M);
128  alpha = 0.0;
129  for (int j = 0; j < M; j++)
130  for (int k = 0; k < M; k++)
131  {
132  alpha(k, j) = 0.0;
133  for (int i = 0; i < N; i++)
134  alpha(k, j) += F[i][j] * F[i][k];
135  }
136  // Next, construct beta vector
138  beta = 0.0;
139  for (int k = 0; k < M; k++)
140  for (int i = 0; i < N; i++)
141  beta[k] += log_u[i] * F[i][k];
142  // Now, invert alpha
143  for (int i = 0; i < M; i++)
144  for (int j = 0; j < M; j++)
145  alphaInv(i, j) = alpha(i, j);
146  double det = invert_matrix(alphaInv);
147  for (int i = 0; i < M; i++)
148  {
149  Coefs[i] = 0.0;
150  for (int j = 0; j < M; j++)
151  Coefs[i] += alphaInv(i, j) * beta[j];
152  }
153  dCoefs = 0.0;
154  d2Coefs = 0.0;
155  for (int i = 0; i < M - 1; i++)
156  dCoefs[i] = (double)(i + 1) * Coefs[i + 1];
157  for (int i = 0; i < M - 2; i++)
158  d2Coefs[i] = (double)(i + 1) * dCoefs[i + 1];
159 }
160 
161 
162 template<int M>
163 void ExpFitClass<M>::eval(double r, double& u)
164 {
165  double r2j = 1.0;
166  double poly = 0.0;
167  for (int j = 0; j < M; j++)
168  {
169  poly += Coefs[j] * r2j;
170  r2j *= r;
171  }
172  u = sign * std::exp(poly);
173 }
174 
175 template<int M>
176 void ExpFitClass<M>::eval(double r, double& u, double& du, double& d2u)
177 {
178  double r2j = 1.0;
179  double P = 0.0, dP = 0.0, d2P = 0.0;
180  for (int j = 0; j < M; j++)
181  {
182  P += Coefs[j] * r2j;
183  dP += dCoefs[j] * r2j;
184  d2P += d2Coefs[j] * r2j;
185  r2j *= r;
186  }
187  u = sign * std::exp(P);
188  du = dP * u;
189  d2u = (d2P + dP * dP) * u;
190 }
191 
192 template<int M>
193 class ComplexExpFitClass
194 {
195 private:
198 
199 public:
200  inline void Fit(std::vector<double>& r, std::vector<std::complex<double>>& u);
201  inline void FitCusp(std::vector<double>& r, std::vector<std::complex<double>>& u, double cusp);
202  inline void eval(double r, std::complex<double>& u);
203  inline void eval(double r, std::complex<double>& u, std::complex<double>& du, std::complex<double>& d2u);
204 };
205 
206 
207 template<int M>
208 void ComplexExpFitClass<M>::FitCusp(std::vector<double>& r, std::vector<std::complex<double>>& u, double cusp)
209 {
210  int N = u.size();
211  ExpFitClass<M> realFit, imagFit;
212  std::vector<double> realVals(N), imagVals(N);
213  for (int i = 0; i < N; i++)
214  {
215  realVals[i] = real(u[i]);
216  imagVals[i] = imag(u[i]);
217  }
218  realFit.FitCusp(r, realVals, cusp);
219  imagFit.FitCusp(r, imagVals, cusp);
220  realSign = realFit.sign;
221  imagSign = imagFit.sign;
222  for (int i = 0; i < M; i++)
223  {
224  Coefs[i] = std::complex<double>(realFit.Coefs[i], imagFit.Coefs[i]);
225  dCoefs[i] = std::complex<double>(realFit.dCoefs[i], imagFit.dCoefs[i]);
226  d2Coefs[i] = std::complex<double>(realFit.d2Coefs[i], imagFit.d2Coefs[i]);
227  }
228 }
229 
230 template<int M>
231 void ComplexExpFitClass<M>::Fit(std::vector<double>& r, std::vector<std::complex<double>>& u)
232 {
233  int N = u.size();
234  ExpFitClass<M> realFit, imagFit;
235  std::vector<double> realVals(N), imagVals(N);
236  for (int i = 0; i < N; i++)
237  {
238  realVals[i] = real(u[i]);
239  imagVals[i] = imag(u[i]);
240  }
241  realFit.Fit(r, realVals);
242  imagFit.Fit(r, imagVals);
243  realSign = realFit.sign;
244  imagSign = imagFit.sign;
245  for (int i = 0; i < M; i++)
246  {
247  Coefs[i] = std::complex<double>(realFit.Coefs[i], imagFit.Coefs[i]);
248  dCoefs[i] = std::complex<double>(realFit.dCoefs[i], imagFit.dCoefs[i]);
249  d2Coefs[i] = std::complex<double>(realFit.d2Coefs[i], imagFit.d2Coefs[i]);
250  }
251 }
252 
253 
254 template<int M>
255 void ComplexExpFitClass<M>::eval(double r, std::complex<double>& u)
256 {
257  double r2j = 1.0;
258  std::complex<double> P = std::complex<double>();
259  for (int j = 0; j < M; j++)
260  {
261  P += Coefs[j] * r2j;
262  r2j *= r;
263  }
264  u = std::complex<double>(realSign * std::exp(P.real()), imagSign * std::exp(P.imag()));
265 }
266 
267 template<int M>
268 void ComplexExpFitClass<M>::eval(double r, std::complex<double>& u, std::complex<double>& du, std::complex<double>& d2u)
269 {
270  double r2j = 1.0;
271  std::complex<double> P, dP, d2P;
272  P = dP = d2P = std::complex<double>();
273  for (int j = 0; j < M; j++)
274  {
275  P += Coefs[j] * r2j;
276  dP += dCoefs[j] * r2j;
277  d2P += d2Coefs[j] * r2j;
278  r2j *= r;
279  }
280  u = std::complex<double>(realSign * std::exp(P.real()), imagSign * std::exp(P.imag()));
281  du = std::complex<double>(dP.real() * u.real(), dP.imag() * u.imag());
282  d2u = std::complex<double>((d2P.real() + dP.real() * dP.real()) * u.real(),
283  (d2P.imag() + dP.imag() * dP.imag()) * u.imag());
284  //u.real() = realSign * std::exp (P.real());
285  //du.real() = dP.real() * u.real();
286  //d2u.real() = (d2P.real() + dP.real()*dP.real())*u.real();
287  //u.imag() = imagSign * std::exp (P.imag());
288  //du.imag() = dP.imag() * u.imag();
289  //d2u.imag() = (d2P.imag() + dP.imag()*dP.imag())*u.imag();
290 }
291 
292 } // namespace qmcplusplus
293 
294 #endif
void eval(double r, std::complex< double > &u)
Definition: ExpFitClass.h:255
MatrixA::value_type invert_matrix(MatrixA &M, bool getdet=true)
invert a matrix
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Definition: TensorOps.h:838
TinyVector< double, M > dCoefs
Definition: ExpFitClass.h:34
std::ostream & app_error()
Definition: OutputManager.h:67
TinyVector< double, M > Coefs
Definition: ExpFitClass.h:34
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
TinyVector< std::complex< double >, M > d2Coefs
Definition: ExpFitClass.h:196
TinyVector< std::complex< double >, M > Coefs
Definition: ExpFitClass.h:196
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
void FitCusp(std::vector< double > &r, std::vector< double > &u, double cusp)
Definition: ExpFitClass.h:46
TinyVector< double, M > d2Coefs
Definition: ExpFitClass.h:34
void eval(double r, double &u)
Definition: ExpFitClass.h:163
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
double sign(double x)
Definition: Standard.h:73
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
Define determinant operators.
void FitCusp(std::vector< double > &r, std::vector< std::complex< double >> &u, double cusp)
Definition: ExpFitClass.h:208
TinyVector< std::complex< double >, M > dCoefs
Definition: ExpFitClass.h:196
void Fit(std::vector< double > &r, std::vector< std::complex< double >> &u)
Definition: ExpFitClass.h:231
void Fit(std::vector< double > &r, std::vector< double > &u)
Definition: ExpFitClass.h:107