28 #ifndef MPQC_ORTHOG_CURVY_STEPS_HPP
29 #define MPQC_ORTHOG_CURVY_STEPS_HPP
31 #include <mpqc/math/matrix.hpp>
32 #include "purification.hpp"
45 double Rnorm2 = R.lpNorm<2>();
46 double Rsold = Rnorm2 * Rnorm2;
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++;
55 Matrix Ap_i = (FPD - FPD.transpose()) - 0.5*(PEs - PEs.transpose());
58 double alpha = Rsold / (
Matrix(P_i * Ap_i).lpNorm<2>());
63 X = X + d; data.adds++;
65 R = R - alpha * Ap_i; data.adds++;
67 double Rsnew = R.lpNorm<2>();
68 Rsnew = Rsnew * Rsnew;
70 P_i = R + (Rsnew/Rsold) * P_i; data.adds++;
75 std::cout <<
"Finished CG" << std::endl;
79 Matrix DX = D * X; data.multiplies++; data.adds++;
80 return DX + DX.transpose();
83 void BCH_rotate(
Matrix &D,
const Matrix &X, std::size_t order,
86 double Fac[] = {1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
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);
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++;
104 std::cout <<
"Dpure = \n" << D << std::endl;
105 std::cout <<
"Finish pure" << std::endl;
109 performance data={0,0,0};
111 Matrix FD = F * D; data.multiplies++;
112 Matrix Eanti = FD - FD.transpose(); data.adds++;
113 Matrix Esymm = FD + FD.transpose(); data.adds++;
115 Matrix X = Eigen::MatrixXd::Zero(F.cols(), F.rows());
116 conjugategradient(F,X,D,Esymm,Eanti,data);
118 double scale = 0.001/X.lpNorm<Eigen::Infinity>();
121 std::size_t rotation_order = 2;
122 BCH_rotate(D, X, rotation_order, data);