QMCPACK
test_Eigensolver.cpp
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) 2023 QMCPACK developers.
6 //
7 // File developed by: Mark Dewing, markdewing@gmail.com
8 //
9 // File created by: Mark Dewing, markdewing@gmail.com
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include "catch.hpp"
15 #include <random>
16 
17 
18 namespace qmcplusplus
19 {
20 
22 
23 TEST_CASE("solveGeneralizedEigenvalues", "[drivers]")
24 {
25  // Eigenvalues and eigenvectors from gen_eigenval.py
26  const int N = 2;
27  Matrix<Real> Ovlp(N, N);
28  Matrix<Real> Ham(N, N);
29 
30  Ovlp(0, 0) = 1.0;
31  Ovlp(0, 1) = 0.1;
32  Ovlp(1, 0) = 0.15;
33  Ovlp(1, 1) = 1.0;
34 
35  Ham(0, 0) = -4.0;
36  Ham(0, 1) = 0.2;
37  Ham(1, 0) = 0.3;
38  Ham(1, 1) = 1.0;
39  std::vector<Real> ev(N);
40  Matrix<Real> evec(N, N);
41  Eigensolver::solveGeneralizedEigenvalues(Ham, Ovlp, ev, evec);
42  CHECK(ev[0] == Approx(-4.10958));
43  CHECK(ev[1] == Approx(1.00298));
44  app_log() << "ev = " << ev[0] << " " << ev[1] << std::endl;
45 
46  app_log() << " evec " << evec(0, 0) << " " << evec(0, 1) << std::endl;
47  app_log() << " evec " << evec(1, 0) << " " << evec(1, 1) << std::endl;
48 
49  CHECK(evec(0, 0) == Approx(-1.0));
50  CHECK(evec(0, 1) == Approx(0.17935662));
51  CHECK(evec(1, 0) == Approx(0.01992851));
52  CHECK(evec(1, 1) == Approx(1.0));
53 }
54 
55 TEST_CASE("solveGeneralizedEigenvaluesInv", "[drivers]")
56 {
57  const int N = 2;
58  Matrix<Real> Ovlp(N, N);
59  Matrix<Real> Ham(N, N);
60 
61  Ovlp(0, 0) = 1.0;
62  Ovlp(0, 1) = 0.1;
63  Ovlp(1, 0) = 0.15;
64  Ovlp(1, 1) = 1.0;
65 
66  Ham(0, 0) = -4.0;
67  Ham(0, 1) = 0.2;
68  Ham(1, 0) = 0.3;
69  Ham(1, 1) = 1.0;
70  std::vector<Real> ev(N);
71  Matrix<Real> evec(N, N);
73  CHECK(ev[0] == Approx(-4.10958));
74  CHECK(ev[1] == Approx(1.00298));
75  app_log() << "ev = " << ev[0] << " " << ev[1] << std::endl;
76 
77  app_log() << " evec " << evec(0, 0) << " " << evec(0, 1) << std::endl;
78  app_log() << " evec " << evec(1, 0) << " " << evec(1, 1) << std::endl;
79 
80  CHECK(evec(0, 0) == Approx(-0.98429354));
81  CHECK(evec(0, 1) == Approx(0.17653957));
82  CHECK(evec(1, 0) == Approx(-0.01992456));
83  CHECK(evec(1, 1) == Approx(-0.99980149));
84 }
85 
86 
87 TEST_CASE("solveGeneralizedEigenvaluesCompare", "[drivers]")
88 {
89  const int N = 4;
90  Matrix<Real> Ovlp(N, N);
91  Matrix<Real> Ham(N, N);
92 
93  std::mt19937 mt(100);
94  std::uniform_real_distribution<Real> rnd(0.0, 1.0);
95 
96 
97  for (int i = 0; i < N; i++)
98  {
99  Ovlp(i, i) = 1.0;
100  }
101 
102  for (int i = 0; i < N; i++)
103  {
104  Ovlp(i, i) = 1.0;
105  for (int j = 0; j < i; j++)
106  {
107  Ovlp(i, j) = rnd(mt);
108  Ovlp(j, i) = Ovlp(i, j) + 0.1;
109  }
110  }
111 
112 
113  for (int i = 0; i < N; i++)
114  {
115  Ham(i, i) = 1.0;
116  for (int j = 0; j < i; j++)
117  {
118  Ham(i, j) = rnd(mt);
119  Ham(j, i) = Ham(i, j) - 0.1;
120  }
121  }
122 
123  Matrix<Real> Ovlp_copy(N, N);
124  Matrix<Real> Ham_copy(N, N);
125 
126  Ovlp_copy = Ovlp;
127  Ham_copy = Ham;
128 
129  std::vector<Real> ev1(N);
130  Matrix<Real> evec1(N, N);
131  Eigensolver::solveGeneralizedEigenvalues(Ham_copy, Ovlp_copy, ev1, evec1);
132 
133  Ovlp_copy = Ovlp;
134  Ham_copy = Ham;
135 
136  std::vector<Real> ev2(N);
137  Matrix<Real> evec2(N, N);
138  Eigensolver::solveGeneralizedEigenvalues_Inv(Ham_copy, Ovlp_copy, ev2, evec2);
139 
140  for (int i = 0; i < N; i++)
141  {
142  CHECK(ev1[i] == Approx(ev2[i]));
143  }
144 }
145 
146 } // namespace qmcplusplus
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
static void solveGeneralizedEigenvalues(Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors)
Use generalized eigenvalue solver.
Definition: Eigensolver.cpp:32
std::ostream & app_log()
Definition: OutputManager.h:65
TEST_CASE("complex_helper", "[type_traits]")
ForceBase::Real Real
Definition: ForceBase.cpp:26
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
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))