QMCPACK
LinearMethod Class Reference
+ Inheritance diagram for LinearMethod:
+ Collaboration diagram for LinearMethod:

Public Member Functions

Real getLowestEigenvector (Matrix< Real > &A, std::vector< Real > &ev) const
 
Real getNonLinearRescale (std::vector< Real > &dP, Matrix< Real > &S, const QMCCostFunctionBase &optTarget) const
 

Static Public Member Functions

static Real selectEigenvalue (std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors, Real zerozero, std::vector< Real > &ev)
 Select eigenvalue and return corresponding scaled eigenvector. More...
 
static Real getLowestEigenvector_Inv (Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &ev)
 Solve the generalized eigenvalue problem and return a scaled eigenvector corresponding to the selected eigenvalue. More...
 
static Real getLowestEigenvector_Gen (Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &ev)
 Solve the generalized eigenvalue problem and return a scaled eigenvector corresponding to the selected eigenvalue. More...
 

Private Types

using Real = QMCTraits::RealType
 

Private Member Functions

void getNonLinearRange (int &first, int &last, const QMCCostFunctionBase &optTarget) const
 

Detailed Description

Definition at line 31 of file LinearMethod.h.

Member Typedef Documentation

◆ Real

using Real = QMCTraits::RealType
private

Definition at line 33 of file LinearMethod.h.

Member Function Documentation

◆ getLowestEigenvector()

LinearMethod::Real getLowestEigenvector ( Matrix< Real > &  A,
std::vector< Real > &  ev 
) const

Definition at line 123 of file LinearMethod.cpp.

References qmcplusplus::Units::distance::A, APP_ABORT, qmcplusplus::app_log(), Matrix< T, Alloc >::data(), LAPACK::geev(), and qmcplusplus::Units::second.

Referenced by QMCFixedSampleLinearOptimizeBatched::previous_linear_methods_run(), QMCFixedSampleLinearOptimize::run(), and QMCFixedSampleLinearOptimizeBatched::solveShiftsWithoutLMYEngine().

124 {
125  int Nl(ev.size());
126  // Getting the optimal worksize
127  Real zerozero = A(0, 0);
128  char jl('N');
129  char jr('V');
130  std::vector<Real> alphar(Nl), alphai(Nl), beta(Nl);
131  Matrix<Real> eigenT(Nl, Nl);
132  Matrix<Real> eigenD(Nl, Nl);
133  int info;
134  int lwork(-1);
135  std::vector<Real> work(1);
136  LAPACK::geev(&jl, &jr, &Nl, A.data(), &Nl, &alphar[0], &alphai[0], eigenD.data(), &Nl, eigenT.data(), &Nl, &work[0],
137  &lwork, &info);
138  lwork = int(work[0]);
139  work.resize(lwork);
140 
141  LAPACK::geev(&jl, &jr, &Nl, A.data(), &Nl, &alphar[0], &alphai[0], eigenD.data(), &Nl, eigenT.data(), &Nl, &work[0],
142  &lwork, &info);
143  if (info != 0)
144  {
145  APP_ABORT("Invalid Matrix Diagonalization Function!");
146  }
147 
148  // Filter and sort to find desired eigenvalue.
149  // Filter accepts eigenvalues between E_0 and E_0 - 100.0,
150  // where E_0 is H(0,0), the current estimate for the VMC energy.
151  // Sort searches for eigenvalue closest to E_0 - 2.0
152 
153  bool found_any_eigenvalue = false;
154  std::vector<std::pair<Real, int>> mappedEigenvalues(Nl);
155  for (int i = 0; i < Nl; i++)
156  {
157  Real evi(alphar[i]);
158  if ((evi < zerozero) && (evi > (zerozero - 1e2)))
159  {
160  mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
161  mappedEigenvalues[i].second = i;
162  found_any_eigenvalue = true;
163  }
164  else
165  {
166  mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
167  mappedEigenvalues[i].second = i;
168  }
169  }
170 
171  // Sometimes there is no eigenvalue less than E_0, but there is one slightly higher.
172  // Run filter and sort again, except this time accept eigenvalues between E_0 + 100.0 and E_0 - 100.0.
173  // Since it's already been determined there are no eigenvalues below E_0, the sort
174  // finds the eigenvalue closest to E_0.
175  if (!found_any_eigenvalue)
176  {
177  app_log() << "No eigenvalues passed initial filter. Trying broader 100 a.u. filter" << std::endl;
178 
179  bool found_higher_eigenvalue;
180  for (int i = 0; i < Nl; i++)
181  {
182  Real evi(alphar[i]);
183  if ((evi < zerozero + 1e2) && (evi > (zerozero - 1e2)))
184  {
185  mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
186  mappedEigenvalues[i].second = i;
187  found_higher_eigenvalue = true;
188  }
189  else
190  {
191  mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
192  mappedEigenvalues[i].second = i;
193  }
194  }
195  if (!found_higher_eigenvalue)
196  {
197  app_log() << "No eigenvalues passed second filter. Optimization is likely to fail." << std::endl;
198  }
199  }
200  std::sort(mappedEigenvalues.begin(), mappedEigenvalues.end());
201  // for (int i=0; i<4; i++) app_log()<<i<<": "<<alphar[mappedEigenvalues[i].second]<< std::endl;
202  for (int i = 0; i < Nl; i++)
203  ev[i] = eigenT(mappedEigenvalues[0].second, i) / eigenT(mappedEigenvalues[0].second, 0);
204  return alphar[mappedEigenvalues[0].second];
205  // }
206 }
std::ostream & app_log()
Definition: OutputManager.h:65
QMCTraits::RealType Real
Definition: LinearMethod.h:33
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
static void geev(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *alphar, double *alphai, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)
Definition: BLAS.hpp:594

