Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

alg_eig.C

Go to the documentation of this file.
00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003 //------------------------------------------------------------------
00009 //--------------------------------------------------------------------
00010 //  CVS keywords
00011 //
00012 //  $Author: chulwoo $
00013 //  $Date: 2009/03/23 19:13:32 $
00014 //  $Header: /space/cvs/cps/cps++/src/alg/alg_eig/alg_eig.C,v 1.25 2009/03/23 19:13:32 chulwoo Exp $
00015 //  $Id: alg_eig.C,v 1.25 2009/03/23 19:13:32 chulwoo Exp $
00016 //  $Name: v5_0_8 $
00017 //  $Locker:  $
00018 //  $RCSfile: alg_eig.C,v $
00019 //  $Revision: 1.25 $
00020 //  $Source: /space/cvs/cps/cps++/src/alg/alg_eig/alg_eig.C,v $
00021 //  $State: Exp $
00022 //
00023 //--------------------------------------------------------------------
00024 
00025 CPS_END_NAMESPACE
00026 #include <util/qcdio.h>
00027 #include <util/enum.h>
00028 #include <math.h>
00029 #include <alg/alg_eig.h>
00030 #include <util/lattice.h>
00031 #include <util/gjp.h>
00032 #include <util/smalloc.h>
00033 #include <util/time_cps.h>
00034 #include <util/vector.h>
00035 #include <util/verbose.h>
00036 #include <util/error.h>
00037 CPS_START_NAMESPACE
00038 
00039 #include <iostream>
00040 #include <fstream>
00041 #include <iomanip>
00042 using namespace std;
00043 
00044 extern void gamma_5(Float *v_out, Float *v_in, int num_sites);
00045 
00046 int NumChkb( RitzMatType ritz_mat)
00047 {
00048   // Determine the number of checkerboards
00049   int Ncb=0;
00050   char *fname = "NumChkb(RitzType)";
00051   switch(ritz_mat)
00052   {
00053   case MAT_HERM:
00054   case MATDAG_MAT:
00055   case NEG_MATDAG_MAT:
00056   case MATDAG_MAT_NORM:
00057   case NEG_MATDAG_MAT_NORM:
00058     Ncb = 2;
00059     break;
00060     
00061   case MATPC_HERM:
00062   case MATPCDAG_MATPC:
00063   case NEG_MATPCDAG_MATPC:
00064     Ncb = 1;
00065     break;
00066 
00067   default:
00068     ERR.General("",fname,"RitzMatOper %d not implemented",
00069                 ritz_mat);
00070   }
00071   return Ncb;
00072 }
00073 
00074 //------------------------------------------------------------------
00075 // Constructor 
00081 //------------------------------------------------------------------
00082 AlgEig::AlgEig(Lattice& latt, 
00083                CommonArg *c_arg,
00084                EigArg *arg) : 
00085                Alg(latt, c_arg) 
00086 {
00087   cname = "AlgEig";
00088   char *fname = "AlgEig(L&,CommonArg*,EigArg*)";
00089   VRB.Func(cname,fname);
00090 
00091   // Initialize the argument pointer
00092   //----------------------------------------------------------------
00093   if(arg == 0)
00094     ERR.Pointer(cname,fname, "arg");
00095   alg_eig_arg = arg;
00096 
00097   Ncb = NumChkb(alg_eig_arg->RitzMatOper);
00098 
00099   // Set the node size of the full (non-checkerboarded) fermion field
00100   // NOTE: at this point we must know on what lattice size the operator 
00101   // will act.
00102   //----------------------------------------------------------------
00103   int f_size = GJP.VolNodeSites() * latt.FsiteSize() * Ncb / 2;
00104   VRB.Flow(cname,fname,"f_size=%d\n",0);
00105 //  int f_size = GJP.VolNodeSites() * Ncb / 2;
00106 //  exit(1);
00107   int N_eig = alg_eig_arg->N_eig;
00108 
00109   // Allocate memory for the eigenvectors and eigenvalues
00110   //----------------------------------------------------------------
00111   eigenv = (Vector **) smalloc (cname,fname, "eigenv", N_eig * sizeof(Vector *));
00112   
00113   for(int n = 0; n < N_eig; ++n)
00114   {
00115     eigenv[n] = (Vector *) smalloc(cname,fname, "eigenv[n]", (f_size)* sizeof(Float));
00116   }
00117 
00118   lambda = (Float *) smalloc(cname,fname, "lambda", 2*N_eig * sizeof(Float));
00119 
00120   chirality = (Float *) smalloc(cname,fname,"chirality", N_eig * sizeof(Float));
00121 
00122   valid_eig = (int *) smalloc(cname,fname,"valid_eig",N_eig * sizeof(int));
00123 
00124   // Print out input parameters
00125   //----------------------------------------------------------------
00126   VRB.Input(cname,fname,
00127             "N_eig = %d\n",int(N_eig));
00128   VRB.Input(cname,fname,
00129             "MaxCG = %d\n",alg_eig_arg->MaxCG);
00130   VRB.Input(cname,fname,
00131             "Mass_init = %g\n",IFloat(alg_eig_arg->Mass_init));
00132   VRB.Input(cname,fname,
00133             "Mass_final = %g\n",IFloat(alg_eig_arg->Mass_final));
00134   VRB.Input(cname,fname,
00135             "Mass_step = %g\n",IFloat(alg_eig_arg->Mass_step));
00136 
00137   // Calculate n_masses if necessary
00138   VRB.Flow(cname,fname,"alg_eig_arg->pattern_kind=%d\n",alg_eig_arg->pattern_kind);
00139   switch( alg_eig_arg->pattern_kind ) {
00140   case ARRAY: 
00141     n_masses = alg_eig_arg->Mass.Mass_len;
00142     break;
00143   case LOG:
00144     n_masses = (int) ((log(alg_eig_arg->Mass_final - alg_eig_arg->Mass_init)
00145                     / log(alg_eig_arg->Mass_step)) + 1.000001);
00146     break;
00147   case LIN:   
00148     n_masses = (int) (fabs((alg_eig_arg->Mass_final 
00149       - alg_eig_arg->Mass_init)/alg_eig_arg->Mass_step) + 1.000001); 
00150     break;
00151   default: 
00152     ERR.General(cname, fname,
00153                 "alg_eig_arg->pattern_kind = %d is unrecognized\n", 
00154                 alg_eig_arg->pattern_kind);
00155     break;
00156   }  
00157   VRB.FuncEnd(cname,fname);
00158 
00159 }
00160 
00161 
00162 //------------------------------------------------------------------
00163 // Destructor
00164 //------------------------------------------------------------------
00165 AlgEig::~AlgEig() {
00166   char *fname = "~AlgEig()";
00167   VRB.Func(cname,fname);
00168 
00169   // Free memory
00170   //----------------------------------------------------------------
00171   sfree(cname,fname, "valid_eig", valid_eig);
00172 
00173   sfree(cname,fname, "chirality", chirality);
00174 
00175   sfree(cname,fname, "lambda", lambda);
00176 
00177   for(int n = alg_eig_arg->N_eig - 1; n >= 0; --n)
00178   {
00179     sfree(cname,fname, "eigenv[n] ",eigenv[n]);
00180   }
00181 
00182   sfree(cname,fname, "eigenv", eigenv);
00183 
00184   //???
00185 }
00186 
00188 void AlgEig::run()
00189 {
00190   run((Float**)0);
00191 }
00192 
00193 
00194 //------------------------------------------------------------------
00196 
00200 //------------------------------------------------------------------
00201 void AlgEig::run(Float **evalues)
00202 {
00203 #if TARGET==cpsMPI
00204     using MPISCU::fprintf;
00205 #endif
00206 
00207   Float time = -dclock();
00208   int iter=0;
00209   EigArg *eig_arg;
00210   char *fname = "run()";
00211   VRB.Func(cname,fname);
00212 
00213   // Set the Lattice pointer eig_arg
00214   //----------------------------------------------------------------
00215   Lattice& lat = AlgLattice();
00216   eig_arg = alg_eig_arg;
00217   Float **hsum;
00218   const int N_eig = eig_arg->N_eig;
00219   const int f_size = GJP.VolNodeSites() * lat.FsiteSize() * Ncb / 2;
00220   int hsum_len = 0;
00221   int n;
00222 
00223   if (eig_arg->print_hsum)
00224   {
00225     switch(eig_arg->hsum_dir)
00226     {
00227     case 0:
00228       hsum_len = GJP.Xnodes()*GJP.XnodeSites();
00229       break;
00230     case 1:
00231       hsum_len = GJP.Ynodes()*GJP.YnodeSites();
00232       break;
00233     case 2:
00234       hsum_len = GJP.Znodes()*GJP.ZnodeSites();
00235       break;
00236     case 3:
00237       hsum_len = GJP.Tnodes()*GJP.TnodeSites();
00238       break;
00239     case 4:
00240       if (lat.Fclass() == F_CLASS_DWF) 
00241         hsum_len = GJP.Snodes()*GJP.SnodeSites();
00242       else
00243         ERR.General(cname,fname,"Invalid direction\n");
00244       break;
00245      default:
00246       ERR.General(cname,fname,"Invalid direction\n");
00247     }
00248 
00249     hsum = (Float **) smalloc(cname,fname,"hsum",N_eig * sizeof(Float*)); // surely Float* ?
00250   
00251     for(n = 0; n < N_eig; ++n)
00252     {
00253       hsum[n] = (Float *) smalloc(cname,fname,"hsum[n]",hsum_len * sizeof(Float));
00254     }
00255   }
00256   else
00257   {
00258     hsum = (Float **) 0;
00259   }
00260 
00261   // allocate memory to store the eigenvectors
00262   Vector** eig_store=0;
00263   if(eig_arg->ncorr) 
00264   {
00265     eig_store = (Vector**)smalloc(cname,fname, "eig_store",N_eig * sizeof(Vector*));
00266     for(n=0;n<N_eig;++n)
00267     {
00268       eig_store[n] = (Vector*) smalloc(cname,fname, "eig_store",f_size * sizeof(Float));
00269     }
00270   }
00271 
00272 
00273   // Initialize eigenvectors to gaussian
00274   // and compute eigenvectors
00275   //----------------------------------------------------------------
00276   //for(int n = 0; n < eig_arg->N_eig; ++n)
00277   //  lat.RandGaussVector(eigenv[n], 0.5, Ncb);
00278   
00279   int sign_dm=1;
00280 
00281   // Initialize the cg_arg mass, with the first mass we
00282   // want to compute for:
00283   switch( eig_arg->pattern_kind ) {
00284   case ARRAY: 
00285     eig_arg->mass = eig_arg->Mass.Mass_val[0]; 
00286     break;
00287   case LIN:   
00288     // Loop over mass values
00289     sign_dm = (eig_arg->Mass_step < 0.0) ? -1 : 1;
00290     eig_arg->mass = eig_arg->Mass_init; 
00291     if (sign_dm*eig_arg->Mass_init > sign_dm*eig_arg->Mass_final)
00292       ERR.General(cname,fname,"initial and final mass not valid\n");
00293     break;
00294   case LOG:   
00295     eig_arg->mass = eig_arg->Mass_init; 
00296     break;
00297   default: 
00298     ERR.General(cname, fname,
00299                 "eig_arg->pattern_kind = %d is unrecognized\n", 
00300                 eig_arg->pattern_kind);
00301     break;
00302   }
00303 
00304   // Loop over masses
00305   for(int m=0; m<n_masses; m++){
00306     
00307     //for(Float mass = eig_arg->Mass_init; 
00308     //sign_dm*mass <= sign_dm*eig_arg->Mass_final;
00309     //mass += eig_arg->Mass_step){
00310 
00311     //eig_arg->mass = mass;
00312     // count the number of masses 
00313     int count(0);
00314 
00315 
00316     // store eigenvectors from previous mass
00317     if(eig_arg->ncorr && ( count > 0 ) ){
00318       for ( n=0; n<N_eig; n++ )
00319       {
00320         eig_store[n]->CopyVec(eigenv[n],f_size); 
00321       }
00322     }
00323 
00324 
00325     // random guess every time; do *not* put in the old solution
00326     for(n = 0; n<N_eig; ++n)
00327     {
00328       lat.RandGaussVector(eigenv[n], 0.5, Ncb);
00329     }
00330 
00331 /*
00332     // DEBUG, dumping start vector from QCDOC to be read in QCDSP
00333     cout << "Dump DEBUGGING info...startvector.dat" << endl;
00334     int f_size = GJP.VolNodeSites() * lat.FsiteSize() * Ncb / 2;
00335     ofstream fout ( "startvector.dat");
00336     fout << "f_size=" << f_size << endl;
00337     for(n=0;n<N_eig;++n) {
00338       fout << "n=" << n << endl;
00339       for(int i=0;i<f_size;i++) {
00340         fout << setprecision(15) << ((Float*)eigenv[n])[i] << endl;
00341       }
00342       fout << endl;
00343     }
00344     fout.close();
00345     //    exit(0);
00346     //DEBUG end
00347 */
00348    
00349     //==============================================
00350     // print out mass here in case we want to
00351     // do any output from within the FeigSolv call
00352     //==============================================
00353                               
00354     if (eig_arg->fname!=0)
00355     {
00356       FILE* filep;
00357       filep=Fopen(eig_arg->fname,"a");
00358       Fprintf(filep,"mass = %g\n",(Float)eig_arg->mass);
00359       Fclose(filep); // close file
00360     }
00361          
00362     VRB.Result(cname,fname, "mass = %g\n", (Float)eig_arg->mass);
00363 
00364     // Solve for eigenvectors and eigenvalues.
00365     // Use eigenv as initial guess. Lambda is not used initially.
00366 
00367     if(Ncb==2)
00368       iter = lat.FeigSolv(eigenv, lambda, chirality, valid_eig, 
00369                         hsum, eig_arg, CNV_FRM_YES);
00370     else if(Ncb==1)
00371       iter = lat.FeigSolv(eigenv, lambda, chirality, valid_eig, 
00372                         hsum, eig_arg, CNV_FRM_NO);
00373 
00374     //------------------------------------------------------------
00375     // Solve for eigenvectors and eigenvalues.
00376     // Lambda is not used initially.
00377     // This call will return a negative value for the iteration number
00378     // if either the solver maxes out on one of the limits.
00379 #if 0
00380     iter = lat.FeigSolv(eigenv,lambda,chirality, valid_eig,
00381                         hsum, eig_arg, CNV_FRM_YES);
00382 #endif
00383    
00385     if (evalues != 0) {
00386       for (int eig=0; eig<eig_arg->N_eig; eig++) {
00387         evalues[eig][m] = lambda[eig];
00388       }
00389     }
00390 
00391     if ( iter < 0 )
00392     {
00393       FILE* filep;
00394       filep=Fopen(eig_arg->fname,"a");
00395       if ( iter == -1 )
00396       {
00397         Fprintf(filep, "maxed out in ritz\n");
00398       }
00399       else
00400       {
00401         Fprintf(filep, "maxed out for KS steps\n");
00402       }
00403       Fclose(filep);
00404     }
00405     else
00406     {   
00407       //----------------------------------------
00408       //  spatial correlations of eigen vectors
00409       //---------------------------------------
00410       
00411       if ( eig_arg->fname != 0x0 )
00412         {
00413           
00414           FILE* filep;
00415           filep=Fopen(eig_arg->fname,"a");
00416               
00417           int i_eig,j_eig;
00418               
00419           // GM5Correlation
00420               
00421           //tmp vector v1
00422           Vector* v1 = (Vector *)smalloc(cname, fname, "v1",f_size*sizeof(Float));
00423               
00424           for(i_eig=0;i_eig<N_eig;i_eig++){
00425             for(j_eig=i_eig;j_eig<N_eig;j_eig++){
00426               gamma_5((Float*)v1, 
00427                       (Float*)eigenv[j_eig], 
00428                       f_size/24);
00429               Complex cr = eigenv[i_eig]->CompDotProductGlbSum(v1,f_size);
00430               Fprintf(filep,"GM5CORR: %d %d %g %g\n",
00431                       i_eig, j_eig, (Float)cr.real(), (Float)cr.imag());
00432             }
00433           }
00434           sfree(cname,fname, "v1", v1);
00435               
00436           // Correlation with previous eigen vector
00437           if(count >0 && eig_arg->ncorr ){
00438             for(i_eig=0;i_eig<N_eig;i_eig++){
00439               for(j_eig=0;j_eig<N_eig;j_eig++){
00440                 Complex cr = eig_store[i_eig]
00441                   ->CompDotProductGlbSum(eigenv[j_eig],f_size);
00442                 Fprintf(filep,"NeibCORR: %d %d %g %g\n",
00443                         i_eig, j_eig, (Float)cr.real(), (Float)cr.imag());
00444               }
00445             }
00446           }
00447 
00448 
00449           //------------------------------------------
00450           // Print out number of iterations  and hsum
00451           //------------------------------------------
00452           
00453           int i;
00454           Fprintf(filep, "  iter = %d\n", iter);
00455           if (eig_arg->print_hsum)
00456             {
00457               for(n = 0; n < eig_arg->N_eig; ++n)
00458                 {
00459                   for(i = 0; i < hsum_len; ++i)
00460                     {
00461                       Fprintf(filep, "  hsum[%d][%d] = %g\n",n,i,
00462                               (Float)hsum[n][i]);
00463                     }
00464                 }
00465             }
00466           Fclose(filep);
00467         } // output
00468     } // solver worked
00469 
00470     // If there is another mass loop iteration ahead, we should
00471     // set the eig_arg->mass to it's next desired value
00472     if( m < n_masses - 1 ) {
00473       switch( eig_arg->pattern_kind ) {
00474       case ARRAY: 
00475         eig_arg->mass = eig_arg->Mass.Mass_val[m+1]; 
00476         break;
00477       case LIN:   
00478         eig_arg->mass += eig_arg->Mass_step; 
00479         break;
00480       case LOG:   
00481         eig_arg->mass *= eig_arg->Mass_step; 
00482         break;
00483       }
00484     }
00485     count++;
00486   } // mass loop
00487 
00488   //==============================
00489   // deallocate eigenvalue store
00490   //==============================
00491   
00492   if ( eig_arg->ncorr )
00493     {
00494       for(n = 0; n < N_eig; ++n)
00495         {
00496           sfree(cname,fname,"eig_store[n]",eig_store[n]);
00497         }
00498       sfree(cname,fname,"eig_store",eig_store);
00499     }
00500   time +=dclock();
00501   print_flops(cname,fname,0,time);
00502 
00503 }
00504 
00505 CPS_END_NAMESPACE

Generated on Sat Oct 10 14:11:16 2009 for Columbia Physics System by  doxygen 1.3.9.1