MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
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
34namespace 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 */
matrix< double > Matrix
Convience double matrix type.
Definition matrix.hpp:170
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37

Generated at Wed Sep 25 2024 02:45:30 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.