Allink  v0.1
MatematicaSign.cpp
00001 //#include "../include/Matematica.h"
00002 #include <Matematica.h>
00003 
00004 #ifdef __GSL__
00005 #include <gsl/gsl_randist.h>
00006 double Matematica::Casuale(){
00007   return gsl_rng_uniform(rng);
00008 }
00009 bool Matematica::InizializzaGaussiano(double Scarto,int N){
00010   return 0;
00011 }
00012 double Matematica::Gaussiano(double Media,double Scarto){//Gia inizializzato
00013   return Media + gsl_ran_gaussian(rng,Scarto);
00014 }
00015 #else
00016 bool Matematica::InizializzaGaussiano(double Scarto,int N){
00017   zigset(86947731);
00018   return 0;
00019 }
00023 double Matematica::Gaussiano(double Media,double Scarto){
00024   double Rand = genrand_real1() ;
00025   double Length = -log( Rand ) ;
00026   double Theta = 2. * M_PI * genrand_real2() ;
00027   double kdX = sqrt( 2. * Length ) * cos( Theta ) ;
00028   return   Scarto * kdX + Media ;
00029   return  RandomGaussian(Media,Scarto);
00030 }
00031 double Matematica::Casuale(){
00032   return genrand_real2();
00033   return RandomUniform();
00034   int IA=16807,IM=2147483647,IQ=127773,IR=2836,NDIV=1+(IM-1)/NTAB,kcas,jcas;
00035   double AM,EPS,RNMX;
00036   EPS=1.7*pow(10.,-7.);
00037   RNMX=1.-EPS;
00038   AM=1./IM;
00039   static int iv[NTAB];
00040   static int iy=10;
00041   static int seme = 2351653;
00042   //  printf("%d,%d\n",seme,iy);
00043   if(seme<=0 || iy==0){
00044     seme = -seme>1 ? -seme : 1;
00045     for(jcas=NTAB+8;jcas>=1;jcas--){
00046       kcas=seme/IQ;
00047       seme=IA*(seme-kcas*IQ)-IR*kcas;
00048       if(seme<=0) seme += IM;
00049       if(jcas<=NTAB) iv[jcas]=seme;
00050     }
00051     iy = iv[1];
00052   }
00053   kcas=seme/IQ;
00054   seme=IA*(seme-kcas*IQ)-IR*kcas;
00055   if(seme<=0) seme+=IM;
00056   jcas=1+iy/NDIV;
00057   iy=iv[jcas];
00058   iv[jcas]=seme;
00059   double casuale=AM*iy < RNMX ? AM*iy : RNMX;
00060   //  fprintf(CONTROLLA,"%f\n",casuale);
00061   return casuale;
00062 }
00063 #endif
00064 double Matematica::RandDiscrProb(double *Prob,int NBin){
00065   double Ran = Casuale();
00066   double InvNBin = 1./(double)NBin;
00067   int j = 0;
00068   for(int i=0;i<NBin-1;i++){
00069     if(Ran > Prob[i] && Ran <= Prob[i+1]){
00070       j = i;
00071       break;
00072     }
00073   }
00074   double xi = Ran - floor(Ran*NBin)*InvNBin;
00075   double m = (Prob[j+1] - Prob[j])*NBin;
00076   double y = j*InvNBin + m*xi;
00077   return y;
00078 }
00079 #ifdef USE_FFTW
00080 void Matematica::Spettro(double *st,double *sw,int NMax){//N=int^2
00081   //printf("using fftw\n");
00082   fftw_complex *uscita = (fftw_complex *) fftw_malloc( sizeof(fftw_complex)*(NMax) );
00083   fftw_complex *entrata = (fftw_complex *) fftw_malloc( sizeof(fftw_complex)*(NMax) );
00084   fftw_plan p;
00085   for(int i=0;i<NMax;i++){
00086     entrata[0][i] = st[i];
00087   }
00088   //for(int i=0;i<NMax;i++)printf("%d %lf \n",i,st[i]);  
00089   //p = fftw_plan_dft_r2c_1d(NMax,st,uscita,FFTW_FORWARD);
00090   p = fftw_plan_dft_1d(NMax,entrata,uscita,FFTW_FORWARD,FFTW_ESTIMATE);
00091   fftw_execute(p);
00092   for(int i=0;i<NMax;i++){
00093     sw[i] = QUAD(uscita[i][0])+QUAD(uscita[i][1]);
00094   }
00095   //for(int i=0;i<NMax;i++) printf("%d %lf %lf\n",i,st[i],sw[i]);  
00096   fftw_destroy_plan(p);
00097   fftw_free(entrata);
00098   fftw_free(uscita);
00099 }
00100 void Matematica::Spettro2d(double *st,double *sw,int NMax){//N=int^2
00101   //printf("using fftw\n");
00102   fftw_complex *uscita = (fftw_complex *) fftw_malloc( sizeof(fftw_complex)*(NMax*NMax) );
00103   fftw_plan p = fftw_plan_dft_r2c_2d(NMax,NMax,st,uscita,FFTW_MEASURE);
00104   fftw_execute(p);
00105   for(int i=0;i<NMax;i++){
00106     sw[i] = 0.;
00107     for(int j=0;j<NMax;j++){
00108       sw[i*NMax+j] = SQR(uscita[i*NMax+j][0])+SQR(uscita[i*NMax+j][0]);
00109     }
00110   }
00111   fftw_destroy_plan(p);
00112   fftw_free(uscita);
00113 }
00114 void Matematica::Spettro2d(double *st,double **sw,int NMax){//N=int^2
00115   //printf("using fftw\n");
00116   double NMaxInv = 1./(double)NMax;
00117   int NHalf = (int)(NMax/2.);
00118   fftw_plan p;
00119   //fftw_complex *uscita = (fftw_complex *) fftw_malloc( sizeof(fftw_complex)*(NMax*NMax) );
00120   fftw_complex *uscita = (fftw_complex *)calloc(NMax*NMax,sizeof(fftw_complex));
00121   //for(int i=0;i<NMax;i++)for(int j=0;j<NMax;j++)printf("%d %d %lf \n",i,j,st[i*NMax+j]);
00122   p = fftw_plan_dft_r2c_2d(NMax,NMax,st,uscita,FFTW_MEASURE);
00123   fftw_execute(p);
00124   for(int i=0;i<NMax;i++){
00125     for(int j=0;j<NMax;j++){
00126       sw[i][j] = QUAD(uscita[0][i*NMax+j])+QUAD(uscita[1][i*NMax+j]);
00127       sw[i][j] *= QUAD(NMaxInv);
00128       //printf("%d %d %lf %lf %lf\n",i,j,st[i*NMax+j],uscita[0][i*NMax+j],uscita[1][i*NMax+j]);
00129     }
00130   }
00131   fftw_destroy_plan(p);
00132   //fftw_free(uscita);
00133   free(uscita);
00134 }
00135 #else
00136 void Matematica::Spettro(double *st,double *sw,int NMax){//N=int^2
00137   double Re1=0.,Im1=0.,Re2=0.,Im2=0.;
00138   double FMass=(double)NMax/DUE_PI;
00139   double dNMax = 1./(double)NMax;
00140   for(int j=0;j<NMax;j++){
00141     Re1=0.;Re2=0.;Im1=0.;Im2=0.;
00142     for(int i=0;i<NMax;i++){
00143       Re1+=st[i]*cos(DUE_PI*dNMax*(i)*j);
00144       Im1-=st[i]*sin(DUE_PI*dNMax*(i)*j);
00145     }
00146     sw[j]= sqrt(QUAD((Re1+Re2))*dNMax+QUAD((Im1+Im2))*dNMax);
00147   }
00148   // double Parseval1 = 0.;
00149   // double Parseval2 = 0.;
00150   // for(int j=0;j<NMax;j++){
00151   //   Parseval1 += QUAD(st[j]);
00152   //   Parseval2 += sw[j];
00153   // }
00154   // printf("Parseval %lf=%lf\n",Parseval1,Parseval2);
00155 }
00156 void Matematica::Spettro2d(double *st,double *sw,int NMax){
00157   printf("dft\n");
00158   double dNMax = 1./(double)NMax;
00159   int NHalf = (int)(NMax/2.);
00160   for(int kx=-NMax/2;kx<NMax/2;kx++){
00161     double qx = kx*dNMax;
00162     for(int ky=-NMax/2;ky<NMax/2;ky++){
00163       double qy = ky*dNMax;
00164       double Re2=0.,Im2=0.;
00165       double Re1=0.,Im1=0.;
00166       for(int lx=0;lx<NMax;lx++){
00167    for(int ly=0;ly<NMax;ly++){
00168      double Arg = 2.*M_PI*(lx*kx + ly*ky);
00169      double cy = cos(Arg);
00170      double sy = sin(Arg);
00171      Re1 += st[lx*NMax+ly]*cy;
00172      Im1 += st[lx*NMax+ly]*sy;
00173    }
00174       }
00175       int kkx = kx + NMax/2;
00176       int kky = ky + NMax/2;
00177       sw[kkx*NMax+kky] = SQR(Re1*dNMax) + SQR(Im1*dNMax);
00178     }
00179   }
00180 }
00181 // void Matematica::Spettro2d(double *st,double *sw,int NMax){
00182 //   double dNMax = 1./(double)NMax;
00183 //   int NHalf = (int)(NMax/2.);
00184 //   for(int kx=0;kx<NMax;kx++){
00185 //     for(int ky=0;ky<NMax;ky++){
00186 //       double Re2=0.,Im2=0.;
00187 //       for(int lx=0;lx<NMax;lx++){
00188 //    double cx = cos(kx*lx*dNMax*DUE_PI);
00189 //    double sx = sin(kx*lx*dNMax*DUE_PI);
00190 //    double Re1=0.,Im1=0.;
00191 //    for(int ly=0;ly<NMax;ly++){
00192 //      double cy = cos(ky*ly*dNMax*DUE_PI);
00193 //      double sy = sin(ky*ly*dNMax*DUE_PI);
00194 //      Re1 += st[lx*NMax + ly]*cy;
00195 //      Im1 += st[lx*NMax + ly]*sy;
00196 //    }
00197 //    Re2 += cx*Re1 - sx*Im1;
00198 //    Im2 -= sx*Re1 + cx*Im1;
00199 //       }
00200 //       sw[kx*NMax+ky] = SQR(Re2*dNMax) + SQR(Im2*dNMax);
00201 //     }
00202 //   }
00203 // }
00204 void Matematica::Spettro2d(double *st,double **sw,int NMax){
00205   printf("No fftw\n");
00206   double dNMax = 1./(double)NMax;
00207   int NHalf = (int)(NMax/2.);
00208   for(int l=0;l<NMax;l++){
00209     for(int k=0;k<NMax;k++){
00210       double Re1=0.,Im1=0.,Re2=0.,Im2=0.;
00211       for(int n=0;n<NMax;n++){
00212    double Cosn = cos(DUE_PI*l*n*dNMax);
00213    double Sinn = sin(DUE_PI*l*n*dNMax);
00214    for(int m=0;m<NMax;m++){
00215      double Arg = DUE_PI*((l-NHalf)*n*dNMax + (k-NHalf)*m*dNMax);
00216      // Re1 += cos(Arg)*st[n*NMax + m];
00217      // Im2 += sin(Arg)*st[n*NMax + m];
00218      Re1 += Cosn*cos(DUE_PI*k*m*dNMax)*st[n*NMax + m];
00219      Re2 -= Sinn*sin(DUE_PI*k*m*dNMax)*st[n*NMax + m];
00220      Im1 += Cosn*sin(DUE_PI*k*m*dNMax)*st[n*NMax + m];
00221      Im2 += Sinn*cos(DUE_PI*k*m*dNMax)*st[n*NMax + m];
00222    }
00223       }
00224       sw[l][k] = QUAD((Re1+Re2)*dNMax*dNMax) + QUAD((Im1+Im2)*dNMax*dNMax);
00225     }
00226   }
00227   // double Parseval1 = 0.;
00228   // double Parseval2 = 0.;
00229   //  for(int v=0;v<NMax;v++){
00230   //   for(int vv=0;vv<NMax;vv++){
00231   //     Parseval1 += QUAD(sw[v][vv]);
00232   //     Parseval2 += QUAD(st[v*NMax+vv]);
00233   //   }
00234   // }
00235   //  printf("Parseval %lf=%lf\n",Parseval1,Parseval2);
00236 }
00237 #endif
00238 void Matematica::Radice(double *st,double *sw,int N){
00239   for(int j=0;j<N;j++){
00240     if(st[j] > 0.)
00241       sw[j] = sqrt(st[j]);
00242     else 
00243       sw[j] = sqrt(-st[j]);
00244   }
00245 }
00246 void Matematica::Autocor(double *st,double *sAutocor,int NMax){
00247   for(int i=0;i<NMax;i++){
00248     sAutocor[i] = 0.;
00249     for(int j=0,k=0;j<NMax;j++){
00250       k = i-j;
00251       if(k<0)
00252    k = NMax - i + j;
00253       sAutocor[i] += (double)(st[k]*st[j]);
00254     }
00255     sAutocor[i] /= (double)(NMax);
00256   }
00257 }
00258 void Matematica::MediaMobile(double *st,int NMax,double *sw,int Parti){
00259   if(Parti <= 1){
00260     return;
00261   }
00262   double PartiInv = 1./(double)Parti;
00263   int Nw = (int) (NMax/(double)Parti);
00264   for(int i=0;i<Nw;i++)
00265     sw[i] = 0.;
00266   for(int i=0,j=0;i<NMax;i++){
00267     sw[j] += st[i];
00268     if( (i%Parti)==0 ){
00269       sw[j] *= PartiInv;
00270       j++;
00271     }
00272   }
00273 }
00274 int Matematica::MediaMobile(double *st,int NMax,double *sw,double *sErr,int NParti){
00275   if(NParti <= 0 ){
00276     return NParti;
00277   }
00278   int Nw = (int) (NMax/(double)NParti);
00279   double InvNParti = 1./(double)NParti;
00280   for(int i=0;i<Nw;i++){
00281     sw[i] = 0.;
00282     sErr[i] = 0.;
00283   }
00284   for(int i=0,j=0;i<NMax;i++){
00285     sw[j] += st[i];
00286     sErr[j] += SQR((st[i]));
00287     if( ((i+1)%NParti)==0 ){
00288       sw[j] *= InvNParti;
00289       sErr[j] = sqrt( (sErr[j] - SQR(sw[j])*NParti)*InvNParti );
00290       j++;
00291       if(j==Nw) return Nw;
00292     }
00293   }
00294   return Nw;
00295 }
00296 int Matematica::CorrelaDuePunti(double *st,int NMax,double *sw,int Punti){
00297   int PuntiMass = NMax - Punti;
00298   for(int i=0;i<PuntiMass;i++){
00299     sw[i] = (st[i] + st[i+Punti]) / 2.;
00300   }
00301   return PuntiMass;
00302 }
00303 void Matematica::Autosimilarita(double *st,int NMax,double *sw,int Potenze){
00304   for(int j=0;j<Potenze;j++){
00305     sw[j] = 0.;
00306   }
00307   for(int i=0;i<NMax;i++){
00308     double Temp = 1;
00309     for(int j=0;j<Potenze;j++){
00310       Temp *= st[i];
00311       sw[j] += Temp;
00312     }
00313   }
00314   for(int j = 0;j<Potenze;j++){
00315     sw[j] = log10(POS(sw[j]))/log10((double)NMax);
00316     //    printf("sw[%d] %f\n",j,sw[j]);
00317   }
00318 }
00319 int Matematica::Normalizza(double *st,double *sw,int NMax){
00320   double yMass=st[0];
00321   double yMin = st[0];
00322   double Media=0.;
00323   int Zeri=0;
00324   int Campioni=0;
00325   for(int i = 1;i<NMax;i++){
00326     if(yMin > st[i])
00327       yMin = st[i];
00328     if(yMass< st[i])
00329       yMass = st[i];
00330     Media += st[i];
00331   }
00332   Media /= (double)NMax;
00333   for(int i=0;i<NMax;i++){
00334     sw[i] = (st[i]-yMin)/(yMass-yMin);
00335     if(st[i] > Media && st[i-1] < Media)
00336       Zeri++;
00337   }
00338   Campioni = (int)(NMax/(double)Zeri);
00339   return Campioni;
00340 }
00341 int Matematica::Normalizza(double *st,int NMax){
00342   double yMass=st[0];
00343   double yMin = st[0];
00344   double Media=0.;
00345   int Zeri=0;
00346   int Campioni=0;
00347   for(int i = 1;i<NMax;i++){
00348     if(yMin > st[i])
00349       yMin = st[i];
00350     if(yMass< st[i])
00351       yMass = st[i];
00352     Media += st[i];
00353   }
00354   Media /= (double)NMax;
00355   for(int i=0;i<NMax;i++){
00356     st[i] = (st[i]-yMin)/(yMass-yMin);
00357     if(st[i] > Media && st[i-1] < Media)
00358       Zeri++;
00359   }
00360   Campioni = (int)(NMax/(double)Zeri);
00361   return Campioni;
00362 }
00363 int Matematica::NormalizeArea(double *st,int NMax){
00364   double Area = 0.;
00365   for(int i = 0;i<NMax;i++){
00366     Area += st[i];
00367   }
00368   for(int i=0;i<NMax;i++){
00369     st[i] /= Area;
00370   }
00371   return 0;
00372 }
00373 MOMENTI Matematica::Distribuzione(const double *st,int NMax){
00374   MOMENTI m1; m1.Uno=0.; m1.Due=0.; m1.Tre=0.;m1.Delta=0.;m1.Num=0;
00375   m1.Min = st[0];
00376   m1.Max = st[0];
00377   for(int i=0;i<NMax;i++){
00378     m1.Uno += st[i];
00379     if(st[i] < m1.Min) m1.Min = st[i];
00380     if(st[i] > m1.Max) m1.Max = st[i];
00381   }
00382   m1.Uno /= (double)(NMax);
00383   m1.Delta = (m1.Max-m1.Min);
00384   for(int i=0;i<NMax;i++){
00385     m1.Due+=QUAD((st[i]-m1.Uno));
00386     m1.Tre+=QUAD((st[i]-m1.Uno))*(st[i]-m1.Uno);
00387     m1.Num++;
00388   }
00389   m1.Due=sqrt(m1.Due/(double)(NMax-1));
00390   m1.Tre = pow(m1.Tre / (double)(NMax - 2),.33333);
00391   return m1;
00392 }
00393 MOMENTI Matematica::DistrErr(const double *st,int NMax,double *Distr,double *Err,int NBin,double *Confine,int IfNorm){
00394   MOMENTI m1 = Distribuzione(st,NMax,Distr,NBin,Confine,IfNorm);
00395   for(int i=0;i<NBin;i++)
00396     Err[i] = 0.;
00397   double Add = 1./(double)NMax;
00398   for(int i=0;i<NMax;i++){
00399     int j = (int)((st[i]-Confine[0])/(Confine[1]-Confine[0])*NBin);
00400     if(j >= NBin || j < 0) continue;
00401     Err[j] += Add;
00402   }
00403   for(int i=0;i<NBin;i++){
00404     Err[i] *= Distr[i];
00405   }
00406   return m1;
00407 }
00408 MOMENTI Matematica::Distribuzione(const double *st,int NMax,double *Distr,int NBin,double *Confine,int IfNorm){
00409   MOMENTI m1; m1.Uno=0.; m1.Due=0.; m1.Tre=0.;m1.Delta=0.;m1.Num=0;
00410   m1.Min = Confine[0];
00411   m1.Max = Confine[1];
00412   for(int i=0;i<NBin;i++) Distr[i]=0.;
00413   for(int i=0;i<NMax;i++) m1.Uno += st[i];
00414   m1.Uno/=(double)(NMax);
00415   m1.Delta = (m1.Max - m1.Min)/(double)NBin;
00416   double Add = !IfNorm ? 1. : 1./(double)NMax;
00417   for(int i=0;i<NMax;i++){
00418     m1.Due += QUAD(st[i]-m1.Uno);
00419     m1.Tre += m1.Due*(st[i]-m1.Uno);
00420     int j = (int)((st[i]-Confine[0])/(Confine[1]-Confine[0])*NBin);
00421     if(j >= NBin || j < 0) continue;
00422     Distr[j] += Add;
00423     m1.Num++;
00424   }
00425   m1.yMin = Distr[0];
00426   m1.yMax = Distr[0];
00427   for(int v=0;v<NBin;v++){
00428     if(m1.yMin > Distr[v]) m1.yMin = Distr[v];
00429     if(m1.yMax < Distr[v]) m1.yMax = Distr[v];
00430   }
00431   m1.Due=sqrt(m1.Due/((double)(NMax-1)));
00432   m1.Tre = pow(m1.Tre,.33333) / (double)(NMax - 2);
00433   //   printf("[-]    Massimo %g m1.Minimo %g Media %g          [-] \n[-]    Scarto %g Terzo %g Deltax/3 %g      [-]\n",m1.Massimo,m1.Minimo,m1.Uno,m1.Due,m1.Tre,(m1.Massimo-m1.Minimo)/6.);
00434   return m1;
00435 }
00436 MOMENTI Matematica::Distribuzione(const double *st,int NMax,double *Distr,int NBin,int IfNorm){
00437   MOMENTI m1; m1.Uno=0.; m1.Due=0.; m1.Tre=0.;m1.Delta=0.;m1.Num=0;
00438   m1.Min = st[0];
00439   m1.Max = st[0];
00440   double Sum2 = 0.;
00441   double Sum3 = 0.;
00442   for(int i=0;i<NBin;i++) Distr[i] = 0.;
00443   for(int i=0;i<NMax;i++){
00444     if(st[i] < m1.Min) m1.Min = st[i];
00445     if(st[i] > m1.Max) m1.Max = st[i];
00446     m1.Uno += st[i];
00447     Sum2 += QUAD(st[i]);
00448     Sum3 += st[i]*st[i]*st[i];
00449   }
00450   double Add = !IfNorm ? 1. : 1./(double)NMax;
00451   m1.Delta = (m1.Max-m1.Min)/(double)NBin;
00452   for(int i=0;i<NMax;i++){
00453     int j = (int)((st[i]-m1.Min)/(m1.Max-m1.Min)*NBin);
00454     if(j >= NBin) continue;
00455     Distr[j] += Add;
00456     m1.Num++;
00457   }
00458   m1.yMin = Distr[0];
00459   m1.yMax = Distr[0];
00460   for(int v=0;v<NBin;v++){
00461     if(m1.yMin > Distr[v]) m1.yMin = Distr[v];
00462     if(m1.yMax < Distr[v]) m1.yMax = Distr[v];
00463   }
00464   m1.Uno/=(double)(NMax);
00465   m1.Due = sqrt((Sum2 - QUAD(m1.Uno)*NMax)/((double)NMax-1.));
00466   m1.Tre = Sum3-3.*Sum2*m1.Uno+3.*NMax*QUAD(m1.Uno)-NMax*m1.Uno;
00467   m1.Tre = pow( m1.Tre , 1./3.)/(double)(NMax-1);
00468   //   printf("[-]    Massimo %g m1.Minimo %g Media %g          [-] \n[-]    Scarto %g Terzo %g Deltax/3 %g      [-]\n",m1.Massimo,m1.Minimo,m1.Uno,m1.Due,m1.Tre,(m1.Massimo-m1.Minimo)/6.);
00469   return m1;
00470 }
00471 void Matematica::DistrSample(double *Px,double *Py,int NMax,double **Distr,int NBin,const int NSample,int IfNorm,double *yBorder){
00472   double xBorder[2];
00473   double yDelta;
00474   double Norm[NSample];
00475   xBorder[1] = Px[0];
00476   xBorder[0] = Px[0];
00477   for(int n=0;n<NMax;n++){
00478     if(xBorder[1] < Px[n]) xBorder[1] = Px[n];
00479     if(xBorder[0] > Px[n]) xBorder[0] = Px[n];
00480   }
00481   double Dx = (xBorder[1] - xBorder[0]) > 0. ? 1./(xBorder[1] - xBorder[0]) : 1.;
00482   if(1==0){//search for borders
00483     for(int s=0;s<NSample;s++){
00484       yBorder[0] = Py[s];
00485       yBorder[1] = Py[s];
00486     }
00487     for(int n=0;n<NMax;n++){
00488       int sx = (int)((Px[n]-xBorder[0])*Dx*NSample);
00489       if(sx < 0 || sx >= NSample) continue;
00490       if(yBorder[0] > Py[n]) yBorder[0] = Py[n];
00491       if(yBorder[1] < Py[n]) yBorder[1] = Py[n];    
00492     }
00493   }
00494   yDelta = yBorder[1] - yBorder[0] > 0. ? 1./(yBorder[1] - yBorder[0]) : 1.;
00495   for(int n=0;n<NMax;n++){
00496     int sx = (int)((Px[n]-xBorder[0])*Dx*NSample);
00497     if(sx < 0 || sx >= NSample) continue;
00498     int by = (int)((Py[n]-yBorder[0])*yDelta*NBin);
00499     if(by < 0 || by >= NBin) continue;
00500     Distr[sx][by] += 1.;
00501   }
00502   if(IfNorm){
00503     for(int sx=0;sx<NSample;sx++){
00504       Norm[sx] = 0.;
00505       for(int by=0;by<NBin;by++){
00506    Norm[sx] += Distr[sx][by];
00507       }
00508     }
00509     for(int sx=0;sx<NSample;sx++){
00510       Norm[sx] = Norm[sx] > 1. ? 1./Norm[sx] : 1.;
00511       for(int by=0;by<NBin;by++){
00512    Distr[sx][by] *= Norm[sx];
00513       }
00514     }
00515   }
00516 }
00517 MOMENTI Matematica::DistribuzioneGauss(const double *st,int NMax,double *Distr,double *dInt,int NBin,int IfNorm){
00518   MOMENTI m1;
00519   m1 = Distribuzione(st,NMax,Distr,NBin,IfNorm);
00520   m1.Chi = 0.;
00521   for(int v=0;v<NBin;v++){
00522     dInt[v] = NMax*Gauss( m1.Uno , m1.Due , (v)*m1.Delta + m1.Min)*m1.Delta;
00523     m1.Chi += QUAD( (Distr[v] - dInt[v])/m1.Due);
00524   }
00525   m1.Chi /= NBin-2;
00526   return m1;
00527 }
00528 MOMENTI Matematica::DistribuzioneMaxwell(const double *st,int NMax,double *Distr,double *dInt,int NBin,int IfNorm){
00529   MOMENTI m1;
00530   m1 = Distribuzione(st,NMax,Distr,NBin,IfNorm);
00531   m1.Chi = 0.;
00532   for(int i=0;i<NBin;i++){
00533     dInt[i] =  2*DUE_PI*QUAD((i*m1.Delta + m1.Min))*NMax*Gauss( m1.Uno , m1.Due , i*m1.Delta + m1.Min)*m1.Delta;
00534     m1.Chi += QUAD( Distr[i] - dInt[i]);
00535   }
00536   m1.Chi /= NBin-2;
00537   return m1;
00538 }
00539 MOMENTI Matematica::WeightAverage(const double *sx,const double *sy,int NMax){
00540   MOMENTI m1; m1.Uno=0.; m1.Due=0.; m1.Tre=0.;m1.Delta=0.;m1.Num=0;
00541   m1.Min = sx[0];
00542   m1.Max = sx[0];
00543   double TotWei = 0.;
00544   for(int i=0;i<NMax;i++){
00545     if(sx[i] < m1.Min) m1.Min = sx[i];
00546     if(sx[i] > m1.Max) m1.Max = sx[i];
00547     m1.Uno += sx[i]*sy[i];
00548     TotWei += sy[i];
00549     m1.Due += sy[i] > 0. ? 1./sy[i] : 0.;
00550   }
00551   m1.Uno /= TotWei;
00552   m1.Due = sqrt(1./m1.Due);
00553   m1.Delta = (m1.Max-m1.Min);
00554   return m1;
00555 }
00556 void Matematica::WeightHisto(double **hist,double *Border,int NBin,int NHisto,double tolerance,double *OrPos,double *kSpring){
00557   if(1==0) {
00558     cout<<"Usage:\n\n";
00559     cout<<"do_wham_c <TEMPERATURE> <MIN> <MAX> <BINS> <TOLERANCE> <OUTPUT> <INPUT1> <INPUT2> ....\n\n";
00560     cout<<"TEMPERATURE\t\tTemperature that simulations were performed at\n";
00561     cout<<"MIN\t\t\tMinimum value used in histogram. All histograms must have been computed with matching value.\n";
00562     cout<<"MAX\t\t\tMaximum value used in histogram. All histograms must have been computed with matching value.\n";
00563     cout<<"NBIN\t\t\tNumber of NBin in histogram. All histograms must have been computed with matching value.\n";
00564     cout<<"TOLERANCE\t\tTolerance value used to determine convergence. Value of 0.00001 seems to work fine.\n";
00565     cout<<"OUTPUT\t\t\tName of output file.\n";
00566     cout<<"INPUT\t\t\tNames of input files. These are histogram files produced from the .pdo files using make_histo.pl.\n";
00567     cout<<endl;
00568   }
00569   double temperature = 1.;
00570   double min         = Border[0];
00571   double max         = Border[1];
00572   double RT = temperature * 8.314472e-3;
00573   ofstream output("WeightHistoAnal.dat");
00574   double* F      = new double[NHisto];
00575   double* old_F  = new double[NHisto];
00576   double* result = new double[NBin];
00577   double*   N    = new double[NHisto];
00578   double* energy = new double[NBin];
00579   double * numerator = new double[NBin];
00580   double ** expU  = new double *[NHisto];
00581   double ** NexpU = new double *[NHisto];
00582   //filling the exponential and normalizing factor
00583   for(int h = 0;h < NHisto;++h) {
00584     F[h] = 1.0;
00585     old_F[h] = 0.0;
00586     N[h] = 0.0;
00587     expU[h]  = new double[NBin];
00588     NexpU[h] = new double[NBin];
00589     for(int i = 0; i < NBin; ++i) {
00590       N[h] += hist[h][i];
00591       double pos = (i + 0.5)/NBin * (max - min) + min;
00592       expU[h][i] = exp(-(0.5 * kSpring[h] * (pos - OrPos[h]) * (pos - OrPos[h]))/RT);
00593     }
00594     for(int i=0; i < NBin; ++i) {
00595       NexpU[h][i] = N[h] * expU[h][i];
00596     }
00597   }
00598   for(int bin = 0; bin < NBin; ++bin) {
00599     result[bin] = 0.0;
00600   }
00601   double d_max = 0.;
00602   for(int bin = 0; bin < NBin; ++bin) {
00603     numerator[bin] = 0.0;
00604     for(int file = 0; file < NHisto; ++file) {
00605       numerator[bin] += hist[file][bin];
00606     }
00607   }
00608   cerr<<"Done loading histograms. Doing WHAM."<<endl;
00609   int count = 0;
00610   int IfContinue = 1;
00611   do {
00612     d_max = 0.;
00613     for(int bin=0; bin < NBin; ++bin) {
00614       double denom = 0.0;
00615       for(int file = 0; file < NHisto; ++file) {
00616    denom += NexpU[file][bin] / F[file];
00617       }
00618       //printf("%lf %lf %lf\n",denom,numerator[bin],result[bin]);
00619       if(denom > 1.e9) IfContinue = 0;
00620       denom = denom <= 0.0000001 ? 1. : denom;
00621       result[bin] = numerator[bin] / denom;
00622     }
00623     double norm = 0.0;
00624     for(int bin=0; bin < NBin; ++bin) norm += result[bin];
00625     norm = norm > 0. ? norm : 1.;
00626     for(int bin=0; bin < NBin; ++bin) result[bin] /= norm;
00627     for(int file = 0; file < NHisto; ++file) {
00628       double Z = 0.;
00629       for (int bin = 0; bin < NBin; ++bin){
00630    Z += result[bin] * expU[file][bin];
00631       }
00632       if(isnan(Z)){IfContinue = 0;break;}
00633       if(isinf(Z)){IfContinue = 0;break;}
00634       if(Z <= 1.e-9){IfContinue = 0;break;}
00635       double dZ = (max - min)/(double)NBin;
00636       Z = Z * dZ;
00637       old_F[file] = F[file];
00638       //printf("%d %d %lf %lf\n",count,file,F[file],Z);
00639       F[file] = Z;
00640     }
00641     if(!IfContinue) break;
00642     double temp = F[0];
00643     for(int file = 0; file < NHisto; ++file) {
00644       temp = RT * fabs(log(F[file]) - log(old_F[file]));
00645       if(temp > d_max)
00646    d_max = temp;
00647     }
00648     if(!(count % 1000)) 
00649       cerr<<"Step: "<<count<<"\tTolerance: "<<d_max<<endl;
00650     ++count;
00651     if(count == 2) break;
00652   } while(d_max > tolerance);
00653   for(int bin = 0; bin < NBin; ++bin) {
00654     energy[bin] = 0.0;
00655   }
00656   for(int bin = 0; bin < NBin; ++bin) {
00657     double res = result[bin] > 0. ? log(result[bin]) : 0.;
00658     energy[bin] = -RT*res;
00659     double pos = (double)bin / NBin * (max - min) + min;
00660     output << pos << "  " << result[bin] << "  " << energy[bin] << endl;
00661   }
00662   output.close();
00663   delete [] F;
00664   delete [] old_F;
00665   delete [] result;
00666   delete [] N;
00667   delete [] energy;
00668   delete [] numerator;
00669   for(int current = 0;current < NHisto;++current) {
00670     delete [] expU[current];
00671     delete [] NexpU[current];
00672   }
00673   delete [] expU;
00674   delete [] NexpU;
00675 }
00676 void Matematica::Sort(double *Sign,int NMax){
00677   for(int i=0;i<NMax;i++){
00678     for(int j=i;j>0;j--){
00679       if(Sign[j] < Sign[j-1])
00680    Swap(j,j-1,Sign);
00681       else 
00682    break;
00683     }
00684   }
00685 }
00686 void Matematica::Swap(int i, int j,double *Sign){
00687   double Temp = Sign[j];
00688   Sign[j] = Sign[i];
00689   Sign[i] = Temp;
00690 }
00691 void Matematica::Swap(double *s,int si,double *t,int ti,const int NDim){
00692   double Temp[NDim];
00693   for(int d=0;d<NDim;d++){
00694     Temp[d] = s[si*NDim+d];
00695     s[si*NDim+d] = t[ti*NDim+d];
00696     t[ti*NDim+d] = Temp[d];
00697   }
00698 }
00699 void Matematica::Sort(int *Sign,int NMax){
00700   for(int i=0;i<NMax;i++){
00701     for(int j=i;j>0;j--){
00702       if(Sign[j] < Sign[j-1])
00703    Swap(j,j-1,Sign);
00704       else 
00705    break;
00706     }
00707   }
00708 }
00709 void Matematica::Swap(int i, int j,int *Sign){
00710   int Temp = Sign[j];
00711   Sign[j] = Sign[i];
00712   Sign[i] = Temp;
00713 }
00714 void Matematica::ConvWeight(double *st,int NMax,double *sw,int *WIndex,int NWeight){
00715   double *st1 = (double *)calloc(NMax,sizeof(double));
00716   for(int n=0;n<NMax;n++){
00717     st1[n] = st[n];
00718   }
00719   for(int n=0;n<NMax;n++){
00720     st[n] = 0;
00721     if(n+WIndex[0] < 0 || n+WIndex[NWeight-1] >= NMax){
00722       st[n] = st1[n];
00723       continue;
00724     }
00725     for(int w=0;w<NWeight;w++){
00726       st[n] += sw[w]*st1[n+WIndex[w]];
00727     }
00728   }
00729   free(st1);
00730 }
00731 void Matematica::FillWeightGauss(double *st,int *WIndex,int NWeight,double CutOff,double Sigma){
00732   int Half = NWeight/2;
00733   double Norm = 0.;
00734   for(int w=0;w<NWeight;w++){
00735     WIndex[w] = w-Half;
00736     double x = CutOff*(w-Half)/(double)NWeight;
00737     double r2 = SQR(x);
00738     double Gauss = exp(-r2*.5/SQR(Sigma));
00739     st[w] = Gauss;
00740     Norm += Gauss;
00741   }
00742   for(int w=0;w<NWeight;w++){
00743     st[w] /= Norm;
00744   }
00745 }
00746 void Matematica::ExecCommand(double *st,double *sw,int NMax,char *cmd){
00747   for(int i=0;i<NMax;i++){
00748     sw[i] = ExecFormula(st[i],1.,cmd);
00749   }
00750 }
00751 double Matematica::ExecFormula(double x,double y,char *cmd){
00752   if(strlen(cmd) == 0) return x;
00753   const int NOp = 20;
00754   int PosOp[NOp];
00755   int PosPar[NOp];
00756   int PosNum[2*NOp];
00757   PosNum[0] = 0;
00758   int nOp = 1;
00759   int Comm[NOp];
00760   double Numb;
00761   char *cPart = cmd;
00762   for(int i=0;i<NOp;i++){
00763     cPart = strpbrk(cPart+1,"*/^+-");
00764     if(cPart == NULL) break;
00765     Comm[i] = (int)*cPart;
00766     PosOp[i] = cPart-cmd+1;
00767     PosNum[nOp] = PosOp[i];
00768     nOp++;
00769   }
00770   Sort(PosNum,nOp);
00771   PosNum[nOp++] = strlen(cmd);
00772   double Res = 0.;
00773   for(int i=0;i<nOp-1;i++){
00774     if( *(cmd+PosNum[i]) == 'x'){
00775       Numb = x;
00776     }
00777     if( *(cmd+PosNum[i]) == 'y'){
00778       Numb = y;
00779     }
00780     else
00781       sscanf(cmd+PosNum[i],"%lf",&Numb);
00782     if(i == 0){ 
00783       Res = Numb;
00784       continue;
00785     }
00786     switch(Comm[i-1]){
00787     case '+':
00788       Res += Numb;
00789       break;
00790     case '-':
00791       Res -= Numb;
00792       break;
00793     case '/':
00794       Res /= Numb;
00795       break;
00796     case '*':
00797       Res *= Numb;
00798       break;
00799     }
00800     //printf("%d) %s %d %lf %lf %lf %c %lf\n",i,cmd+PosNum[i],PosNum[i],Numb,x,y,Comm[i],Res);
00801   }
00802   return Res;
00803   // cPart = cmd;
00804   // for(int i=0;i<NOp;i++){
00805   //   cPart = strpbrk(cPart+1,"()");
00806   //   if(cPart == NULL) break;
00807   //   PosPar[i] = cPart-cmd+1;
00808   //   PosNum[nOp] = PosOp[i];
00809   //   nOp++;
00810   // }
00811   // 
00812 }
00813 double Matematica::ExecFormula(double **st,int n,char *cmd){
00814   if(strlen(cmd) == 0) return st[0][n];
00815   const int NOp = 20;
00816   int PosOp[NOp];
00817   int PosPar[NOp];
00818   int PosNum[2*NOp];
00819   PosNum[0] = 0;
00820   int nOp = 1;
00821   int Comm[NOp];
00822   double Numb;
00823   char *cPart = cmd;
00824   for(int i=0;i<NOp;i++){
00825     cPart = strpbrk(cPart+1,"*/^+-");
00826     if(cPart == NULL) break;
00827     Comm[i] = (int)*cPart;
00828     PosOp[i] = cPart-cmd+1;
00829     PosNum[nOp] = PosOp[i];
00830     nOp++;
00831   }
00832   Sort(PosNum,nOp);
00833   PosNum[nOp++] = strlen(cmd);
00834   double Res = 0.;
00835   int NVar = 0;
00836   for(int i=0;i<nOp-1;i++){
00837     if( *(cmd+PosNum[i]) == 'x'){
00838       sscanf(cmd+PosNum[i]+1,"%d",&NVar);
00839       Numb = st[NVar][n];
00840     }
00841     else
00842       sscanf(cmd+PosNum[i],"%lf",&Numb);
00843     //printf("%d) %s %d %lf %lf %c\n",i,cmd+PosNum[i],PosNum[i],Numb,x,Comm[i]);
00844     if(i == 0){ 
00845       Res = Numb;
00846       continue;
00847     }
00848     switch(Comm[i-1]){
00849     case '+':
00850       Res += Numb;
00851       break;
00852     case '-':
00853       Res -= Numb;
00854       break;
00855     case '/':
00856       Res /= Numb;
00857       break;
00858     case '*':
00859       Res *= Numb;
00860       break;
00861     }
00862   }
00863   return Res;
00864 }