MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
purification.hpp
1//
2// purification.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_INTERFACES_PURIFICATION_HPP
29#define MPQC_INTERFACES_PURIFICATION_HPP
30
31#include <mpqc/math/matrix.hpp>
32#include <tiledarray.h>
33#include <array>
34
35namespace mpqc {
36namespace purification {
37
38 using TArray2 = TA::Array<double, 2>;
39 // Holds data we want for each type of algorithm
40 struct performance {
41 std::size_t multiplies;
42 std::size_t adds;
43 std::size_t traces;
44 };
45
46 // Compute Eigenvalue Estimates first element is largest eigenvalue.
47 std::array<double ,2> BoundsTA(const TArray2 &F){
48 // make madness::Group all process that contain important row.
49 // define local reduction reduces tiles into the vector
50 // global reduction to finish the vector off.
51 // or maybe an all reduce
52 // Final
53
54 double min = 10, max = -10;
55 return {{max, min}};
56 }
57
58 std::array<double, 2> Bounds(const Matrix &F){
59 auto n = F.rows();
60 double min = 10;
61 for(auto i = 0; i < n; ++i){
62 double row_sum = 0;
63 for(auto j = 0; j < n; ++j){
64 row_sum += (j != i) ? -std::abs(F(i,j)) : F(i,i);
65 }
66 min = (row_sum < min) ? row_sum : min;
67 }
68
69 double max = -10;
70 for(auto i = 0; i < n; ++i){
71 double row_sum = 0;
72 for(auto j = 0; j < n; ++j){
73 row_sum += (j != i) ? std::abs(F(i,j)) : F(i,i);
74 }
75 max = (row_sum > max) ? row_sum : max;
76 }
77 return {{max, min}};
78 }
79
80 // Performs Trace Resetting Purification and returns number of multiplies and additions
81 performance tr_pure(const TArray2 &F, TArray2 &D, std::size_t occ){
82 performance data;
83 data.multiplies = 0;
84 data.adds = 1;
85 data.traces = 1; // Start at 1 since last while loop won't be counted
86 // and has one of each.
87 auto E = Bounds(F);
88
89 Matrix I = Eigen::MatrixXd::Identity(F.rows(), F.cols());
90
91 D = (E[0] * I - F)/(E[0] - E[1]);
92 data.adds++;
93
94 Matrix IDD = (I - D) * D;
95 data.adds++; data.multiplies++;
96
97 while((IDD).lpNorm<Eigen::Infinity>() > 1e-6){ // While D^2 != D
98 data.adds++; // Update counters
99
100 int gamma = (occ - D.trace() > 0) ? 1 : -1;
101 data.traces++;
102
103 D = D + gamma * IDD;
104 data.adds++;
105 D = 0.5 * Matrix(D + D.transpose());
106 IDD = (I - D) * D;
107 data.adds++; data.multiplies++;
108
109 }
110 return data;
111 }
112
113 Matrix Fpure(Matrix &D){
114 Matrix I = Eigen::MatrixXd::Identity(D.rows(), D.cols());
115 return Matrix(D * D * D * (4 * I - 3 * D));
116 }
117
118 Matrix Gpure(Matrix &D){
119 Matrix I = Eigen::MatrixXd::Identity(D.rows(), D.cols());
120 return Matrix( D * D * (I - D) * (I - D));
121 }
122
123 performance fourth_order_pure(const Matrix &F, Matrix &D, std::size_t occ){
124 performance data;
125 data.multiplies = 0;
126 data.adds = 1;
127 data.traces = 1; // Start at 1 since last while loop won't be counted
128 // and has one of each.
129 auto E = Bounds(F);
130
131 Matrix I = Eigen::MatrixXd::Identity(F.rows(), F.cols());
132
133 D = (E[0] * I - F)/(E[0] - E[1]);
134 data.adds++;
135
136 Matrix D2 = D*D;
137 data.multiplies++;
138
139 while((D - D2).lpNorm<Eigen::Infinity>() > 1e-9){ // While D^2 != D
140 data.adds++; // Update counters
141
142 Matrix D3 = D2 * D;
143 Matrix ID = I - D;
144 data.adds++; data.multiplies++;
145
146 double gamma = (double(occ) - Matrix(D3 * (4 * I - 3 * D)).trace())/
147 (Matrix(D2 * ID * ID).trace());
148 data.adds += 1; data.multiplies += 3; data.traces += 2;
149 if(gamma >= 6) {
150 D = 2 * D - D2;
151 data.adds++;
152 }
153 else if (gamma < 0){
154 D = D2;
155 }
156 else {
157 D = D3 * (4 * I - 3 * D) + gamma * (D2 * ID * ID);
158 data.adds += 4; data.multiplies += 3;
159 }
160 D2 = D * D;
161 data.multiplies++;
162 }
163
164 return data;
165 }
166
167 performance canonical_pure(const Matrix &F, Matrix &D, std::size_t occ){
168 performance data;
169 data.multiplies = 1;
170 data.adds = 1;
171 data.traces = 1; // Start at 1 since last while loop won't be counted
172 // and has one of each.
173 auto n = F.rows();
174 auto E = Bounds(F);
175
176 Matrix I = Eigen::MatrixXd::Identity(n, n);
177 double mu = F.trace()/n;
178 data.traces++;
179 double lambda = std::min(double(occ)/(E[0]-mu),
180 double(n-occ)/(mu - E[1]));
181 D = (lambda/double(n)) * (mu * I - F) + double(occ)/double(n) * I;
182 data.adds += 2;
183
184 Matrix D2 = D * D;
185 data.multiplies++;
186
187 while((D - D2).lpNorm<Eigen::Infinity>() > 1e-6
188 ){ // While D^2 != D
189 data.adds++; // Update counters
190
191 Matrix D3 = D2 * D;
192 data.multiplies++;
193
194 double c = (Matrix(D2 - D3).trace())/
195 (Matrix(D - D2).trace());
196 data.adds += 2; data.traces +=2;
197 if(c >= 0.5){
198 D = (1.0/c) * ((1 + c) * D2 - D3);
199 data.adds += 1;
200 } else {
201 D = 1.0/(1.0 - c) * ((1 - 2*c) * D + (1 + c)*D2 - D3);
202 data.adds += 2;
203 }
204
205 D2 = D * D;
206 data.multiplies++;
207 }
208
209 return data;
210 }
211} // namespace purification
212} // namespace mpqc
213
214
215
216
217
218
219#endif /* MPQC_INTERFACES_PURIFICATION_HPP */
matrix< double > Matrix
Convience double matrix type.
Definition matrix.hpp:170
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37
Definition purification.hpp:40

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