◆ getLowestEigenvector_Gen()

LinearMethod::Real getLowestEigenvector_Gen ( Matrix< Real > &  A,
Matrix< Real > &  B,
std::vector< Real > &  ev 
)
static

Solve the generalized eigenvalue problem and return a scaled eigenvector corresponding to the selected eigenvalue.

Parameters
[in]AHamiltonian matrix
[in]BOverlap matrix
[out]evScaled eigenvector

This uses a generalized eigenvalue solver (LAPACK ggev).

Definition at line 41 of file LinearMethod.cpp.

References qmcplusplus::Units::distance::A, B(), LinearMethod::selectEigenvalue(), and Eigensolver::solveGeneralizedEigenvalues().

Referenced by QMCFixedSampleLinearOptimizeBatched::one_shift_run().

42 {
43  int Nl(ev.size());
44  std::vector<Real> alphar(Nl);
45  Matrix<Real> eigenT(Nl, Nl);
46  Real zerozero = A(0, 0);
48  return selectEigenvalue(alphar, eigenT, zerozero, ev);
49 }
static void solveGeneralizedEigenvalues(Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors)
Use generalized eigenvalue solver.
Definition: Eigensolver.cpp:32
QMCTraits::RealType Real
Definition: LinearMethod.h:33
double B(double x, int k, int i, const std::vector< double > &t)
static Real selectEigenvalue(std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors, Real zerozero, std::vector< Real > &ev)
Select eigenvalue and return corresponding scaled eigenvector.

◆ getLowestEigenvector_Inv()

LinearMethod::Real getLowestEigenvector_Inv ( Matrix< Real > &  A,
Matrix< Real > &  B,
std::vector< Real > &  ev 
)
static

Solve the generalized eigenvalue problem and return a scaled eigenvector corresponding to the selected eigenvalue.

Parameters
[in]AHamiltonian matrix
[in]BOverlap matrix
[out]evScaled eigenvector

This uses a regular eigenvalue solver for B^-1 A (LAPACK geev). In theory using the generalized eigenvalue solver is more numerically stable, but in practice this solver is sufficiently stable, and is faster than the generalized solver.

Definition at line 31 of file LinearMethod.cpp.

References qmcplusplus::Units::distance::A, B(), LinearMethod::selectEigenvalue(), and Eigensolver::solveGeneralizedEigenvalues_Inv().

Referenced by QMCFixedSampleLinearOptimizeBatched::one_shift_run().

32 {
33  int Nl(ev.size());
34  std::vector<Real> alphar(Nl);
35  Matrix<Real> eigenT(Nl, Nl);
36  Real zerozero = A(0, 0);
38  return selectEigenvalue(alphar, eigenT, zerozero, ev);
39 }
QMCTraits::RealType Real
Definition: LinearMethod.h:33
static void solveGeneralizedEigenvalues_Inv(Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors)
Solve by explicitly inverting the overlap matrix.
Definition: Eigensolver.cpp:78
double B(double x, int k, int i, const std::vector< double > &t)
static Real selectEigenvalue(std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors, Real zerozero, std::vector< Real > &ev)
Select eigenvalue and return corresponding scaled eigenvector.

◆ getNonLinearRange()

void getNonLinearRange ( int &  first,
int &  last,
const QMCCostFunctionBase optTarget 
) const
private

Definition at line 208 of file LinearMethod.cpp.

References QMCCostFunctionBase::getParameterTypes(), and optimize::LINEAR_P.

Referenced by LinearMethod::getNonLinearRescale().

209 {
210  std::vector<int> types;
211  optTarget.getParameterTypes(types);
212  first = 0;
213  last = types.size();
214  //assume all non-linear coeffs are together.
215  if (types[0] == optimize::LINEAR_P)
216  {
217  int i(0);
218  while (i < types.size())
219  {
220  if (types[i] == optimize::LINEAR_P)
221  first = i;
222  i++;
223  }
224  first++;
225  }
226  else
227  {
228  int i(types.size() - 1);
229  while (i >= 0)
230  {
231  if (types[i] == optimize::LINEAR_P)
232  last = i;
233  i--;
234  }
235  }
236  // returns the number of non-linear parameters.
237  // app_log()<<"line params: "<<first<<" "<<last<< std::endl;
238 }

