Allink
v0.1
|
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 }