1#ifndef EIGEN_SYSTEM_DAVIDSON_DEFINED
2# define EIGEN_SYSTEM_DAVIDSON_DEFINED
16template <
typename H,
typename P,
typename V>
19 typedef typename V::FieldType
F;
54 const int eigenVectorsCount_,
56 const double toleranceVectors,
57 const double toleranceEnergy,
58 const unsigned int maxBasisSize_,
59 const unsigned int maxIterations_,
60 const unsigned int minIterations_)
64 ,
tolerance({toleranceEnergy, toleranceVectors})
70 virtual void run() = 0;
113template <
typename H,
typename P,
typename V>
116 typedef typename V::FieldType
F;
119 const int eigenVectorsCount_,
121 const double toleranceVectors,
122 const double toleranceEnergy,
123 const unsigned int maxBasisSize_,
124 const unsigned int maxIterations_,
125 const unsigned int minIterations_)
137 .flags(std::ios::right | std::ios::scientific | std::ios::showpos);
139 LOG(1,
"Davidson") <<
"Initial basis retrieving" << std::endl;
141 std::vector<typename P::V> initialBasis(
142 this->
p->getInitialBasis(this->eigenVectorsCount));
145 LOG(1,
"Davidson") <<
"Initial basis retrieved" << std::endl;
148 std::vector<complex> previousReducedMatrixElements;
152 double energyDifference;
153 unsigned int iterationCount(0);
155 LOG(1,
"Davidson") <<
"iteration=" << (iterationCount + 1) << std::endl;
156 LOG(0,
"Davidson") <<
"It."
175 LOG(1,
"Davidson") <<
"Writing out overlap matrix" << std::endl;
176 std::string overlapFile(
"overlap-matrix-");
177 overlapFile += std::to_string(iterationCount);
178 for (
unsigned int i(0); i < rightBasis.size(); i++) {
179 for (
unsigned int j(0); j < rightBasis.size(); j++) {
180 complex overlap(rightBasis[i].
dot(rightBasis[j]));
181 FILE(overlapFile) << overlap <<
" ";
183 FILE(overlapFile) << std::endl;
189 this->refreshIterations.end(),
191 != this->refreshIterations.end()
192 || (this->refreshOnMaxBasisSize()
193 && rightBasis.size() >= this->maxBasisSize)) {
194 LOG(1,
"Davidson") <<
"Refreshing current basis!" << std::endl;
197 for (
unsigned int i(0); i < rightBasis.size(); i++) {
198 rightBasis[i] *=
F(0);
202 LOG(1,
"Davidson") <<
"Orthonormalizing the refreshed basis"
204 for (
unsigned int i(0); i < rightBasis.size(); i++) {
205 for (
unsigned int j(0); j < i; j++) {
206 rightBasis[i] -= rightBasis[j] * rightBasis[j].dot(rightBasis[i]);
208 F refreshedVectorNorm(std::sqrt(rightBasis[i].
dot(rightBasis[i])));
210 rightBasis[i] *= 1.0 / refreshedVectorNorm;
214 previousReducedMatrixElements.resize(0);
217 LOG(1,
"Davidson") <<
"Writing out overlap matrix" << std::endl;
218 std::string refreshOverlapFile(
"refreshed-overlap-matrix-");
219 refreshOverlapFile += std::to_string(iterationCount);
220 for (
unsigned int i(0); i < rightBasis.size(); i++) {
221 for (
unsigned int j(0); j < rightBasis.size(); j++) {
222 complex roverlap(rightBasis[i].
dot(rightBasis[j]));
223 FILE(refreshOverlapFile) << roverlap <<
" ";
225 FILE(refreshOverlapFile) << std::endl;
230 unsigned int previousBasisSize(
231 std::sqrt(previousReducedMatrixElements.size()));
235 for (
unsigned int j(0); j < previousBasisSize; ++j) {
236 for (
unsigned int i(0); i < previousBasisSize; ++i) {
238 previousReducedMatrixElements[i + previousBasisSize * j];
242 auto previousReducedMatrixElementsCopy(previousReducedMatrixElements);
243 previousReducedMatrixElements.resize(rightBasis.size()
244 * rightBasis.size());
246 for (
unsigned int j(0); j < previousReducedMatrixElements.size(); ++j) {
247 previousReducedMatrixElements[j] =
complex(0);
250 for (
unsigned int j(0); j < previousBasisSize; ++j) {
251 for (
unsigned int i(0); i < previousBasisSize; ++i) {
252 previousReducedMatrixElements[i + rightBasis.size() * j] =
253 previousReducedMatrixElementsCopy[i + previousBasisSize * j];
258 for (
unsigned int j(0); j < rightBasis.size(); ++j) {
260 V HBj(this->
h->right_apply(rightBasis[j]));
261 for (
unsigned int i(previousBasisSize); i < rightBasis.size(); ++i) {
263 reducedH(i, j) = rightBasis[i].dot(HBj);
264 previousReducedMatrixElements[i + rightBasis.size() * j] =
269 if (previousBasisSize > 0) {
271 for (
unsigned int j(previousBasisSize); j < rightBasis.size(); ++j) {
272 V HBj(this->
h->right_apply(rightBasis[j]));
273 for (
unsigned int i(0); i < rightBasis.size(); ++i) {
275 reducedH(i, j) = rightBasis[i].dot(HBj);
276 previousReducedMatrixElements[i + rightBasis.size() * j] =
290 LOG(1,
"Davidson") <<
"Writing out reduced overlap matrix" << std::endl;
291 std::string reducedOverlapFile(
"reduced-overlap-matrix-");
292 reducedOverlapFile += std::to_string(iterationCount);
293 for (
unsigned int i(0); i < rightBasis.size(); i++) {
294 for (
unsigned int j(0); j < rightBasis.size(); j++) {
296 for (
int c(0); c < reducedH.
getColumns(); ++c) {
298 std::conj(reducedEigenSystem.getLeftEigenVectors()(c, i))
299 * reducedEigenSystem.getRightEigenVectors()(c, j);
301 FILE(reducedOverlapFile) << redoverlap <<
" ";
303 FILE(reducedOverlapFile) << std::endl;
306 LOG(1,
"Davidson") <<
"Writing out reducedRR overlap matrix" << std::endl;
307 std::string reducedRROverlapFile(
"reduced-rr-overlap-matrix-");
308 reducedRROverlapFile += std::to_string(iterationCount);
309 for (
unsigned int i(0); i < rightBasis.size(); i++) {
310 for (
unsigned int j(0); j < rightBasis.size(); j++) {
312 for (
int c(0); c < reducedH.
getColumns(); ++c) {
314 std::conj(reducedEigenSystem.getRightEigenVectors()(c, i))
315 * reducedEigenSystem.getRightEigenVectors()(c, j);
317 FILE(reducedRROverlapFile) << redRROverlap <<
" ";
319 FILE(reducedRROverlapFile) << std::endl;
325 energyDifference = 0.0;
326 for (
unsigned int k(0); k < this->
eigenValues.size(); ++k) {
328 this->
eigenValues[k] = reducedEigenSystem.getEigenValues()[k];
332 for (
int b(0); b < reducedH.
getColumns(); ++b) {
340 reducedEigenSystem.getRightEigenVectors()(b, k));
344 for (
int b(0); b < reducedH.
getColumns(); ++b) {
348 reducedEigenSystem.getLeftEigenVectors()(b, k));
355 for (
int c(0); c < reducedH.
getColumns(); ++c) {
357 std::conj(reducedEigenSystem.getRightEigenVectors()(c, k))
358 * reducedEigenSystem.getRightEigenVectors()(c, k);
360 std::conj(reducedEigenSystem.getLeftEigenVectors()(c, k))
361 * reducedEigenSystem.getRightEigenVectors()(c, k);
362 lapackNorm += reducedEigenSystem.getLeftEigenVectors()(c, k)
363 * reducedEigenSystem.getRightEigenVectors()(c, k);
367 const F rightNorm(std::sqrt(
370 const F leftRightNorm(
374 V residuum(this->
h->right_apply(this->rightEigenVectors[k]));
375 const double kNorm = std::real(
379 rms += std::real(residuum.dot(residuum)) / kNorm;
382 V correction(this->
p->getCorrection(this->eigenValues[k], residuum));
385 for (
unsigned int b(0); b < rightBasis.size(); ++b) {
386 correction -= rightBasis[b] * rightBasis[b].dot(correction);
388 const F correction_norm(std::sqrt(correction.dot(correction)));
390 std::abs(previousEigenvalues[k] - this->
eigenValues[k]);
393 << iterationCount + 1 <<
" " << k + 1 <<
" " << rightBasis.size()
394 <<
" " << std::setprecision(15) << std::setw(23)
402 OUT() <<
" " << rightNorm <<
" " << leftRightNorm
403 <<
" " << lapackNorm <<
" " << lapackNormConjLR <<
" "
404 << lapackNormConjRR <<
" " << std::endl;
407 if (std::abs(correction_norm) < 1E-6)
continue;
408 correction *= 1.0 / correction_norm;
409 rightBasis.push_back(correction);
417 && (this->refreshOnMaxBasisSize()
423 && (this->refreshOnMaxBasisSize()
#define LOG(...)
Definition Log.hpp:119
#define OUT()
Provides an output stream for writing a log message of the log level specified by the argument....
Definition Log.hpp:107
#define FILE(NAME)
Definition Log.hpp:116
Definition Complex.hpp:48
Definition EigenSystemDavidson.hpp:114
EigenSystemDavidsonMono(H *h_, const int eigenVectorsCount_, P *p_, const double toleranceVectors, const double toleranceEnergy, const unsigned int maxBasisSize_, const unsigned int maxIterations_, const unsigned int minIterations_)
Definition EigenSystemDavidson.hpp:118
V::FieldType F
Definition EigenSystemDavidson.hpp:116
void run()
Definition EigenSystemDavidson.hpp:135
Definition EigenSystemDavidson.hpp:17
P * p
Definition EigenSystemDavidson.hpp:98
unsigned int maxBasisSize
Definition EigenSystemDavidson.hpp:103
const std::vector< V > & getRightEigenVectors() const
Definition EigenSystemDavidson.hpp:74
V::FieldType F
Definition EigenSystemDavidson.hpp:19
EigenSystemDavidson(H *h_, const int eigenVectorsCount_, P *p_, const double toleranceVectors, const double toleranceEnergy, const unsigned int maxBasisSize_, const unsigned int maxIterations_, const unsigned int minIterations_)
...
Definition EigenSystemDavidson.hpp:53
void refreshOnMaxBasisSize(const bool value)
Controls if the Davidson algorithm should make a refreshment of the basis whenever the maximal basis ...
Definition EigenSystemDavidson.hpp:85
unsigned int maxIterations
Definition EigenSystemDavidson.hpp:104
std::vector< V > leftEigenVectors
Definition EigenSystemDavidson.hpp:110
const struct sisi4s::EigenSystemDavidson::@0 tolerance
bool refreshOnMaxBasisSizeValue
Definition EigenSystemDavidson.hpp:107
unsigned int minIterations
Definition EigenSystemDavidson.hpp:105
int eigenVectorsCount
Definition EigenSystemDavidson.hpp:97
const std::vector< complex > & getEigenValues() const
Definition EigenSystemDavidson.hpp:72
const std::vector< V > & getLeftEigenVectors() const
Definition EigenSystemDavidson.hpp:78
double vectors
Definition EigenSystemDavidson.hpp:101
bool refreshOnMaxBasisSize()
Check wether or not the basis should be refreshed whenever the maximal basis size has been reached.
Definition EigenSystemDavidson.hpp:93
std::vector< V > rightEigenVectors
Definition EigenSystemDavidson.hpp:109
H * h
Definition EigenSystemDavidson.hpp:96
double energy
Definition EigenSystemDavidson.hpp:100
std::vector< complex > eigenValues
Definition EigenSystemDavidson.hpp:108
std::vector< int > refreshIterations
Definition EigenSystemDavidson.hpp:106
Definition LapackGeneralEigenSystem.hpp:15
Definition LapackMatrix.hpp:11
int getColumns() const
Definition LapackMatrix.hpp:64
Definition Algorithm.hpp:10
F dot(F const x, F const y)
Definition MathFunctions.hpp:45
Complex< real > complex
Definition Complex.hpp:17