00001 #include <iostream>
00002 #include "QMCLinearizeStepLength.h"
00003 #include "QMCInput.h"
00004 #include <iomanip>
00005
00006 using namespace std;
00007
00008
00009 bool QMCLinearizeStepLength::isLinear(int ai)
00010 {
00011 int numJW = globalInput.JP.getNumberJWParameters();
00012 int numCI = globalInput.WF.getNumberCIParameters();
00013
00014
00015 if(ai >= numJW && ai < (numJW + numCI))
00016 return true;
00017 return false;
00018 }
00019
00020 double QMCLinearizeStepLength::rescalingJCP()
00021 {
00022
00023 Array1D<double> N(dp.dim1());
00024 double denom = 1.0;
00025
00026 for(int j=0; j<N.dim1(); j++)
00027 for(int k=0; k<N.dim1(); k++)
00028 if(!isLinear(j) && !isLinear(k))
00029 denom += dp(j) * dp(k) * S(j+1,k+1);
00030 if(verbose) printf("den = %20.10e",denom);
00031 denom = sqrt(denom);
00032 denom = (1.0 - ksi) + ksi*denom;
00033 if(verbose) printf(" -> den = %20.10e\n",denom);
00034 if(verbose) cout << "Rescaling denominator: " << denom << endl;
00035 for(int ai=0; ai<N.dim1(); ai++)
00036 {
00037 if(isLinear(ai))
00038 {
00039 N(ai) = S(ai+1,0);
00040 } else {
00041
00042 double numerator = 0;
00043 for(int j=0; j<N.dim1(); j++)
00044 if(!isLinear(j))
00045 numerator += dp(j) * S(ai+1,j+1);
00046 if(verbose) printf("ai %3i num = %20.10e",ai,numerator);
00047 numerator *= (1.0 - ksi);
00048
00049 N(ai) = - numerator / denom;
00050 if(verbose) printf(" Nai = %20.10e\n",N(ai));
00051 }
00052 }
00053
00054 if(verbose) globalInput.printAIParameters(cout,"JCP terms",20,N,!true);
00055
00056 double sum = 0;
00057 for(int i=0; i<N.dim1(); i++)
00058 sum += dp(i) * N(i);
00059 sum = 1.0 - sum;
00060
00061 return 1.0 / sum;
00062 }
00063
00064 double QMCLinearizeStepLength::rescalingPRL()
00065 {
00066 Array1D<double> N(dp.dim1());
00067
00068 double sum_S0jPj = 0;
00069 for(int j=0; j<N.dim1(); j++)
00070 if(!isLinear(j))
00071 sum_S0jPj += S(0,j+1) * dp(j);
00072
00073 double sum_SjkPjPk = 0;
00074 for(int j=0; j<N.dim1(); j++)
00075 for(int k=0; k<N.dim1(); k++)
00076 if(!isLinear(j) && !isLinear(k))
00077 sum_SjkPjPk += S(j+1,k+1) * dp(j) * dp(k);
00078
00079 double D = sqrt(1.0 + 2.0 * sum_S0jPj + sum_SjkPjPk);
00080 double denom = ksi * D + (1.0 - ksi)*(1.0 + sum_S0jPj);
00081
00082 if(verbose) printf("S0jPj = %20.10e SjkPjPk = %20.10e D = %20.10e denom = %20.10e\n",
00083 sum_S0jPj, sum_SjkPjPk, D, denom);
00084
00085 for(int i=0; i<N.dim1(); i++)
00086 {
00087 double sum_SijPj = 0;
00088 for(int j=0; j<N.dim1(); j++)
00089 if(!isLinear(j))
00090 sum_SijPj += S(i+1,j+1) * dp(j);
00091
00092 double numerator = ksi * D * S(0,i+1) + (1.0 - ksi)*(S(0,i+1) + sum_SijPj);
00093
00094 N(i) = - numerator / denom;
00095
00096 if(verbose) printf("%3i S0i = %20.10e SijPj = %20.10e num = %20.10e N = %20.10e\n",
00097 i, S(0,i+1), sum_SijPj, numerator, N(i));
00098 }
00099
00100 if(verbose) globalInput.printAIParameters(cout,"PRL terms",20,N,!true);
00101 double sum = 0;
00102 for(int i=0; i<N.dim1(); i++)
00103 sum += dp(i) * N(i);
00104 sum = 1.0 - sum;
00105
00106 return 1.0 / sum;
00107 }
00108
00109 double QMCLinearizeStepLength::stepLength(QMCObjectiveFunction *function,
00110 Array1D<double> & delta_x,
00111 Array1D<double> & unused1,
00112 Array1D<double> & unused2,
00113 Array2D<double> & overlap,
00114 double ksi)
00115 {
00116 this->ksi = ksi;
00117 S = overlap;
00118 dp = delta_x;
00119
00120
00121
00122
00123 verbose = !true;
00124
00125 if(ksi > 1.0 || ksi < 0.0)
00126 {
00127 cerr << "Warning: bad value for ksi in QMCLinearizeStepLength!" << endl;
00128 cerr << " ksi = " << ksi << endl;
00129 ksi = 0.5;
00130 cerr << "changing, ksi is now = " << ksi << endl;
00131 }
00132
00133 double jcp_scale = rescalingJCP();
00134
00135 double scale = jcp_scale;
00136
00137
00138 return scale;
00139 }