/* zeta-pinning.c */ /* compile with: */ /* MAC: gcc -O6 -o zeta-pinning zeta-pinning.c */ /* LINUX: gcc -O6 -o zeta-pinning zeta-pinning.c -lm */ #include #include #include /* #include */ #include /* For getopt */ /* external references for getopt */ extern char *optarg; extern int optind; extern int optopt; extern int opterr; extern int optreset; /*--------------------------------------------------------------------------*/ /* Random Numbers Generators (see at the end of the source) */ /*--------------------------------------------------------------------------*/ /* ran_array */ extern double *ranf_arr_ptr; #define ranf_arr_next() (*ranf_arr_ptr>=0? *ranf_arr_ptr++: ranf_arr_cycle()) double ranf_arr_cycle(); void ranf_start(long seed); /* mt19937 */ void init_genrand(unsigned long s); double genrand_real1(void); double genrand_real3(void); /*--------------------------------------------------------------------------*/ enum { ra, /* ran_array */ mt /* mersenne-twister */ } generator = mt; /* default generator */ int save_rng_state(char *name); int load_rng_state(char *name); void init_rng_state(unsigned long seed); double get_rng_double(); double ranu(); double *z1,*z2,*zaux,*omega; double lambda = 0.6; double h = 0.43; int N; int step; int each = 1; int feach = 0; int fsel = 0; #define NOUTDIM 100 int nout[NOUTDIM]; int nout_count = 0; long seed = 31416; char omegafile[256]; char saveomegafile[256]; char load_zeta_state[256] = "zeta-pinning.stt"; char save_zeta_state[256] = "zeta-pinning.stt"; /* Flags */ int ffile = 0; int fseed = 0; int fsaverng = 0; int fsize =0; int flambda =0; int fh = 0; int fsaveomega = 0; int finvert = 0; int fstep = 0; int fsave_zeta_state = 0; int fload_zeta_state = 0; int fG = 0; /* Functions used to limit to "cut" some RW trajectories */ #define LOW 6 #define HIGH 6 #define TILL 1000 //double tlow = 1.0 * (TILL * TILL) / (LOW * LOW) ; /* Does nothing till */ //double thigh = 1.0 * (TILL * TILL) / (HIGH * HIGH) ; /* N <= TILL */ int cut_low(int N) { int c; if (N <= TILL) c = N; else if (TILL > (c = LOW * sqrt(N))) c = TILL; else if (N < c) c = N; // if (N < (c = LOW * sqrt(N + tlow - TILL))) c = N; return c; } int cut_high(int N) { int c; if (N <= TILL) c = N; else if (TILL > (c = HIGH * sqrt(N))) c = TILL; else if (N < c) c = N; // if (N < (c = HIGH * sqrt(N + thigh - TILL))) c = N; return c; } /* Usage */ void usage() { fprintf(stderr,"\n\ zeta-pinning [options]\n\n\ [Parameters of the polymer]\n\ -n final size of the system (int)\n\ -l lambda (double) - default value is 0.6\n\ -h h (double) - default value is 0.43\n\ \n\ [Output saving options]\n\ -e print one line of output each (int)\n\ - default value is 1 (= print every line)\n\ -t print results for the size \n\ (The -t option can be repeated to print various intermediate sizes, -e and\n\ -t options are mutually exclusive)\n\ \n\ [Random environment]\n\ -f load sequence of omegas from file \n\ -r seed for initializing RNG (long int)\n\ -g generator (0: ran_array, 1: mersenne-twiser)\n\ -G generate gaussian omegas\n\ \n\ (Precedency rules: If option '-f' is chosen, the environment is loaded\n\ from file , otherwise the environment is generated by the RNG.\n\ If seed is given, RNG is initialized from that; else, if file 'zeta-pinning.rng'\n\ is found in folder, RNG state is automatically restored from that; else,\n\ RNG is initialized by default with seed 31416)\n\ \n\ -i use omega in the reverse order\n\ -z save sequence of omegas to file \n\ -w save RNG state to file 'zeta-pinning.rng' (overwrite!)\n\ \n\ [Recovery options]\n\ -a load zeta state from file 'zeta-pinning.stt'\n\ -b save zeta state to file 'zeta-pinning.stt' (overwrite!)\n\ -c save zeta state each steps - default\n\ value is \n\ \n\ -? usage\n\n\ The program send output to stdout and control messages to stderr.\n\ Output is made of a sequence of lines with the following format:\n\ \n\ where:\n\ system size\n\ sum of omegas since the last output\n\ overall sum of omegas\n\ value of the partition sum\n\ partition sum when the polymer is conditioned to return to 0.\n"); } /* Parse arguments */ void parse_arguments(int argc, char **argv) { int ch; int xx; while ((ch = getopt(argc, argv, "g:in:l:h:f:r:wz:abc:e:Gt:?")) != -1) switch (ch) { case 'i': finvert = 1; break; case 'G': fG = 1; break; case 'w': fsaverng = 1; break; case 'g': if (1!=sscanf(optarg,"%d",&xx)) { fprintf(stderr,"\nError on argument of -n. Exit.\n\n"); exit(-1); } else {if (xx==0) {generator = ra;} else if (xx==1) {generator = mt;} else {fprintf(stderr,"\nError on argument of -g. Exit.\n\n"); exit(-1);}} break; case 'n': fsize = 1; if (1!=sscanf(optarg,"%d",&N)) { fprintf(stderr,"\nError on argument of -n. Exit.\n\n"); exit(-1); } break; case 'l': if (1!=sscanf(optarg,"%lf",&lambda)) { fprintf(stderr,"\nError on argument of -l. Exit.\n\n"); exit(-1); } flambda = 1; break; case 'h': if (1!=sscanf(optarg,"%lf",&h)) { fprintf(stderr,"\nError on argument of -h. Exit.\n\n"); exit(-1); } fh = 1; break; case 'r': fseed = 1; if (1!=sscanf(optarg,"%ld",&seed)) { fprintf(stderr,"\nError on argument of -r. Exit.\n\n"); exit(-1); } break; case 'f': ffile = 1; if (1!=sscanf(optarg,"%s",&omegafile)) { fprintf(stderr,"\nError on argument of -f. Exit.\n\n"); exit(-1); } break; case 'z': fsaveomega = 1; if (1!=sscanf(optarg,"%s",&saveomegafile)) { fprintf(stderr,"\nError on argument of -z. Exit.\n\n"); exit(-1); } break; case 'a': fload_zeta_state = 1; break; case 'b': fsave_zeta_state = 1; break; case 'c': if (1!=sscanf(optarg,"%d",&step)) { fprintf(stderr,"\nError on argument of -c. Exit.\n\n"); exit(-1); } fstep = 1; break; case 'e': if (fsel) { fprintf(stderr,"\nYou cannot specify both -e and -t flags.\n\n"); exit(-1); } if (1!=sscanf(optarg,"%d",&each)) { fprintf(stderr,"\nError on argument of -e. Exit.\n\n"); exit(-1); } else feach = 1; break; case 't': if (feach) { fprintf(stderr,"\nYou cannot specify both -e and -t flags.\n\n"); exit(-1); } { int aux; if ((1!=sscanf(optarg,"%d",&aux))||(aux<0)) { fprintf(stderr,"\nError on argument of -t. Exit.\n\n"); exit(-1); } else { if (nout_count == NOUTDIM) { fprintf(stderr,"\nToo many -t flags. Exit.\n\n"); exit(-1); } nout[nout_count++] = aux; fsel = 1; } } break; case '?': default: usage(); exit(-1); break; } argc -= optind; argv += optind; if (!fsize) { fprintf(stderr,"\nYou must provide at least the final size of the system.\n"); usage(); exit(-1); } if (!fstep) step = N; if (ffile && fsaverng) { fprintf(stderr,"\nOptions '-f' and '-w' cannot be used together.\n\n"); exit(-1); } } /* Function used in the sampling loop */ double next_alpha(int i) { double alpha; alpha = exp(lambda*omega[i] - h); return alpha; } /* Main */ int main(int argc, char **argv) { int i,j,k; parse_arguments(argc,argv); #if 0 fprintf(stderr,"\n%f\t%f\t%d\t%d\n\n",tlow,thigh,cut_low(N),cut_high(N)); return 0; #endif if (!flambda) { fprintf(stderr,"\nWarning: value of lambda not given, setted by default to %f", lambda); } if (!fh) { fprintf(stderr,"\nWarning: value of h not given, setted by default to %f", h); } fprintf(stderr,"\nN=%d lambda=%f h=%f\n\n",N,lambda,h); omega = (double*)malloc(sizeof(double)*N); if(!ffile) { if (fseed) { fprintf(stderr,"RNG initialized with seed: %ld\n\n",seed); init_rng_state(seed); } else { if (!load_rng_state("zeta-pinning.rng")) { init_rng_state(seed); fprintf(stderr,"Warning: RNG initialized by default with seed '%ld'\n\n",seed); } else fprintf(stderr,"RNG restored from file 'zeta-pinning.rng'\n\n"); } } if (generator == ra) { fprintf(stderr,"RNG: unsing ran_array\n"); } else if (generator == mt) { fprintf(stderr,"RNG: unsing Mersenne-Twister\n"); } if (ffile) { /* Load random environment */ fprintf(stderr,"Loading omega from '%s' ... ",omegafile); FILE *stream = fopen(omegafile,"r"); if (ferror(stream)) { fprintf(stderr,"\nProblems opening file '%s'. Exit.\n\n",omegafile); exit(-1); } for(i=0; i< N; i++) { double a; if (1!=fscanf(stream,"%lf",&a)) { fprintf(stderr,"\nError reading file '%s'. Exit.\n\n",omegafile); exit(-1); } else { omega[i] = a; } } fclose(stream); fprintf(stderr,"OK\n\n"); } else { /* Generate a random environment */ if (fG == 0) { fprintf(stderr,"Generating random omegas ... "); double aaa = get_rng_double(); /* To skip the first omega generated */ /* (backward compatibility...) */ for(i=0; i< N; i++) { double a = get_rng_double(); if ((0 <= a) && (a < 0.5)) omega[i] = -1; else if (a <= 1) omega[i] = 1; else {fprintf(stderr,"\nProblems with the RNG. Exit.\n\n"); exit(-1);} } fprintf(stderr,"OK\n\n"); } else { /* Gaussian case */ fprintf(stderr,"Generating GAUSSIAN random omegas ... "); for(i=0; i<(N/2); i++) { double x1, x2, w, y1, y2; do { x1 = 2.0 * ranu() - 1.0; x2 = 2.0 * ranu() - 1.0; w = x1 * x1 + x2 * x2; } while ( w >= 1.0 ); w = sqrt( (-2.0 * log( w ) ) / w ); y1 = x1 * w; y2 = x2 * w; omega[2*i] = y1; omega[2*i+1] = y2; } fprintf(stderr,"OK\n\n"); } } if (finvert) fprintf(stderr,"Using omega in reverse order\n\n"); if (fsaveomega) { /* Save random environment */ if (!finvert) fprintf(stderr,"Saving omega in '%s' ... ",saveomegafile); else fprintf(stderr,"Saving omega (in reverse order) in '%s' ... ",saveomegafile); FILE *stream = fopen(saveomegafile,"w"); if (ferror(stream)) { fprintf(stderr,"\nProblems opening file '%s': skipping omega saving.\n\n",saveomegafile); } else { for(i=0; i< N; i++) { double a = finvert ? omega[N-1-i] : omega[i] ; fprintf(stream,"%f\n",a); } fclose(stream); fprintf(stderr,"OK\n\n"); } } if (fsaverng) { fprintf(stderr,"Saving RNG state ... "); if (save_rng_state("zeta-pinning.rng")) fprintf(stderr,"OK\n\n"); } int sstart; sstart = cut_low(N); int sstop; sstop = cut_high(N); int maxlength; /* To determine the length of vectors z1, z2 */ maxlength = sstart + sstop + 1; /* Alloc (+2 is for boundary conditions) */ z1 = (double*)malloc(sizeof(double)*(maxlength + 2)) + 1 + sstart; z2 = (double*)malloc(sizeof(double)*(maxlength + 2)) + 1 + sstart; /* Observe that "+ 1 + start" is given in order that z[j] at step k */ /* correspond to Z_{2k}(2j), where k = 0, 1, 2, ... and */ /* j = -cut_low(k), ..., -1, 0, +1, ..., +cut_high(k) */ int NN; double llambda, hh, oomegasum; /* Load zeta state */ if (fload_zeta_state) { fprintf(stderr,"Loading zeta state from '%s'\n",load_zeta_state); FILE *stream = fopen(load_zeta_state,"r"); if (ferror(stream)) { fprintf(stderr,"\nProblems opening file '%s'. Exit.\n\n",load_zeta_state); exit(-1); } /* The first line of the file must contain Nstart, lambda, h, omegasum */ if (1!=fscanf(stream,"%d",&NN)) { fprintf(stderr,"\nError reading first line of '%s'. Exit.\n\n",load_zeta_state); exit(-1); } if (1!=fscanf(stream,"%lf",&llambda)) { fprintf(stderr,"\nError reading first line of '%s'. Exit.\n\n",load_zeta_state); exit(-1); } if (1!=fscanf(stream,"%lf",&hh)) { fprintf(stderr,"\nError reading first line of '%s'. Exit.\n\n",load_zeta_state); exit(-1); } if (1!=fscanf(stream,"%le",&oomegasum)) { fprintf(stderr,"\nError reading first line of '%s'. Exit.\n\n",load_zeta_state); exit(-1); } fprintf(stderr,"From file '%s' I read the values:\nNstart=%d, lambda=%f, h=%f, omegasum=%le\n" ,load_zeta_state,NN,llambda,hh,oomegasum); if (NN >= N) { fprintf(stderr,"\nThe value of Nstart (=%d) I read from '%s' is not" " smaller than the one you gave (=%d). Exit.\n\n" ,NN,load_zeta_state,N); exit(-1); } if (lambda != llambda) { fprintf(stderr,"\nThe value of lambda (=%f) I read from '%s' does not" " coincide with the one you gave (=%f). Exit.\n\n", llambda,load_zeta_state,lambda); exit(-1); } if (h != hh) { fprintf(stderr,"\nThe value of h (=%f) I read from '%s' does not" " coincide with the one you gave (=%f). Exit.\n\n", hh,load_zeta_state,h); exit(-1); } /* Copy zeta state into z1 and z2 */ int tstart; tstart = cut_low(NN); int tstop; tstop = cut_high(NN); for (i=-sstart -1; i< -tstart; i++) { /* '-1' is for bound. cond. */ z2[i] = z1[i] = 0.0; } for (i= tstop + 1 ; i<= sstop +1; i++) { /* '+1' is for bound. cond. */ z2[i] = z1[i] = 0.0; } double a; int bb; for(i= - tstart; i <= + tstop; i++) { if ((1!=fscanf(stream,"%d",&bb)) || (bb != i) ) { fprintf(stderr,"\nError reading file '%s' at \"line\" %d. Exit.\n\n", load_zeta_state, i); exit(-1); } if (1!=fscanf(stream,"%le",&a)) { fprintf(stderr,"\nError reading file '%s' at \"line\" %d. Exit.\n\n", load_zeta_state, i); exit(-1); } else { z2[i] = z1[i] = a; } } fprintf(stderr,"Zeta state loaded and restored.\n\n"); fclose(stream); } /* Standard initialization (remember boundary components) */ if(!fload_zeta_state) { for(i=-sstart - 1; i<= sstop + 1; i++) z2[i] = z1[i] = 0.0; z1[0] = 1.0; } /*---------------*/ /* Sampling loop */ /*---------------*/ { int start, stop, iii; double alpha; double ff, omegasum, incr; omegasum = ( (fload_zeta_state) ? oomegasum : 0.0 ); incr = 0.0; for(i=( (fload_zeta_state) ? (NN + 1) : 1 ); i<= N; i++) { iii = (finvert ? N-i+1 : i) -1; alpha = next_alpha(iii); start = cut_low(i); stop = cut_high(i); ff = 0.0; /* Reinitialize ff at each step */ for(j= -start; j< 0; j++) { ff += z2[j] = 0.25*(z1[j+1]+2*z1[j]+z1[j-1]); } // ff += z2[-1] = 0.25*(z1[0]+2*z1[-1]+z1[-2]); ff += z2[0] = 0.25*alpha*(z1[1]+2*z1[0]+z1[-1]); // ff += z2[1] = 0.25*(z1[0]+2*z1[1]+z1[2]); for(j= 1; j<= stop; j++) { ff += z2[j] = 0.25*(z1[j+1]+2*z1[j]+z1[j-1]); } omegasum += omega[iii]; incr += omega[iii]; /* Swap vectors */ zaux = z1; z1 = z2; z2 = zaux; /* Write output */ if (fsel) { int ii; for(ii=0; ii=0? *ranf_arr_ptr++: ranf_arr_cycle()) double ranf_arr_cycle(); void ranf_start(long seed); /* mt19937 */ void init_genrand(unsigned long s); double genrand_real1(void); /*--------------------------------------------------------------------------*/ void init_rng_state(unsigned long seed) { /* initalize the generators with the same seed */ ranf_start(seed); init_genrand(seed); } double get_rng_double() { if (generator == ra) { return ranf_arr_next(); } else { return genrand_real1(); } } double ranu() { if (generator == ra) { return ranf_arr_next(); } else { return genrand_real3(); } } /************************************************************************/ /************************************************************************/ /************************************************************************/ /************************************************************************/ /************************************************************************/ /************************************************************************/ /* This program by D E Knuth is in the public domain and freely copyable * AS LONG AS YOU MAKE ABSOLUTELY NO CHANGES! * It is explained in Seminumerical Algorithms, 3rd edition, Section 3.6 * (or in the errata to the 2nd edition --- see * http://www-cs-faculty.stanford.edu/~knuth/taocp.html * in the changes to Volume 2 on pages 171 and following). */ /* N.B. The MODIFICATIONS introduced in the 9th printing (2002) are included here; there's no backwards compatibility with the original. */ /* If you find any bugs, please report them immediately to * taocp@cs.stanford.edu * (and you will be rewarded if the bug is genuine). Thanks! */ /************ see the book for explanations and caveats! *******************/ /************ in particular, you need two's complement arithmetic **********/ #define KK 100 /* the long lag */ #define LL 37 /* the short lag */ #define mod_sum(x,y) (((x)+(y))-(int)((x)+(y))) /* (x+y) mod 1.0 */ double ran_u[KK]; /* the generator state */ #ifdef __STDC__ void ranf_array(double aa[], int n) #else void ranf_array(aa,n) /* put n new random fractions in aa */ double *aa; /* destination */ int n; /* array length (must be at least KK) */ #endif { register int i,j; for (j=0;j=0? *ranf_arr_ptr++: ranf_arr_cycle()) double ranf_arr_cycle() { ranf_array(ranf_arr_buf,QUALITY); ranf_arr_buf[100]=-1; ranf_arr_ptr=ranf_arr_buf+1; return ranf_arr_buf[0]; } #define TT 70 /* guaranteed separation between streams */ #define is_odd(s) ((s)&1) #ifdef __STDC__ void ranf_start(long seed) #else void ranf_start(seed) /* do this before using ranf_array */ long seed; /* selector for different streams */ #endif { register int t,s,j; double u[KK+KK-1]; double ulp=(1.0/(1L<<30))/(1L<<22); /* 2 to the -52 */ double ss=2.0*ulp*((seed&0x3fffffff)+2); for (j=0;j=1.0) ss-=1.0-2*ulp; /* cyclic shift of 51 bits */ } u[1]+=ulp; /* make u[1] (and only u[1]) "odd" */ for (s=seed&0x3fffffff,t=TT-1; t; ) { for (j=KK-1;j>0;j--) u[j+j]=u[j],u[j+j-1]=0.0; /* "square" */ for (j=KK+KK-2;j>=KK;j--) { u[j-(KK-LL)]=mod_sum(u[j-(KK-LL)],u[j]); u[j-KK]=mod_sum(u[j-KK],u[j]); } if (is_odd(s)) { /* "multiply by z" */ for (j=KK;j>0;j--) u[j]=u[j-1]; u[0]=u[KK]; /* shift the buffer cyclically */ u[LL]=mod_sum(u[LL],u[KK]); } if (s) s>>=1; else t--; } for (j=0;j> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) static unsigned long state[N]; /* the array for the state vector */ static int left = 1; static int initf = 0; static unsigned long *next; /* initializes state[N] with a seed */ void init_genrand(unsigned long s) { int j; state[0]= s & 0xffffffffUL; for (j=1; j> 30)) + j); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array state[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ state[j] &= 0xffffffffUL; /* for >32 bit machines */ } left = 1; initf = 1; } /* initialize by an array with array-length */ /* init_key is the array for initializing keys */ /* key_length is its length */ /* slight change for C++, 2004/2/26 */ void init_by_array(unsigned long init_key[], int key_length) { int i, j, k; init_genrand(19650218UL); i=1; j=0; k = (N>key_length ? N : key_length); for (; k; k--) { state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL)) + init_key[j] + j; /* non linear */ state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; j++; if (i>=N) { state[0] = state[N-1]; i=1; } if (j>=key_length) j=0; } for (k=N-1; k; k--) { state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL)) - i; /* non linear */ state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; if (i>=N) { state[0] = state[N-1]; i=1; } } state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ left = 1; initf = 1; } static void next_state(void) { unsigned long *p=state; int j; /* if init_genrand() has not been called, */ /* a default initial seed is used */ if (initf==0) init_genrand(5489UL); left = N; next = state; for (j=N-M+1; --j; p++) *p = p[M] ^ TWIST(p[0], p[1]); for (j=M; --j; p++) *p = p[M-N] ^ TWIST(p[0], p[1]); *p = p[M-N] ^ TWIST(p[0], state[0]); } /* generates a random number on [0,0xffffffff]-interval */ unsigned long genrand_int32(void) { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return y; } /* generates a random number on [0,0x7fffffff]-interval */ long genrand_int31(void) { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return (long)(y>>1); } /* generates a random number on [0,1]-real-interval */ double genrand_real1(void) { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return (double)y * (1.0/4294967295.0); /* divided by 2^32-1 */ } /* generates a random number on [0,1)-real-interval */ double genrand_real2(void) { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return (double)y * (1.0/4294967296.0); /* divided by 2^32 */ } /* generates a random number on (0,1)-real-interval */ double genrand_real3(void) { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return ((double)y + 0.5) * (1.0/4294967296.0); /* divided by 2^32 */ } /* generates a random number on [0,1) with 53-bit resolution*/ double genrand_res53(void) { unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; return(a*67108864.0+b)*(1.0/9007199254740992.0); } /* These real versions are due to Isaku Wada, 2002/01/09 added */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Save and restore generator state */ int save_rng_state(char *name) { FILE *stream = fopen(name,"w"); int i; if (ferror(stream)) { fprintf(stderr,"Problems writing in file '%s'\n\n",name); return 0; } if (generator == ra) { fprintf(stream,"type=%d\n",0); // identifier for(i=0; i< KK; i++) fprintf(stream,"%lf\n",ran_u[i]); ranf_arr_cycle(); // refill the buffer } else { fprintf(stream,"type=%d\n",1); // identifier for(i=0; i< N; i++) fprintf(stream,"%lu\n",state[i]); next_state(); // refill the buffer } fclose(stream); return 1; } int load_rng_state(char *name) { FILE *stream = fopen(name,"r"); int i; if ((!stream)||ferror(stream)) { fprintf(stderr,"Problems reading file '%s'\n\n",name); return 0; } int type; if (1!=fscanf(stream,"type=%ld\n",&type)) { fprintf(stderr,"Problems reading generator type for file '%s'\n\n",name); return 0; } if (type == 0) { /*fprintf(stderr,"reading ran_array state\n");*/ double buffer[KK]; for(i=0; i< KK; i++) { double a; if (1!=fscanf(stream,"%lf\n",&(buffer[i]))) { fprintf(stderr,"Problems reading file '%s'\n\n",name); return 0; } } for(i=0; i< KK; i++) ran_u[i] = buffer[i]; ranf_arr_cycle(); generator = ra; } else if (type == 1) { unsigned long buffer[N]; /*fprintf(stderr,"reading mersenne-twister state\n");*/ for(i=0; i< N; i++) { unsigned long a; if (1!=fscanf(stream,"%lu\n",&(buffer[i]))) { fprintf(stderr,"Problems reading file '%s'\n\n",name); return 0; } } for(i=0; i< N; i++) state[i] = buffer[i]; initf =1; next_state(); // refill the buffer generator = mt; } else { fprintf(stderr,"Unknown generator type in file '%s'\n\n",name); return 0; } fclose(stream); return 1; } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/