24 #include "ConjugateGradient.h" 31 veclength = veclength_in;
33 DIAG_CUTOFF = DIAG_CUTOFF_in;
39 XVEC =
new double[ veclength ];
40 PRECON =
new double[ veclength ];
41 RHS =
new double[ veclength ];
42 WORK =
new double[ veclength ];
43 RESID =
new double[ veclength ];
44 PVEC =
new double[ veclength ];
45 OPVEC =
new double[ veclength ];
97 apply_precon( XVEC, WORK );
116 if ( rnorm >= RTOL ){
117 apply_precon( PVEC, WORK );
122 apply_precon( XVEC );
135 pointers[1][0] = rnorm;
144 void CheMPS2::ConjugateGradient::stepL2K(){
146 apply_precon( OPVEC );
147 const double alpha = rdotr / inprod( PVEC, OPVEC );
148 for (
int elem = 0; elem < veclength; elem++ ){
149 XVEC[ elem ] = XVEC[ elem ] + alpha * PVEC[ elem ];
151 for (
int elem = 0; elem < veclength; elem++ ){
152 RESID[ elem ] = RESID[ elem ] - alpha * OPVEC[ elem ];
154 const double new_rdotr = inprod( RESID );
155 const double beta = new_rdotr / rdotr;
156 for (
int elem = 0; elem < veclength; elem++ ){
157 PVEC[ elem ] = RESID[ elem ] + beta * PVEC[ elem ];
160 rnorm = sqrt( rdotr );
161 if ( print ){ cout <<
"ConjugateGradient : After " << num_matvec <<
" matrix-vector products, the residual of p*O*p * x = p*RHS is " << rnorm << endl; }
165 void CheMPS2::ConjugateGradient::stepY2Z(){
168 for (
int elem = 0; elem < veclength; elem++ ){
169 const double diff = OPVEC[ elem ] - RHS[ elem ];
170 rnorm += diff * diff;
172 rnorm = sqrt( rnorm );
173 if ( print ){ cout <<
"ConjugateGradient : At convergence the residual of O * x = RHS is " << rnorm << endl; }
177 void CheMPS2::ConjugateGradient::stepJ2K(){
179 apply_precon( OPVEC );
180 for (
int elem = 0; elem < veclength; elem++ ){
181 RESID[ elem ] = RESID[ elem ] - OPVEC[ elem ];
183 for (
int elem = 0; elem < veclength; elem++ ){
184 PVEC[ elem ] = RESID[ elem ];
186 rdotr = inprod( RESID );
187 rnorm = sqrt( rdotr );
191 void CheMPS2::ConjugateGradient::stepG2H(){
194 for (
int elem = 0; elem < veclength; elem++ ){
195 if ( PRECON[ elem ] < DIAG_CUTOFF ){ PRECON[ elem ] = DIAG_CUTOFF; }
196 PRECON[ elem ] = 1.0 / sqrt( PRECON[ elem ] );
200 apply_precon( RHS, RESID );
203 for (
int elem = 0; elem < veclength; elem++ ){
204 XVEC[ elem ] = XVEC[ elem ] / PRECON[ elem ];
209 double CheMPS2::ConjugateGradient::inprod(
double * vector ){
211 double inproduct = 0.0;
212 for (
int elem = 0; elem < veclength; elem++ ){
213 inproduct += vector[ elem ] * vector[ elem ];
219 double CheMPS2::ConjugateGradient::inprod(
double * vector,
double * othervector ){
221 double inproduct = 0.0;
222 for (
int elem = 0; elem < veclength; elem++ ){
223 inproduct += vector[ elem ] * othervector[ elem ];
229 void CheMPS2::ConjugateGradient::apply_precon(
double * vector ){
231 for (
int elem = 0; elem < veclength; elem++ ){
232 vector[ elem ] = PRECON[ elem ] * vector[ elem ];
237 void CheMPS2::ConjugateGradient::apply_precon(
double * vector,
double * result ){
239 for (
int elem = 0; elem < veclength; elem++ ){
240 result[ elem ] = PRECON[ elem ] * vector[ elem ];
char step(double **pointers)
The iterator to converge the ground state vector.
int get_num_matvec() const
Get the number of matrix vector multiplications which have been performed.
virtual ~ConjugateGradient()
Destructor.
ConjugateGradient(const int veclength_in, const double RTOL_in, const double DIAG_CUTOFF_in, const bool print_in)
Constructor.