◆ getNonLinearRescale()

LinearMethod::Real getNonLinearRescale ( std::vector< Real > &  dP,
Matrix< Real > &  S,
const QMCCostFunctionBase optTarget 
) const

Definition at line 240 of file LinearMethod.cpp.

References LinearMethod::getNonLinearRange(), and qmcplusplus::sqrt().

Referenced by QMCFixedSampleLinearOptimizeBatched::one_shift_run(), QMCFixedSampleLinearOptimizeBatched::previous_linear_methods_run(), QMCFixedSampleLinearOptimize::run(), and QMCFixedSampleLinearOptimizeBatched::solveShiftsWithoutLMYEngine().

243 {
244  int first(0), last(0);
245  getNonLinearRange(first, last, optTarget);
246  if (first == last)
247  return 1.0;
248  Real rescale(1.0);
249  Real xi(0.5);
250  Real D(0.0);
251  for (int i = first; i < last; i++)
252  for (int j = first; j < last; j++)
253  D += S(i + 1, j + 1) * dP[i + 1] * dP[j + 1];
254  rescale = (1 - xi) * D / ((1 - xi) + xi * std::sqrt(1 + D));
255  rescale = 1.0 / (1.0 - rescale);
256  // app_log()<<"rescale: "<<rescale<< std::endl;
257  return rescale;
258 }
void getNonLinearRange(int &first, int &last, const QMCCostFunctionBase &optTarget) const
QMCTraits::RealType Real
Definition: LinearMethod.h:33
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)

◆ selectEigenvalue()

LinearMethod::Real selectEigenvalue ( std::vector< Real > &  eigenvals,
Matrix< Real > &  eigenvectors,
Real  zerozero,
std::vector< Real > &  ev 
)
static

Select eigenvalue and return corresponding scaled eigenvector.

Parameters
[in]eigenvalsEigenvalues
[in]eigenvectorsEigenvectors
[in]zerozeroThe H(0,0) element, used to guide eigenvalue selection
[out]evThe eigenvector scaled by the reciprocal of the first element
Returns
The selected eigenvalue

Definition at line 57 of file LinearMethod.cpp.

References qmcplusplus::app_log(), and qmcplusplus::Units::second.

Referenced by LinearMethod::getLowestEigenvector_Gen(), LinearMethod::getLowestEigenvector_Inv(), and qmcplusplus::TEST_CASE().

61 {
62  // Filter and sort to find desired eigenvalue.
63  // Filter accepts eigenvalues between E_0 and E_0 - 100.0,
64  // where E_0 is H(0,0), the current estimate for the VMC energy.
65  // Sort searches for eigenvalue closest to E_0 - 2.0
66  int Nl = eigenvals.size();
67 
68  bool found_any_eigenvalue = false;
69  std::vector<std::pair<Real, int>> mappedEigenvalues(Nl);
70  for (int i = 0; i < Nl; i++)
71  {
72  Real evi(eigenvals[i]);
73  if ((evi < zerozero) && (evi > (zerozero - 1e2)))
74  {
75  mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
76  mappedEigenvalues[i].second = i;
77  found_any_eigenvalue = true;
78  }
79  else
80  {
81  mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
82  mappedEigenvalues[i].second = i;
83  }
84  }
85 
86  // Sometimes there is no eigenvalue less than E_0, but there is one slightly higher.
87  // Run filter and sort again, except this time accept eigenvalues between E_0 + 100.0 and E_0 - 100.0.
88  // Since it's already been determined there are no eigenvalues below E_0, the sort
89  // finds the eigenvalue closest to E_0.
90  if (!found_any_eigenvalue)
91  {
92  app_log() << "No eigenvalues passed initial filter. Trying broader 100 a.u. filter" << std::endl;
93 
94  bool found_higher_eigenvalue;
95  for (int i = 0; i < Nl; i++)
96  {
97  Real evi(eigenvals[i]);
98  if ((evi < zerozero + 1e2) && (evi > (zerozero - 1e2)))
99  {
100  mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
101  mappedEigenvalues[i].second = i;
102  found_higher_eigenvalue = true;
103  }
104  else
105  {
106  mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
107  mappedEigenvalues[i].second = i;
108  }
109  }
110  if (!found_higher_eigenvalue)
111  {
112  app_log() << "No eigenvalues passed second filter. Optimization is likely to fail." << std::endl;
113  }
114  }
115  std::sort(mappedEigenvalues.begin(), mappedEigenvalues.end());
116  // for (int i=0; i<4; i++) app_log()<<i<<": "<<alphar[mappedEigenvalues[i].second]<< std::endl;
117  for (int i = 0; i < Nl; i++)
118  ev[i] = eigenvectors(mappedEigenvalues[0].second, i) / eigenvectors(mappedEigenvalues[0].second, 0);
119  return eigenvals[mappedEigenvalues[0].second];
120 }
std::ostream & app_log()
Definition: OutputManager.h:65
QMCTraits::RealType Real
Definition: LinearMethod.h:33

The documentation for this class was generated from the following files: