QMCPACK
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) 2020 QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
10 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
11 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
12 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 // Mark Dewing, mdewing@anl.gov, Argonne National Laboratory
14 //
15 // File created by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
16 //////////////////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "Eigensolver.h"
20 #include <vector>
21 #include <CPU/BLAS.hpp>
24 
25 
26 namespace qmcplusplus
27 {
28 
29 
30 // A - Hamiltonian
31 // B - Overlap
33  Matrix<Real>& B,
34  std::vector<Real>& eigenvals,
35  Matrix<Real>& eigenvectors)
36 {
37  int Nl = A.rows();
38  assert(A.rows() == A.cols());
39  assert(Nl == eigenvals.size());
40  assert(Nl == eigenvectors.rows());
41  assert(Nl == eigenvectors.cols());
42 
43  // transpose the A and B (row-major vs. column-major)
44  for (int i = 0; i < Nl; i++)
45  for (int j = i + 1; j < Nl; j++)
46  {
47  std::swap(A(i, j), A(j, i));
48  std::swap(B(i, j), B(j, i));
49  }
50 
51  // Getting the optimal worksize
52  char jl('N');
53  char jr('V');
54  std::vector<Real> alphar(Nl), alphai(Nl), beta(Nl);
55  //Matrix<Real> eigenT(Nl, Nl);
56  int info;
57  int lwork(-1);
58  std::vector<Real> work(1);
59  Real tt(0);
60  int t(1);
61  LAPACK::ggev(&jl, &jr, &Nl, A.data(), &Nl, B.data(), &Nl, alphar.data(), alphai.data(), beta.data(), &tt, &t,
62  eigenvectors.data(), &Nl, work.data(), &lwork, &info);
63  lwork = int(work[0]);
64  work.resize(lwork);
65 
66  LAPACK::ggev(&jl, &jr, &Nl, A.data(), &Nl, B.data(), &Nl, alphar.data(), alphai.data(), beta.data(), &tt, &t,
67  eigenvectors.data(), &Nl, work.data(), &lwork, &info);
68  if (info != 0)
69  throw std::runtime_error("Invalid Matrix Diagonalization Function, ggev info = " + std::to_string(info));
70 
71  for (int i = 0; i < Nl; i++)
72  eigenvals[i] = alphar[i] / beta[i];
73 }
74 
75 
76 // A - Hamiltonian
77 // B - Overlap
79  Matrix<Real>& B,
80  std::vector<Real>& eigenvals,
81  Matrix<Real>& eigenvectors)
82 {
83  int Nl = A.rows();
84  assert(A.rows() == A.cols());
85  assert(Nl == eigenvals.size());
86  assert(Nl == eigenvectors.rows());
87  assert(Nl == eigenvectors.cols());
88 
89  invert_matrix(B, false);
90 
91  Matrix<Real> prdMat(Nl, Nl);
92 
93  MatrixOperators::product(B, A, prdMat);
94 
95  // transpose the result (why?)
96  for (int i = 0; i < Nl; i++)
97  for (int j = i + 1; j < Nl; j++)
98  std::swap(prdMat(i, j), prdMat(j, i));
99 
100  // Getting the optimal worksize
101  char jl('N');
102  char jr('V');
103  std::vector<Real> alphai(Nl);
104  Matrix<Real> eigenD(Nl, Nl);
105  int info;
106  int lwork(-1);
107  std::vector<Real> work(1);
108  LAPACK::geev(&jl, &jr, &Nl, prdMat.data(), &Nl, eigenvals.data(), alphai.data(), eigenD.data(), &Nl,
109  eigenvectors.data(), &Nl, work.data(), &lwork, &info);
110  lwork = int(work[0]);
111  work.resize(lwork);
112 
113  LAPACK::geev(&jl, &jr, &Nl, prdMat.data(), &Nl, eigenvals.data(), alphai.data(), eigenD.data(), &Nl,
114  eigenvectors.data(), &Nl, work.data(), &lwork, &info);
115  if (info != 0)
116  throw std::runtime_error("Invalid Matrix Diagonalization Function, geev info = " + std::to_string(info));
117 }
118 
119 } // namespace qmcplusplus
MatrixA::value_type invert_matrix(MatrixA &M, bool getdet=true)
invert a matrix
static void ggev(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, double *alphar, double *alphai, double *beta, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)
Definition: BLAS.hpp:667
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
static void solveGeneralizedEigenvalues(Matrix< Real > &A, Matrix< Real > &B, std::vector< Real > &eigenvals, Matrix< Real > &eigenvectors)
Use generalized eigenvalue solver.
Definition: Eigensolver.cpp:32
size_type cols() const
Definition: OhmmsMatrix.h:78
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
void product(const Matrix< T > &A, const Matrix< T > &B, Matrix< T > &C)
static function to perform C=AB for real matrices
size_type rows() const
Definition: OhmmsMatrix.h:77
Define determinant operators.
double B(double x, int k, int i, const std::vector< double > &t)
QMCTraits::RealType Real
Definition: Eigensolver.h:30
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