00001 #include <config.h>
00002
00003 CPS_START_NAMESPACE
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 CPS_END_NAMESPACE
00046 #include <util/dirac_op.h>
00047 #include <util/lattice.h>
00048 #include <util/smalloc.h>
00049 #include <util/vector.h>
00050 #include <util/gjp.h>
00051 #include <comms/glb.h>
00052 #include <util/verbose.h>
00053 #include <util/error.h>
00054 #include <util/qcdio.h>
00055 #include <math.h>
00056 CPS_START_NAMESPACE
00057 void MatHermElements( DiracOpWilsonTypes * dirac_op,
00058 Vector ** psi, int n_vec, int f_size,
00059 Float * diag, Complex * off_diag );
00060
00061 inline void PrintDot(char *fname, char *vname, Vector *tmp, int f_size){
00062
00063 }
00064
00065
00066
00067
00068
00069
00070 inline Float Norm( Vector* psi, int f_size )
00071 {
00072 Float norm( sqrt(psi->NormSqGlbSum(f_size)) );
00073
00074 psi->VecTimesEquFloat(1.0/norm,f_size);
00075 return norm;
00076 }
00077
00078 Float GramSchmNorm( Vector* psi,
00079 Vector* vec,
00080 int f_size )
00081 {
00082 const Complex xp(vec->CompDotProductGlbSum(psi, f_size));
00083 psi->CTimesV1PlusV2 (-xp, vec, psi, f_size);
00084 return Norm(psi,f_size);
00085 }
00086
00087
00088
00089 int DiracOpWilsonTypes::RitzEig(Vector **psi, Float lambda_H[], int valid_eig[], EigArg *eig_arg)
00090 {
00091 char *fname = "RitzEig(V**,V**,I)";
00092 VRB.Func(cname,fname);
00093
00094
00095
00096 const Float RsdR_a ( eig_arg->RsdR_a );
00097 const Float RsdR_r ( eig_arg->RsdR_r );
00098 const Float Rsdlam ( eig_arg->Rsdlam );
00099 const Float Cv_fact ( eig_arg->Cv_fact );
00100 const int N_eig ( eig_arg->N_eig );
00101 const int N_min ( eig_arg->N_min );
00102 const int N_max ( eig_arg->N_max );
00103 const int n_renorm ( eig_arg->n_renorm );
00104 const int MaxCG ( eig_arg->MaxCG );
00105 const int ProjApsiP ( eig_arg->ProjApsiP );
00106
00107 int Kalk_Sim ( eig_arg->Kalk_Sim );
00108 int N_KS_max ( eig_arg->N_KS_max );
00109
00110
00111
00112
00113 VRB.LedFlash(cname,fname,3);
00114 VRB.LedOff(cname,fname);
00115 VRB.Func(cname,fname);
00116
00117
00118
00119
00120 VRB.Input(cname,fname,
00121 "mass = %g\n",IFloat(eig_arg->mass));
00122 VRB.Input(cname,fname,
00123 "N_eig = %d\n",N_eig);
00124
00125
00126
00127
00128
00129
00130 if (N_eig == 1) Kalk_Sim = 0;
00131
00132 if (Kalk_Sim == 0) N_KS_max = 0;
00133
00134
00135 Float acc = 2.0e-6;
00136 acc *= acc;
00137 Float rsdl_sq = Rsdlam * Rsdlam;
00138 rsdl_sq = (rsdl_sq > acc) ? rsdl_sq : acc;
00139 Float rsdl_zero = 10.0 * rsdl_sq;
00140
00141
00142
00143
00144 const int f_size = RitzLatSize();
00145
00146
00147 Float lambda_t, del_lamb;
00148 int j, n, ij, NCG_tot, n_KS;
00149 int i;
00150 int n_jacob;
00151
00152
00153 Float * lambda = lambda_H;
00154
00155
00156
00157
00158
00159
00160
00161
00162 Float *lambda_old = & lambda_H[N_eig];
00163
00164
00165
00166 Complex *off_diag (0x0);
00167 if (N_eig > 1)
00168 {
00169 off_diag = (Complex *) smalloc(cname,fname, "off_diag", N_eig*(N_eig-1)/2 * sizeof(Complex));
00170
00171 for(int i=0; i < N_eig*(N_eig-1)/2; ++i)
00172 off_diag[i] = 0.0;
00173 }
00174
00175 NCG_tot = 0;
00176
00177
00178
00179 for(n=0; n < N_eig; ++n)
00180 {
00181 lambda_old[n] = 1.0;
00182 valid_eig[n] = 0;
00183 }
00184
00185 del_lamb = 1.0;
00186
00187 if (Kalk_Sim == 1)
00188 {
00189
00190 for(n_KS = 1; n_KS <= N_KS_max && del_lamb > Rsdlam; n_KS++)
00191 {
00192 ij = 0;
00193 for(n = 1, i = 0; n <= N_eig; n++, i++)
00194 {
00195
00196
00197
00198
00199
00200 int ncnt = Ritz(psi, n, lambda_t, RsdR_a, RsdR_r, Rsdlam, 0.0 ,
00201 n_renorm, Kalk_Sim, N_min, N_max, Cv_fact, MaxCG,
00202 ProjApsiP);
00203
00204
00205 if ( ncnt < 0 ) { if ( off_diag !=0x0 ) { sfree(off_diag); } ; return ncnt; }
00206
00207 NCG_tot += ncnt;
00208 VRB.Result(cname,fname ,"PCNTINFO KS=%d n_eig=%d ncnt=%d\n", n_KS, n, ncnt);
00209
00210 lambda[i] = lambda_t;
00211 VRB.Debug(cname,fname,"yes KS: lambda[%d] = %g\n",i,(IFloat)lambda[i]);
00212
00213 Vector *tmp = (Vector *) smalloc(f_size * sizeof(Float));
00214 if(tmp == 0)
00215 ERR.Pointer(cname,fname, "tmp");
00216 VRB.Smalloc(cname,fname, "tmp", tmp, f_size * sizeof(Float));
00217
00218 RitzMat(tmp, psi[i]);
00219
00220 for(j = 0; j < i; j++)
00221 off_diag[ij++] = psi[j]->CompDotProductGlbSum(tmp, f_size);
00222
00223 VRB.Sfree(cname,fname, "tmp", tmp);
00224 sfree(tmp);
00225 }
00226
00227 n_jacob = Jacobi(psi, N_eig, lambda, off_diag, RsdR_a, 50);
00228
00229 VRB.Result(cname, fname, "NCG_tot=%d\n", NCG_tot);
00230
00231 for(i = 0; i < N_eig; i++)
00232 VRB.Result(cname,fname,"KS=%d: lambda[%d] = %g\n",n_KS,i,(IFloat)(lambda[i]));
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 if ( n_KS == 1 )
00263 {
00264 for(i = 0; i < N_eig; i++) lambda_old[i] = lambda[i];
00265 }
00266 else
00267 {
00268 del_lamb = 0.0;
00269 for(i = 0; i < N_eig; i++)
00270 {
00271 lambda_t = fabs((lambda_old[i]-lambda[i])/lambda[i]);
00272 if (lambda_t > del_lamb)
00273 del_lamb = lambda_t;
00274 lambda_old[i]=lambda[i];
00275 }
00276 }
00277 }
00278
00279
00280
00281
00282 if (n_KS >= N_KS_max) {
00283
00284
00285
00286
00287
00288
00289
00290 VRB.Warn(cname,fname,"NONConversion_warning: n_KS = %d N_KS_max = %d\n",
00291 n_KS,N_KS_max);
00292
00293 if ( off_diag !=0x0 ) { sfree(off_diag); }
00294 return -2;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 }
00321 else
00322 {
00323 ij = 0;
00324 for(n = 1, i = 0; n <= N_eig; n++, i++)
00325 {
00326 NCG_tot += Ritz(psi, n, lambda_t, RsdR_a, RsdR_r, Rsdlam, 0.0 ,
00327 n_renorm, 0, 0, 0, Cv_fact, MaxCG, ProjApsiP);
00328
00329
00330 lambda_old[i] = lambda_t;
00331 VRB.Debug(cname,fname,"no KS: lambda[%d] = %g\n",i,(IFloat)lambda_old[i]);
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 }
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 MatHermElements(this, psi, N_eig, f_size, lambda_H, off_diag);
00371
00372
00373
00374
00375
00376
00377 for (i=0;i<N_eig;i++) { valid_eig[i] = 1; }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 bool looping(true);
00388
00389 while ( looping )
00390 {
00391 looping = false;
00392 for (i=0;i<N_eig;i++)
00393 {
00394 if ( valid_eig[i] )
00395 {
00396 int xy(0),x,y;
00397 const Float rEig2( 1/lambda_old[i] );
00398 Float sum (lambda_H[i]*lambda_H[i] * rEig2);
00399
00400
00401 for (x=0;x<N_eig;x++)
00402 {
00403 for (y=0;y<x;y++)
00404 {
00405 if ( ( x==i && valid_eig[y] ) || ( y==i && valid_eig[x] ) )
00406 {
00407 Float value( off_diag[xy].abs() );
00408 sum+=value*value*rEig2;
00409 }
00410 xy++;
00411 }
00412 }
00413
00414
00415
00416 if ( sum < 0.98 )
00417 {
00418 valid_eig[i] = 0;
00419
00420
00421 looping = true;
00422 }
00423 }
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432 {
00433 int ij = 0;
00434 int i, j;
00435 FILE* fp(Fopen(eig_arg->fname,"a"));
00436 Fprintf(fp,"Eig2 before projection/jacobi\n");
00437
00438 for(i = 0; i < N_eig; i++)
00439 {
00440 Fprintf(fp,"%i %e %i\n",i,lambda_old[i],valid_eig[i]);
00441 }
00442 for(i = 0; i < N_eig; i++)
00443 {
00444 Fprintf(fp,"Jacobi matrix: %i %i %e\n",i,i,(float)lambda_H[i]);
00445 for(j = 0; j < i; j++)
00446 {
00447 Fprintf(fp,"Jacobi matrix: %i %i %e %e\n"
00448 ,i
00449 ,j
00450 ,off_diag[ij].real()
00451 ,off_diag[ij].imag() );
00452 ij++;
00453 }
00454 }
00455 Fclose(fp);
00456 }
00457
00458 int N_dp(0);
00459 for(i=0;i<N_eig;i++)
00460 {
00461 if ( valid_eig[i] == 1 ) N_dp++;
00462 else { break; }
00463 }
00464
00465 VRB.Flow(cname,fname,"N_dp=%d\n",N_dp);
00466 for (i++;i<N_eig;i++) { valid_eig[i] = 0; }
00467
00468
00469 Vector *tmp = (Vector *) smalloc(f_size * sizeof(Float));
00470 if(tmp == 0) ERR.Pointer("",fname, "tmp");
00471 Vector *tmp2 = (Vector *) smalloc(f_size * sizeof(Float));
00472 if(tmp2 == 0) ERR.Pointer("",fname, "tmp2");
00473
00474 while ( N_dp < N_eig )
00475 {
00476 valid_eig[N_dp] = 1;
00477
00478 const Float lam(sqrt(fabs(lambda_old[N_dp])));
00479 VRB.Flow(cname,fname,"lam=%e\n",lam);
00480
00481
00482 RitzEigMat(tmp,psi[N_dp]);
00483 PrintDot(fname,"psi[N_sp]",psi[N_dp],f_size);
00484 PrintDot(fname,"tmp",tmp,f_size);
00485
00486 const Float proj(tmp->ReDotProductGlbSum(psi[N_dp], f_size));
00487 VRB.Flow(cname,fname,"proj=%e\n",proj);
00488
00489 Float sign(1);
00490 if ( proj < 0 ) { sign = -1; }
00491
00492
00493 tmp2->FTimesV1PlusV2( sign/lam, tmp, psi[N_dp], f_size );
00494 PrintDot(fname,"tmp2",tmp2,f_size);
00495 Rcomplex snorm(0,0),onorm(0,0);
00496 for (i=0;i<N_dp;i++)
00497 {
00498 snorm+=tmp2->CompDotProductGlbSum(psi[i],f_size);
00499 }
00500 tmp->FTimesV1PlusV2( -sign/lam, tmp, psi[N_dp], f_size );
00501 PrintDot(fname,"tmp",tmp,f_size);
00502 for (i=0;i<N_dp;i++)
00503 {
00504 onorm+=tmp->CompDotProductGlbSum(psi[i],f_size);
00505 }
00506 if ( onorm.norm() > snorm.norm() )
00507 {
00508 psi[N_dp]->CopyVec( tmp2, f_size );
00509 }
00510 else
00511 {
00512 psi[N_dp]->CopyVec( tmp, f_size );
00513 }
00514 Norm(psi[N_dp],f_size);
00515 PrintDot(fname,"psi[N_sp]",psi[N_dp],f_size);
00516 N_dp++;
00517 }
00518
00519 for (i=0;i<N_eig;i++)
00520 {
00521 for(j=i+1;j<N_eig;j++)
00522 {
00523 GramSchmNorm(psi[j],psi[i],f_size);
00524 PrintDot(fname,"psi[i]",psi[i],f_size);
00525 PrintDot(fname,"psi[j]",psi[j],f_size);
00526 }
00527 }
00528
00529
00530
00531 sfree(tmp);
00532 sfree(tmp2);
00533
00534
00535
00536
00537
00538
00539 int min_dim(0);
00540 for(i=0;i<N_eig;i++){ if(valid_eig[i]) min_dim++; }
00541
00542
00543
00544
00545
00546
00547 MatHermElements(this, psi, min_dim, f_size, lambda_H, off_diag);
00548
00549 {
00550 int ij = 0;
00551 int i, j;
00552 FILE* fp(Fopen(eig_arg->fname,"a"));
00553 Fprintf(fp,"Jacobi matrix after projection\n");
00554
00555 for(i = 0; i < N_eig; i++)
00556 {
00557 Fprintf(fp,"Jacobi matrix: %i %i %e\n",i,i,(float)lambda_H[i]);
00558 for(j = 0; j < i; j++)
00559 {
00560 Fprintf(fp,"Jacobi matrix: %i %i %e %e\n"
00561 ,i
00562 ,j
00563 ,off_diag[ij].real()
00564 ,off_diag[ij].imag() );
00565 ij++;
00566 }
00567 }
00568 Fclose(fp);
00569 }
00570
00571 n_jacob = Jacobi(psi, min_dim, lambda_H, off_diag, 1.0e-5, 50);
00572
00573 if(N_eig>1) sfree(off_diag);
00574
00575
00576
00577
00578 VRB.Result(cname,fname,"Final Jacobi: n_jacob=%d NCG=%d\n",
00579 n_jacob,NCG_tot);
00580
00581 for(n = 0; n < N_eig; n++)
00582 VRB.Result(cname,fname,"lambda_HH[%d] = %g\n",n,(float)lambda_old[n]);
00583 for(n = 0; n < N_eig; n++)
00584 VRB.Result(cname,fname,"lambda_H[%d] = %g\n",n,(float)lambda_H[n]);
00585
00586
00587 return NCG_tot;
00588
00589
00590
00591
00592 #if 0
00593
00594
00595
00596
00597
00599 if (N_eig > 2)
00600 {
00601 lambda_t = lambda_old[N_eig-1] - lambda_old[N_eig-2] + Rsdlam;
00602 dummy = lambda_old[N_eig-2] - lambda_old[N_eig-3] + Rsdlam;
00603 if (lambda_t < 0.0 && dummy > 0.0)
00604 {
00605 n = N_eig - 1;
00606 }
00607 else
00608 n = N_eig;
00609 }
00610 else
00611 n = N_eig;
00612
00613 dummy = sqrt(Rsdlam);
00614
00615 if (N_eig > 1)
00616 {
00617 n_jacob = Jacobi(psi, n, lambda_H, off_diag, RsdR_a, 50);
00618
00619
00620 n_valid = 0;
00621 for(n = 0; n < N_eig; n++)
00622 {
00623 valid_eig[n] = 0;
00624 lambda_t = lambda_H[n]*lambda_H[n];
00625 if( lambda_t < rsdl_zero )
00626 {
00627 for(j = n_valid; j < N_eig; j++)
00628 if( lambda[j] < rsdl_zero )
00629 {
00630 valid_eig[n] = 1;
00631 n_valid++;
00632 break;
00633 }
00634 }
00635 else
00636 {
00637 for(j = n_valid; j < N_eig; j++)
00638 {
00639 del_lamb = fabs(lambda[j] - lambda_t);
00640 if( del_lamb < dummy*lambda[j] )
00641 {
00642 valid_eig[n] = 1;
00643 n_valid++;
00644 break;
00645 }
00646 }
00647 }
00648 }
00649
00650 VRB.Result(cname,fname,"Final Jacobi: n_jacob=%d n_valid=%d NCG=%d\n",
00651 n_jacob,n_valid,NCG_tot);
00652 for(n = 0; n < N_eig; n++)
00653 VRB.Result(cname,fname,"lambda_old[%d] = %g\n",n,(IFloat)lambda_old[n]);
00654 for(n = 0; n < N_eig; n++)
00655 VRB.Result(cname,fname,"lambda_H[%d] = %g\n",n,(IFloat)lambda_H[n]);
00656 for(n = 0; n < N_eig; n++)
00657 VRB.Result(cname,fname,"valid_eig[%d] = %d\n",n,valid_eig[n]);
00658
00659 VRB.Sfree(cname,fname, "off_diag", off_diag);
00660 sfree(off_diag);
00661 }
00662 else
00663 {
00664 del_lamb = fabs(lambda_H[0] * lambda_H[0] - lambda[0]);
00665 if( del_lamb < dummy*lambda[0] )
00666 {
00667 valid_eig[0] = 1;
00668 n_valid = 1;
00669 }
00670 else
00671 {
00672 valid_eig[0] = 0;
00673 n_valid = 0;
00674 }
00675
00676 VRB.Result(cname,fname,"Final Result: n_valid=%d NCG=%d\n",n_valid,NCG_tot);
00677 for(n = 0; n < N_eig; n++)
00678 VRB.Result(cname,fname,"lambda[%d] = %g\n",n,(IFloat)lambda[n]);
00679 for(n = 0; n < N_eig; n++)
00680 VRB.Result(cname,fname,"lambda_H[%d] = %g\n",n,(IFloat)lambda_H[n]);
00681 for(n = 0; n < N_eig; n++)
00682 VRB.Result(cname,fname,"valid_eig[%d] = %d\n",n,valid_eig[n]);
00683 }
00684
00685 VRB.Sfree(cname,fname, "lambda_old", lambda_old);
00686 sfree(lambda_old);
00687 VRB.Sfree(cname,fname, "lambda", lambda);
00688 sfree(lambda);
00689
00690
00691
00692
00693 VRB.FuncEnd(cname,fname);
00694 VRB.LedFlash(cname,fname,2);
00695 VRB.LedOn(cname,fname);
00696
00697 return NCG_tot;
00698
00699 #endif // OLD CODE END
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709 void MatHermElements( DiracOpWilsonTypes * dirac_op,
00710 Vector ** psi, int n_vec, int f_size,
00711 Float * diag, Complex * off_diag ){
00712
00713 char * fname = "MatHermElements";
00714 Vector *tmp = (Vector *) smalloc("DiracOpWilsonTypes",fname,"tmp",f_size * sizeof(Float));
00715
00716
00717 int ij = 0;
00718 int i, j;
00719
00720 for(i = 0; i < n_vec; i++) {
00721 dirac_op->RitzEigMat(tmp, psi[i]);
00722 diag[i] = psi[i]->ReDotProductGlbSum(tmp, f_size);
00723 #if 0
00724 Float *tmp_p = (Float*)tmp;
00725 for(j = 0; j < 10; j++)
00726 printf("tmp[%d]=%e\n",j,*(tmp_p+j));
00727 tmp_p = (Float*)psi[i];
00728 for(j = 0; j < 10; j++)
00729 printf("psi[%d][%d]=%e\n",i,j,*(tmp_p+j));
00730 printf("%s: diag[%d]=%e\n",fname,i,diag[i]);
00731 #endif
00732 PrintDot(fname,"psi[i]",psi[i],f_size);
00733 PrintDot(fname,"tmp",tmp,f_size);
00734 for(j = 0; j < i; j++){
00735 off_diag[ij++] = psi[j]->CompDotProductGlbSum(tmp, f_size);
00736 #if 0
00737 tmp_p = (Float*) off_diag+ij;
00738 printf("%s: off_diag[%d]=%e %e\n",fname,ij-1,*tmp_p, *(tmp_p+1));
00739 #endif
00740 }
00741 }
00742
00743 sfree(tmp);
00744 }
00745
00746
00747
00748 CPS_END_NAMESPACE