MPQC  3.0.0-alpha
orthog_curvy_steps.hpp
1 //
2 // orthog_curvy_steps.hpp
3 //
4 // Copyright (C) 2013 Drew Lewis
5 //
6 // Authors: Drew Lewis
7 // Maintainer: Drew Lewis and Edward Valeev
8 //
9 // This file is part of the MPQC Toolkit.
10 //
11 // The MPQC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The MPQC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the MPQC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef MPQC_ORTHOG_CURVY_STEPS_HPP
29 #define MPQC_ORTHOG_CURVY_STEPS_HPP
30 
31 #include <mpqc/math/matrix.hpp>
32 #include "purification.hpp"
33 
34 namespace mpqc {
35  void conjugategradient(const Matrix &F, Matrix &X, const Matrix &D,
36  const Matrix &Esymm, const Matrix &Eanti,
37  performance &data){
38  Matrix FXD = X; // X guess is 0 so anything times X is 0.
39  Matrix RHS = X;
40 
41  // Gradient
42  Matrix R = Eanti;
43  Matrix P_i = R;
44 
45  double Rnorm2 = R.lpNorm<2>();
46  double Rsold = Rnorm2 * Rnorm2;
47 
48  Matrix d_old = P_i;
49 
50  int iter = 0;
51  while(std::sqrt(Rsold) > 1e-6 && iter < 4){
52  Matrix FPD = F * P_i * D; data.multiplies++;
53  Matrix PEs = P_i * Esymm; data.multiplies++;
54 
55  Matrix Ap_i = (FPD - FPD.transpose()) - 0.5*(PEs - PEs.transpose());
56  data.adds += 3;
57 
58  double alpha = Rsold / (Matrix(P_i * Ap_i).lpNorm<2>());
59  // Not doing a multiply here since this could be optimized away.
60 
61  Matrix d = alpha * P_i;
62 
63  X = X + d; data.adds++;
64 
65  R = R - alpha * Ap_i; data.adds++;
66 
67  double Rsnew = R.lpNorm<2>();
68  Rsnew = Rsnew * Rsnew;
69 
70  P_i = R + (Rsnew/Rsold) * P_i; data.adds++;
71 
72  Rsold = Rsnew;
73  ++iter;
74  }
75  std::cout << "Finished CG" << std::endl;
76  }
77 
78  Matrix commuter(const Matrix &D, const Matrix &X, performance &data){
79  Matrix DX = D * X; data.multiplies++; data.adds++; // Adds is for the return statement
80  return DX + DX.transpose();
81  }
82 
83  void BCH_rotate(Matrix &D, const Matrix &X, std::size_t order,
84  performance &data){
85  Matrix LHS = D;
86  double Fac[] = {1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
87  39916800};
88 
89  Matrix steps = commuter(D,X,data);
90  for(auto i = 0; i < order; ++i){
91  LHS = LHS + 1/Fac[i] * steps; data.adds++;
92  steps = commuter(steps, X, data);
93  }
94  D = LHS;
95  }
96 
97  void Purify(Matrix &D, performance &data){
98  std::cout << "Dpre = \n" << D << std::endl;
99  Matrix D2 = D*D; data.multiplies++;
100  while((D-D2).lpNorm<Eigen::Infinity>() > 1e-6){
101  D = 3 * D2 - 2 * D2 * D; data.adds++; data.multiplies++;
102  D2 = D*D;
103  }
104  std::cout << "Dpure = \n" << D << std::endl;
105  std::cout << "Finish pure" << std::endl;
106  }
107 
108  performance curvy_step(const Matrix &F, Matrix &D){
109  performance data={0,0,0};
110 
111  Matrix FD = F * D; data.multiplies++;
112  Matrix Eanti = FD - FD.transpose(); data.adds++;
113  Matrix Esymm = FD + FD.transpose(); data.adds++;
114 
115  Matrix X = Eigen::MatrixXd::Zero(F.cols(), F.rows());
116  conjugategradient(F,X,D,Esymm,Eanti,data);
117 
118  double scale = 0.001/X.lpNorm<Eigen::Infinity>();
119  X = scale * X;
120 
121  std::size_t rotation_order = 2;
122  BCH_rotate(D, X, rotation_order, data);
123 
124  Purify(D, data);
125 
126  return data;
127  }
128 }
129 
130 
131 
132 
133 #endif /* MPQC_ORTHOG_CURVY_STEPS_HPP */
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::Matrix
matrix< double > Matrix
Convience double matrix type.
Definition: matrix.hpp:170

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.