/** * @brief Find the best eigen value using exponential distribution formula * * This method has the same objective as FindSmallestEV, but uses a different * test to find the best value. It uses s randomly generated value within an * exponential distribution from the minimum to maximum occuring eigen value. * * Upon each call to this routine, the random seed is regenerated. * * NOTE: This implementation differs somewhat from the ISIS2 version in that * the value of the computed eigenvalue is used as the best eigenvalue. This * implementation produced better distributoion of points * * @param stack Stack to find the best value in * @param seedsample The point within the exponential distribution of * interest * @param minEV Minimum occuring eigen value * @param maxEV Maximum occuring eigen value * * @return SmtkQStackIter Stack interator */ SmtkQStackIter SmtkMatcher::FindExpDistEV(SmtkQStack &stack, const double &seedsample, const double &minEV, const double &maxEV) { if (stack.isEmpty()) return (stack.end()); SmtkQStackIter best(stack.begin()), current(stack.begin()); // Random number generator must scale between 0 and 1 double randNum = gsl_rng_uniform (r); double t1 = -std::log(1.0 - randNum * (1.0 - std::exp(-seedsample)))/seedsample; double pt = minEV + t1*(maxEV-minEV); double best_ev(DBL_MAX); while ( current != stack.end() ) { double test_ev(std::fabs(current.value().GoodnessOfFit()-pt)); if ( test_ev < best_ev) { best = current; best_ev = test_ev; // differs from ISIS2 which saved current eigenvalue } ++current; } return (best); }
size_t gsl_ran_discrete(const gsl_rng *r, const gsl_ran_discrete_t *g) { size_t c=0; double u,f; u = gsl_rng_uniform(r); #if KNUTH_CONVENTION c = (u*(g->K)); #else u *= g->K; c = u; u -= c; #endif f = (g->F)[c]; /* fprintf(stderr,"c,f,u: %d %.4f %f\n",c,f,u); */ if (f == 1.0) return c; if (u < f) { return c; } else { return (g->A)[c]; } }
int CModel::WeightedSamplingShotgun(int maxk,double* weights, gsl_rng * stream) { double s; int i; int q1 = 0; int q2 = maxk; //vdRngUniform(0,stream,1,&s,0,1); s = gsl_rng_uniform(stream); while(q1+1!=q2) { int q = (q1+q2)/2; if(weights[q]<s) { q1 = q; } else { q2 = q; } } return(q1); }
vector<vector<double> > SA::take_step(Mol2* Lig, PARSER* Input, gsl_rng* r, vector<vector<double> >xyz){ vector<vector<double> > new_xyz; double rnumber, x, y, z, a, b, g; COORD_MC* Coord = new COORD_MC; rnumber = gsl_rng_uniform(r); x = -Input->cushion + (1.0 * (rnumber*(2*Input->cushion))); rnumber = gsl_rng_uniform(r); y = -Input->cushion + (1.0 * (rnumber*(2*Input->cushion))); rnumber = gsl_rng_uniform(r); z = -Input->cushion + (1.0 * (rnumber*(2*Input->cushion))); rnumber = gsl_rng_uniform(r); a = -Input->rotation_step + (rnumber*(2*Input->rotation_step)); rnumber = gsl_rng_uniform(r); b = -Input->rotation_step + (rnumber*(2*Input->rotation_step)); rnumber = gsl_rng_uniform(r); g = -Input->rotation_step + (rnumber*(2*Input->rotation_step)); new_xyz = Coord->rototranslate(xyz, Lig, a, b,g, x, y, z); delete Coord; return(new_xyz); }
/*!********************************************************************** * \brief Generate a new set of parameters from the old ones with a random number generator * * \param r A pointer to a gnu scientific library random number generator * \param i_rezone_data A pointer to an array of rezone_union objects * \param step_size The double step_size in parameter space * * In order, the rezone_union objects must contain 1) a pointer to the element, 2) the total number of elements in the system, 3) min_size argument from rezone_minimize_ts, 4) max_size argument from rezone_minimize_ts, 5-n) positions of the zonal boundaries. This method is to be called by the GSL simulated annealing routine. ************************************************************************/ static void rezone_generate_step (const gsl_rng *r, void *i_rezone_data, double step_size) { element *element_ptr = ((rezone_data *) i_rezone_data)->element_ptr; double *old_positions = ((rezone_data *) i_rezone_data)->positions; double min_size = ((rezone_data *) i_rezone_data)->min_size; double max_size = ((rezone_data *) i_rezone_data)->max_size; double positions [64]; int id = ((rezone_data *) i_rezone_data)->id; int np = ((rezone_data *) i_rezone_data)->np; mpi::messenger *messenger_ptr = element_ptr->messenger_ptr; if (id == 0) { // Generate a random radius that is less than or equal to the step size double radius = gsl_rng_uniform (r) * step_size; if (radius == 0.0) { messenger_ptr->skip_all (); return; } // Generate a random step for every zonal position and sum the total step size double xs [np + 1]; double total = 0.0; for (int i = 1; i < np; ++i) { xs [i] = gsl_rng_uniform (r) * 2.0 - 1.0; total += xs [i] * xs [i]; } // If possible, rescale the total step to be equal to the radius; otherwise, change nothing if (total == 0.0) { messenger_ptr->skip_all (); return; } total = sqrt (total); total /= radius; positions [0] = old_positions [0]; for (int i = 1; i < np; ++i) { positions [i] = xs [i] / total + old_positions [i]; } positions [np] = old_positions [np]; // Broadcast the new positions messenger_ptr->bcast <double> (np + 1, positions); } else { // Receive the new positions messenger_ptr->bcast <double> (np + 1, positions); } // Iterate forward through the data, checking that the mininum and maximum sizes are obeyed old_positions [0] = positions [0]; for (int i = 1; i < np; ++i) { // Check minimum size if (positions [i] < old_positions [i - 1] + min_size) { positions [i] = old_positions [i - 1] + min_size; } // Check maximum size if (positions [i] > old_positions [i - 1] + max_size) { positions [i] = old_positions [i - 1] + max_size; } old_positions [i] = positions [i]; } // Iterate backward through the positions, checking that the minimum and maximum sizes are obeyed for (int i = np - 1; i >= 1; --i) { // Check minimum size if (old_positions [i] > old_positions [i + 1] - min_size) { old_positions [i] = old_positions [i + 1] - min_size; } // Check maximum size if (old_positions [i] < old_positions [i + 1] - max_size) { old_positions [i] = old_positions [i + 1] - max_size; } DEBUG ("POS: " << old_positions [i]); } // Make sure we didn't accidentally run off the end of the position array if (old_positions [0] < old_positions [1] - max_size) { for (int i = 0; i < np; ++i) { FATAL (old_positions [i] << " " << max_size); } FATAL ("Unrealistic size constraints in rezone: max_size too small"); throw 0; } if (old_positions [0] > old_positions [1] - min_size) { for (int i = 0; i < np; ++i) { FATAL (old_positions [i] << " " << min_size); } FATAL ("Unrealistic size constraints in rezone: min_size too large"); throw 0; } }
float randf() { return gsl_rng_uniform(r); }
void weighted_distribution_Metropolis(double *x, double *y, double *z, int N, double (func)(double, double, double)) { // The gsl random number generator, gsl_rng_uniform(q) is now a uniformly distributed random number const gsl_rng_type *T; gsl_rng *q; gsl_rng_env_setup(); T = gsl_rng_default; q = gsl_rng_alloc(T); gsl_rng_set(q,time(NULL)); int i; int j = 0; double x_val, y_val, z_val, ratio_probabilities, probability; double steps_to_intitial_state = 1e4; double delta = 2.1; int total = 0, accepted = 0; x[0] = 0.0; y[0] = 0.0; z[0] = 0.0; for (i = 1; i < N; i++) { // Makes sure that alos the first points are random points from the distribution if((j < steps_to_intitial_state) && (i == 2)){ total = 0; accepted = 0; i--; x[i-1] = x[i]; y[i-1] = y[i]; z[i-1] = z[i]; j++; } // Generate a trial state total++; x_val = x[i-1] + delta * (gsl_rng_uniform(q) - 0.5); y_val = y[i-1] + delta * (gsl_rng_uniform(q) - 0.5); z_val = z[i-1] + delta * (gsl_rng_uniform(q) - 0.5); // Decide whether the trial state is accepted, using steps 4 and 5' from the slides ratio_probabilities = func(x_val, y_val, z_val) / func(x[i-1], y[i-1], z[i-1]); if (ratio_probabilities >= 1) { accepted++; x[i] = x_val; y[i] = y_val; z[i] = z_val; } else { probability = gsl_rng_uniform(q); if(ratio_probabilities >= probability){ accepted++; x[i] = x_val; y[i] = y_val; z[i] = z_val; } else{ x[i] = x[i-1]; y[i] = y[i-1]; z[i] = z[i-1]; } } } printf("Accepted trial changes: %d\n", accepted); printf("Total trial attempts: %d\n", total); printf("Ratio = %.1f%%\n", (double) accepted/total * 100); // free memory for gsl random number generator gsl_rng_free(q); }
bool CompositionRejectionSampler::Sample(const pssalib::datamodel::CompositionRejectionSamplerData* ptrData, gsl_rng* ptrRNG, const REAL scale, UNSIGNED_INTEGER& outI, REAL& outR) { for(UNSIGNED_INTEGER k = 0; k < PSSA_CR_MAX_ITER; ++k) { REAL r = gsl_rng_uniform (ptrRNG) * scale; pssalib::datamodel::PSSACR_Bins::CONST_PAIR_BINS_ITER itB; int c = 0; ptrData->bins.getBins(itB); // Linear search step to find the bin REAL temp = 0.0; for(; itB.first != itB.second; ++itB.first) { c++; temp += itB.first->second.dBinSum; if(r < temp) break; } // When r =~ scale, In some cases the sum can fail for small value and reach the end without // find a bin. In this case take the latest one bin if (itB.first == itB.second) { // It seem that boost does not support --: // so reiterate c - 1 ptrData->bins.getBins(itB); for(int s = 0; s < c - 1 ; s++) ++itB.first; } if (itB.first->first <= 30) temp = ptrData->minValue * (1 << itB.first->first); else temp = ldexp(ptrData->minValue, itB.first->first); const pssalib::datamodel::PSSACR_Bin *pBin = &(itB.first->second); UNSIGNED_INTEGER unBins = pBin->size(); // Rejection step to sample within the bin while (true) { UNSIGNED_INTEGER sI = gsl_rng_uniform_int(ptrRNG, unBins); r = gsl_rng_uniform (ptrRNG); r *= temp; sI = pBin->get_at(sI); if(r < ptrData->bins.getValue(sI)) { outI = sI; outR = r; return true; } } } // All bins are guaranteed to be at least 50% full, so the probability of not finding a sample is <= 2^-k (~8e-31). return false; }
int GSLRNG_uniform(stEval *args, stEval *result, void *i) { gsl_rng *r = STPOINTER(&args[0]); STDOUBLE(result) = gsl_rng_uniform(r); return EC_OK; }
void TChainWriteBuffer::add(const TChain& chain, bool converged, double lnZ, double * GR) { // Make sure buffer is long enough if(length_ >= nReserved_) { reserve(1.5 * (length_ + 1)); std::cout << "reserving" << std::endl; } // Store metadata TChainMetadata meta = {converged, lnZ}; metadata.push_back(meta); // Choose which points in chain to sample double totalWeight = chain.get_total_weight(); for(unsigned int i=0; i<nSamples_; i++) { samplePos[i] = gsl_rng_uniform(r) * totalWeight; } std::sort(samplePos.begin(), samplePos.end()); // Copy chosen points into buffer unsigned int i = 1; // Position in chain unsigned int k = 0; // Position in buffer double w = chain.get_w(0); unsigned int chainLength = chain.get_length(); size_t startIdx = length_ * nDim_ * (nSamples_+2); const double *chainElement; while(k < nSamples_) { if(w < samplePos[k]) { assert(i < chainLength); w += chain.get_w(i); i++; } else { chainElement = chain.get_element(i-1); buf[startIdx + nDim_*(k+2)] = chain.get_L(i-1); for(size_t n = 1; n < nDim_; n++) { buf[startIdx + nDim_*(k+2) + n] = chainElement[n-1]; } k++; } } assert(k == nSamples_); // Copy best point into buffer i = chain.get_index_of_best(); chainElement = chain.get_element(i); buf[startIdx + nDim_] = chain.get_L(i); for(size_t n = 1; n < nDim_; n++) { buf[startIdx + nDim_ + n] = chainElement[n-1]; } // Copy the Gelman-Rubin diagnostic into the buffer buf[startIdx] = std::numeric_limits<float>::quiet_NaN(); if(GR == NULL) { for(size_t n = 1; n < nDim_; n++) { buf[startIdx + n] = std::numeric_limits<float>::quiet_NaN(); } } else { //std::cout << "Writing G-R ..." << std::endl; for(size_t n = 1; n < nDim_; n++) { //std::cout << n << std::endl; buf[startIdx + n] = GR[n-1]; } } //std::cout << "Done." << std::endl; length_++; }
double Random::uniform() { return gsl_rng_uniform(this->randomGeneratorHandle); }
void simulation(float mu, float koff){ /*set up variables for RNG, generate seed that's time-dependent, * seed RNG with that value - guarantees that MPI instances will * actually be different from each other*/ const gsl_rng_type * T; gsl_rng_env_setup(); T = gsl_rng_default; gsl_rng *r; r = gsl_rng_alloc (T); unsigned long int seed; seed=gen_seed(); gsl_rng_set(r,seed); /*old legacy stuff //memset(lanes,0,NLANES*L*sizeof(int)); //lanes[8][48]=22; //FILE *fp;*/ /*define total time of simulation (in units of polymerizing events)*/ int totaltime=500; /*define number of ends in the system, necessary for depol * calculation and rates. Also, define a toggle for the first pol * event to reset*/ int ends=0; int newends=0; int first=1; /*just declare a bunch of stuff that we will use*/ float domega,kon; int accepted=0; int filaments,noconsts; int int_i; int j,k,size,currfils,currlen,gap,l,m; float i,p,coverage; int type=0; /*declare two matrices for the filaments per lane, one for the * "permanent" stuff and one for temporary testing in the * Metropolis scheme*/ int lanes[NLANES][L]={{0}}; int newlanes[NLANES][L]={{0}}; /*two floats to store the time of the next polymerization and depol * events, that will be initialized later*/ float nexton=0; float nextoff=VERYBIG; /*declare three GMP arbitrary precision values: one for storing the * current number of microstates, one for the new number when testing * in the Metropolis scheme and one to store the difference*/ mpz_t states; mpz_t newstates; mpz_t deltastates; mpz_init(states); mpz_init(newstates); mpz_init(deltastates); /*sets up: the value of the chemical potential of a monomer, the * on-rate (we're always taking it to be one), the off-rate * (defined in relation to the on-rate) and the average size of * a new polymer*/ kon=1; //float kon=1.0; //float koff=0.1; //try based on ends //printf("%f %f\n",kon,koff); int avg_size=3; p=1.0/avg_size; float inv_sites=1.0/(NLANES*(L-1)); clock_t t1 = clock(); /*sets up the I/O to a file - filename is dependent on MPI * instance number to avoid conflicts*/ char* filename[40]; //int my_rank=0; int my_rank; MPI_Comm_rank(MPI_COMM_WORLD,&my_rank); sprintf(filename,"outputs_%1.1f_%1.1f/run%d.txt",mu,koff,my_rank); FILE *fp = fopen(filename, "w"); //strcat(filename,threadnum); //strcat(filename,".txt"); /*sets up the time for the first on event (first off only calculated * after we have filaments!)*/ nexton=gsl_ran_exponential(r,1.0/kon); //nextoff=gsl_ran_exponential(r,1.0/koff); //printf("nexton=%f nexoff=%f, avg on=%f avg off=%f thread=%d\n",nexton,nextoff,1.0/kon,1.0/koff,omp_get_thread_num()); /*start of the main loop*/ for (i=0;i<totaltime;i=i+0.01){ clock_t t2 = clock(); //printf("thread=%d i=%f\n",omp_get_thread_num(),i); /*before anything else, make a copy of the current lanes into * the matrix newlanes*/ memcpy(newlanes,lanes,sizeof(lanes)); newends=ends; /*calculate the current coverage (sites occupied divided by the * total number of sites) and output to file the current "time" * and coverage*/ coverage=0; for (k=0;k<NLANES;k++){ for (j=1;j<lanes[k][0]+1;j++){ coverage=coverage+lanes[k][j]; } } //printf("total length=%f\n",coverage); coverage=coverage*inv_sites; //printf("coverage=%f\n",coverage); fprintf(fp, "%f %f %f\n", i,coverage,ends,(double)(t2-t1)/CLOCKS_PER_SEC); //printf("%f %f\n",i,coverage); //printf("i=%f nexton=%f nextoff=%f type=%d\n",i,nexton,nextoff,type); /*tests for events, with priority for polymerizing - if both * are due, it will polymerize first and only depol in the next * timestep*/ if (i>=nextoff){ type=2;} if (i>=nexton){ type=1; } /*we will now calculate the number of filaments and constraints * in the system, going over each lane - relatively * straightforward!*/ filaments=0; noconsts=0; for (k=0;k<NLANES;k++){ //printf("according to main, %d filaments in lane %d\n",newlanes[k][0],k); filaments=filaments+newlanes[k][0]; noconsts=noconsts+2*newlanes[k][0]; if (newlanes[k][0]>1){ noconsts=noconsts+newlanes[k][0]; } } /*polymerization event!*/ if (type==1){ /*big legacy stuff - leave it alone!*/ //printf("lanes at beginning: filaments=%d noconsts=%d\n",filaments,noconsts); //for (k=0;k<NLANES;k++){ //printf("lane %d: ",k); //for (j=1;j<lanes[k][0]+1;j++){ //printf("%d ",lanes[k][j]); //} //printf("\n"); //} //if (i>0) count(states,argc, argv, lanes, filaments, noconsts); //gmp_printf("%Zd\n",states); /*sample exponential to get the size of the filament to be * added (integer exponential is geometric!)*/ size=gsl_ran_geometric(r,p); /*pick a lane at random to add the new filament*/ /*parentheses: in the system without stickers, as long as * this step of random sampling doesn't change, we're fine - * order inside lane doesn't really matter!*/ j=gsl_rng_uniform_int(r,NLANES); /*calculate the current number of filaments and occupied * length in the chosen lane*/ currfils=lanes[j][0]; currlen=0; for (k=1;k<currfils+1;k++){ currlen=currlen+lanes[j][k]; } //printf("currlen %d currfils %d\n",currlen,currfils); /*test if there's enough space to insert the new filament*/ if (currlen+currfils+size+2>L) continue; /*if there is, pick a "gap" to insert the filament in * (i.e. the place in the order of filaments of that lane)*/ else{ gap=1+gsl_rng_uniform_int(r,currfils+1); /*if it's not at the end of the order, need to move the other * ones in the lanes matrix to open space for the new one*/ if (gap!=currfils+1){ for (k=currfils;k>gap-1;k--){ newlanes[j][k+1]=newlanes[j][k]; } } /*insert new filament...*/ newlanes[j][gap]=size; /*...and update the number of filaments in the lane*/ newlanes[j][0]++; } /*calculate number of filaments and constraints for the * newlanes matrix - seems like a waste of a for loop, eh?*/ filaments=0; noconsts=0; for (k=0;k<NLANES;k++){ //printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k); filaments=filaments+newlanes[k][0]; noconsts=noconsts+2*newlanes[k][0]; if (newlanes[k][0]>1){ noconsts=noconsts+newlanes[k][0]; } } //printf("lanes after adding: filaments=%d noconsts=%d\n",filaments,noconsts); //printf("proposed change:\n"); //for (k=0;k<NLANES;k++){ //printf("lane %d: ",k); //for (j=1;j<newlanes[k][0]+1;j++){ //printf("%d ",newlanes[k][j]); //} //printf("\n"); //} /*count microstates after addition!*/ count_new(&newstates, newlanes, filaments, noconsts); //fprintf(fp,"count="); //value_print(fp, P_VALUE_FMT, newstates); //fprintf(fp,"\n"); //gmp_printf("states=%Zd\n",states); //gmp_printf("newstates=%Zd\n",newstates); /*calculate delta omega for the addition - chemical potential * plus entropy difference - this should always work since we * set states to 0 in the very first iteration*/ domega=-mu*size-mpzln(newstates)+mpzln(states); //printf("delta omega: %f log10newstates=%f log10states=%f\n",domega, mpzln(newstates),mpzln(states)); /*metropolis test - if delta omega is negative, we accept * the addition*/ if (domega<0){ memcpy(lanes,newlanes,sizeof(lanes)); mpz_set(states,newstates); if (size==1){ ends=ends+1; }else if (size>1){ ends=ends+2; } if (first==1){ first=0; nextoff=gsl_ran_exponential(r,1.0/(koff*ends)); }else{ nextoff=i+gsl_ran_exponential(r,1.0/(koff*ends)); } } /*if it's positive, we calculate the probability of acceptance * and test for it*/ else{ double prob=exp(-1.0*domega); double fromthehat=gsl_rng_uniform(r); //printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob); if (fromthehat<prob){ memcpy(lanes,newlanes,sizeof(lanes)); mpz_set(states,newstates); if (size==1){ ends=ends+1; }else if (size>1){ ends=ends+2; } if (first==1){ first=0; nextoff=gsl_ran_exponential(r,1.0/(koff*ends)); }else{ nextoff=i+gsl_ran_exponential(r,1.0/(koff*ends)); } //printf("accepted anyway!\n"); } } //printf("final result:\n"); //for (k=0;k<NLANES;k++){ //printf("lane %d: ",k); //for (j=1;j<lanes[k][0]+1;j++){ //printf("%d ",lanes[k][j]); //} //printf("\n"); //} /*calculate time of next polymerization event and reset type*/ nexton=nexton+gsl_ran_exponential(r,1.0/kon); //printf("nexton: %f\n",nexton); type=0; } /*Depol event! We need to check for number of filaments here * (note that "filaments" here is the one calculated at the * beginning of the for loop) because if there are no filaments * we just need to recalculate nextoff and keep going*/ if (type==2 && filaments>0){ //printf("entered depol\n"); //printf("filaments: %d\n",filaments); /*this is one of those conditions that shouldn't be necessary, * but I needed to add this at some point and now I'm afraid * to take it out and break the whole thing, so there you go*/ if (i>0 && filaments>0 ) { //count(states,argc, argv, lanes, filaments, noconsts); //gmp_printf("%Zd\n",states); /*pick a filament to decrease size - this will be changed * soon!*/ //j=gsl_rng_uniform_int(r,filaments)+1; //printf("j=%d\n",j); j=gsl_rng_uniform_int(r,ends)+1; //fprintf(fp,"j=%d out of %d\n",j,ends); /*need to replicate the routine below, but with more * intelligence to track ends - maybe create small * test program to try it in isolation?*/ /*go through lanes until you find the filament to be * decreased in size. Then, decrease size by one, check * whether the filament disappeared (in which case following * filaments need to be shifted left and number of filaments * in lane decreased). Finally, break from the for loop*/ int end_counter=0; int doneit=0; for (k=0;k<NLANES;k++){ //fprintf(fp,"k=%d nd_counter=%d, lane has %d filaments\n",k,end_counter,lanes[k][0]); for (l=1;l<lanes[k][0]+1;l++){ if (lanes[k][l]==1){ end_counter=end_counter+1; }else{ end_counter=end_counter+2; } if (j<=end_counter){ //fprintf(fp,"filaments=%d k=%d end_counter=%d thing to change=%d\n",filaments,k,end_counter,newlanes[k][l]); newlanes[k][l]=newlanes[k][l]-1; if (newlanes[k][l]==1){ newends=newends-1; } if (newlanes[k][l]==0){ for (m=l;m<newlanes[k][0];m++){ newlanes[k][m]=newlanes[k][m+1]; } newlanes[k][0]--; newends=newends-1; } doneit=1; break; } } if (doneit==1){ break; } } } //printf("nextoff=%f\n",nextoff); type=0; filaments=0; noconsts=0; for (k=0;k<NLANES;k++){ //printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k); filaments=filaments+newlanes[k][0]; noconsts=noconsts+2*newlanes[k][0]; if (newlanes[k][0]>1){ noconsts=noconsts+newlanes[k][0]; } } //printf("rank %d is dumping previous lanes:\n",my_rank); //dump_lanes(lanes); //printf("rank %d is dumping its %d filaments and noconsts %d\n",my_rank,filaments,noconsts); //dump_lanes(newlanes); /*metropolis test should go in here*/ count_new(&newstates, newlanes, filaments, noconsts); //<-segfault is here! //fprintf(fp,"count="); //value_print(fp, P_VALUE_FMT, newstates); //fprintf(fp,"\n"); //gmp_printf("states=%Zd\n",states); //gmp_printf("newstates=%Zd\n",newstates); /*calculate delta omega for the addition - chemical potential * plus entropy difference - this should always work since we * set states to 0 in the very first iteration*/ domega=mu-mpzln(newstates)+mpzln(states); //fprintf(fp,"depol domega=%f, diff in mpzln=%f\n",domega,domega-1); if (domega<0){ memcpy(lanes,newlanes,sizeof(lanes)); mpz_set(states,newstates); ends=newends; } /*if it's positive, we calculate the probability of acceptance * and test for it*/ else{ double prob=exp(-1.0*domega); double fromthehat=gsl_rng_uniform(r); //printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob); if (fromthehat<prob){ memcpy(lanes,newlanes,sizeof(lanes)); mpz_set(states,newstates); } } if (ends>0){ /*recalculate nextoff and reset type*/ nextoff=nextoff+gsl_ran_exponential(r,1.0/(koff*ends)); }else{ nextoff=VERYBIG; //first=1; } /*recalculate the number of filaments and constraints (could * be done more efficiently, but whatever)*/ filaments=0; noconsts=0; for (k=0;k<NLANES;k++){ //printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k); filaments=filaments+lanes[k][0]; noconsts=noconsts+2*lanes[k][0]; if (lanes[k][0]>1){ noconsts=noconsts+lanes[k][0]; } //printf("before counting: filaments=%d noconsts=%d\n",filaments,noconsts); } /*recalculate total number of states - this will probably be * part of the Metropolis test further up when this is done*/ count_new(&states, lanes, filaments, noconsts); //fprintf(fp,"count="); //value_print(fp, P_VALUE_FMT, states); //fprintf(fp,"\n"); } /*in case there's nothing to depolimerize, we set nextoff as a big * float and reset the first flag*/ if (type==2 && filaments==0){ nextoff=VERYBIG; //first=1; type=0; } /*also, in any situation where there's no filament in the system, * we set states to zero just to be on the safe side*/ if (filaments==0){ mpz_set_si(states,0);} //else{ ////printf("pass/ng to count: %d %d \n",filaments, noconsts); //count_new(&states,lanes, filaments, noconsts);} ////for (k=0;k<NLANES;k++){ //////printf("lane %d: ",k); ////for (j=1;j<lanes[k][0]+1;j++){ //////printf("%d ",lanes[k][j]); ////} ////printf("\n"); //} //printf("%d %d\n",size,j); //printf("%d %f\n",omp_get_thread_num(),coverage); } /*clearing up - deallocating the arbitrary precision stuff, closing * the I/O file and returning!*/ mpz_clear(states); mpz_clear(newstates); mpz_clear(deltastates); gsl_rng_free (r); fclose(fp); return coverage; }
void predefinedGrid(inputPars *par, struct grid *g){ FILE *fp; int i; double x,y,z,scale; gsl_rng *ran = gsl_rng_alloc(gsl_rng_ranlxs2); #ifdef TEST gsl_rng_set(ran,6611304); #else gsl_rng_set(ran,time(0)); #endif fp=fopen(par->pregrid,"r"); par->ncell=par->pIntensity+par->sinkPoints; for(i=0;i<par->pIntensity;i++){ // fscanf(fp,"%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", &g[i].id, &g[i].x[0], &g[i].x[1], &g[i].x[2], &g[i].dens[0], &g[i].t[0], &abun, &g[i].dopb, &g[i].vel[0], &g[i].vel[1], &g[i].vel[2]); // fscanf(fp,"%d %lf %lf %lf %lf %lf %lf %lf\n", &g[i].id, &g[i].x[0], &g[i].x[1], &g[i].x[2], &g[i].dens[0], &g[i].t[0], &abun, &g[i].dopb); int nRead = fscanf(fp,"%d %lf %lf %lf %lf %lf %lf %lf %lf\n", &g[i].id, &g[i].x[0], &g[i].x[1], &g[i].x[2], &g[i].dens[0], &g[i].t[0], &g[i].vel[0], &g[i].vel[1], &g[i].vel[2]); if( nRead != 9 || g[i].id < 0 || g[i].id > par->ncell) { if(!silent) bail_out("Reading Grid File error"); exit(0); } g[i].dopb=200; g[i].abun[0]=1e-9; g[i].sink=0; g[i].t[1]=g[i].t[0]; g[i].nmol[0]=g[i].abun[0]*g[i].dens[0]; /* This next step needs to be done, even though it looks stupid */ g[i].dir=malloc(sizeof(point)*1); g[i].ds =malloc(sizeof(double)*1); g[i].neigh =malloc(sizeof(struct grid *)*1); if(!silent) progressbar((double) i/((double)par->pIntensity-1), 4); } for(i=par->pIntensity;i<par->ncell;i++){ x=2*gsl_rng_uniform(ran)-1.; y=2*gsl_rng_uniform(ran)-1.; z=2*gsl_rng_uniform(ran)-1.; if(x*x+y*y+z*z<1){ scale=par->radius*sqrt(1/(x*x+y*y+z*z)); g[i].id=i; g[i].x[0]=scale*x; g[i].x[1]=scale*y; g[i].x[2]=scale*z; g[i].sink=1; g[i].abun[0]=0; g[i].dens[0]=1e-30; g[i].t[0]=par->tcmb; g[i].t[1]=par->tcmb; g[i].dopb=0.; } else i--; } fclose(fp); qhull(par,g); distCalc(par,g); // getArea(par,g, ran); // getMass(par,g, ran); getVelosplines_lin(par,g); if(par->gridfile) write_VTK_unstructured_Points(par, g); gsl_rng_free(ran); }
void rand_vector(double*const x, size_t N, gsl_rng* r, double A) { for(size_t i=0; i<N; i++) { x[i] = A*gsl_rng_uniform(r); } }
int main ( int argc, char * argv[] ) { double * rx, * ry, * rz; double * vx, * vy, * vz; double * fx, * fy, * fz; int * ix, * iy, * iz; int N=216,c,a; double L=0.0; double rho=0.5, Tb = 1.0, gamma=1.0, rc2 = 2.5; double vir, vir_sum, pcor, V; double PE, KE, TE, ecor, ecut, T0=0.0, TE0; double rr3,dt=0.001, dt2, gfric, noise; int i,j,s; int nSteps = 10, fSamp=100; int short_out=0; int use_e_corr=0; int unfold = 0; char fn[20]; FILE * out; char * wrt_code_str = "w"; char * init_cfg_file = NULL; gsl_rng * r = gsl_rng_alloc(gsl_rng_mt19937); unsigned long int Seed = 23410981; /* Here we parse the command line arguments; If you add an option, document it in the usage() function! */ for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-N")) N=atoi(argv[++i]); else if (!strcmp(argv[i],"-rho")) rho=atof(argv[++i]); else if (!strcmp(argv[i],"-gam")) gamma=atof(argv[++i]); else if (!strcmp(argv[i],"-dt")) dt=atof(argv[++i]); else if (!strcmp(argv[i],"-rc")) rc2=atof(argv[++i]); else if (!strcmp(argv[i],"-ns")) nSteps = atoi(argv[++i]); else if (!strcmp(argv[i],"-so")) short_out=1; else if (!strcmp(argv[i],"-T0")) T0=atof(argv[++i]); else if (!strcmp(argv[i],"-Tb")) Tb=atof(argv[++i]); else if (!strcmp(argv[i],"-fs")) fSamp=atoi(argv[++i]); else if (!strcmp(argv[i],"-sf")) wrt_code_str = argv[++i]; else if (!strcmp(argv[i],"-icf")) init_cfg_file = argv[++i]; else if (!strcmp(argv[i],"-ecorr")) use_e_corr = 1; else if (!strcmp(argv[i],"-seed")) Seed = (unsigned long)atoi(argv[++i]); else if (!strcmp(argv[i],"-uf")) unfold = 1; else if (!strcmp(argv[i],"-h")) { usage(); exit(0); } else { fprintf(stderr,"Error: Command-line argument '%s' not recognized.\n", argv[i]); exit(-1); } } /* Compute the side-length */ L = pow((V=N/rho),0.3333333); /* Compute the tail-corrections; assumes sigma and epsilon are both 1 */ rr3 = 1.0/(rc2*rc2*rc2); ecor = use_e_corr?8*M_PI*rho*(rr3*rr3*rr3/9.0-rr3/3.0):0.0; pcor = use_e_corr?16.0/3.0*M_PI*rho*rho*(2./3.*rr3*rr3*rr3-rr3):0.0; ecut = 4*(rr3*rr3*rr3*rr3-rr3*rr3); /* Compute the *squared* cutoff, reusing the variable rc2 */ rc2*=rc2; /* compute the squared time step */ dt2=dt*dt; /* Compute gfric */ gfric = 1.0-gamma*dt/2.0; /* Compute noise */ noise = sqrt(6.0*gamma*Tb/dt); /* Output some initial information */ fprintf(stdout,"# Langevin-Thermostat MD Simulation" " of a Lennard-Jones fluid\n"); fprintf(stdout,"# L = %.5lf; rho = %.5lf; N = %i; rc = %.5lf\n", L,rho,N,sqrt(rc2)); fprintf(stdout,"# nSteps %i, seed %d, dt %.5lf, T0 %.5lf, gamma %.5lf\n", nSteps,Seed,dt,T0,gamma); fprintf(stdout,"# gfric %.5lf noise %.5lf\n",gfric,noise); /* Seed the random number generator */ gsl_rng_set(r,Seed); /* Allocate the position arrays */ rx = (double*)malloc(N*sizeof(double)); ry = (double*)malloc(N*sizeof(double)); rz = (double*)malloc(N*sizeof(double)); /* Allocate the boundary crossing counter arrays */ ix = (int*)malloc(N*sizeof(int)); iy = (int*)malloc(N*sizeof(int)); iz = (int*)malloc(N*sizeof(int)); /* Allocate the velocity arrays */ vx = (double*)malloc(N*sizeof(double)); vy = (double*)malloc(N*sizeof(double)); vz = (double*)malloc(N*sizeof(double)); /* Allocate the force arrays */ fx = (double*)malloc(N*sizeof(double)); fy = (double*)malloc(N*sizeof(double)); fz = (double*)malloc(N*sizeof(double)); /* Generate initial positions on a cubic grid, and measure initial energy */ init(rx,ry,rz,vx,vy,vz,ix,iy,iz,N,L,r,T0,&KE,init_cfg_file); sprintf(fn,"%i.xyz",0); out=fopen(fn,"w"); xyz_out(out,rx,ry,rz,vx,vy,vz,ix,iy,iz,L,N,16,1,unfold); fclose(out); PE = total_e(rx,ry,rz,fx,fy,fz,N,L,rc2,ecor,ecut,&vir); TE0=PE+KE; fprintf(stdout,"# step time PE KE TE drift T P\n"); for (s=0;s<nSteps;s++) { /* First integration half-step */ for (i=0;i<N;i++) { rx[i] += vx[i]*dt+0.5*dt2*fx[i]; ry[i] += vy[i]*dt+0.5*dt2*fy[i]; rz[i] += vz[i]*dt+0.5*dt2*fz[i]; vx[i] = vx[i]*gfric + 0.5*dt*fx[i]; vy[i] = vy[i]*gfric + 0.5*dt*fy[i]; vz[i] = vz[i]*gfric + 0.5*dt*fz[i]; /* Apply periodic boundary conditions */ if (rx[i]<0.0) { rx[i]+=L; ix[i]--; } if (rx[i]>L) { rx[i]-=L; ix[i]++; } if (ry[i]<0.0) { ry[i]+=L; iy[i]--; } if (ry[i]>L) { ry[i]-=L; iy[i]++; } if (rz[i]<0.0) { rz[i]+=L; iz[i]--; } if (rz[i]>L) { rz[i]-=L; iz[i]++; } } /* Calculate forces */ /* Initialize forces */ for (i=0;i<N;i++) { fx[i] = 2*noise*(gsl_rng_uniform(r)-0.5); fy[i] = 2*noise*(gsl_rng_uniform(r)-0.5); fz[i] = 2*noise*(gsl_rng_uniform(r)-0.5); } PE = total_e(rx,ry,rz,fx,fy,fz,N,L,rc2,ecor,ecut,&vir); /* Second integration half-step */ KE = 0.0; for (i=0;i<N;i++) { vx[i] = vx[i]*gfric + 0.5*dt*fx[i]; vy[i] = vy[i]*gfric + 0.5*dt*fy[i]; vz[i] = vz[i]*gfric + 0.5*dt*fz[i]; KE+=vx[i]*vx[i]+vy[i]*vy[i]+vz[i]*vz[i]; } KE*=0.5; TE=PE+KE; fprintf(stdout,"%i %.5lf %.5lf %.5lf %.5lf %.5le %.5lf %.5lf\n", s,s*dt,PE,KE,TE,(TE-TE0)/TE0,KE*2/3./N,rho*KE*2./3./N+vir/3.0/V); if (!(s%fSamp)) { sprintf(fn,"%i.xyz",!strcmp(wrt_code_str,"a")?0:s); out=fopen(fn,wrt_code_str); xyz_out(out,rx,ry,rz,vx,vy,vz,ix,iy,iz,L,N,16,1,unfold); fclose(out); } } }
void rand_vector(double*const x, double* min, double* max, size_t N, gsl_rng* r) { for(size_t i=0; i<N; i++) { x[i] = min[i] + gsl_rng_uniform(r) * (max[i] - min[i]); } }
void sample_model_synth(TGalacticLOSModel &galactic_model, TSyntheticStellarModel &stellar_model, TExtinctionModel &extinction_model, TStellarData &stellar_data) { unsigned int N_DM = 20; double DM_min = 5.; double DM_max = 20.; TMCMCParams params(&galactic_model, &stellar_model, NULL, &extinction_model, &stellar_data, N_DM, DM_min, DM_max); TMCMCParams params_tmp(&galactic_model, &stellar_model, NULL, &extinction_model, &stellar_data, N_DM, DM_min, DM_max); // Random number generator gsl_rng *r; seed_gsl_rng(&r); // Vector describing position in probability space size_t length = 1 + params.N_DM + 4*params.N_stars; // x = {RV, Delta_EBV_1, ..., Delta_EBV_M, Theta_1, ..., Theta_N}, where Theta = {DM, logMass, logtau, FeH}. double *x = new double[length]; // Random starting point for reddening profile x[0] = 3.1;// + gsl_ran_gaussian_ziggurat(r, 0.2); // RV for(size_t i=0; i<params.N_DM; i++) { x[i+1] = params.data->EBV / (double)N_DM * gsl_ran_chisq(r, 1.); } // Delta_EBV // Random starting point for each star TSED sed_tmp(true); for(size_t i = 1 + params.N_DM; i < 1 + params.N_DM + 4*params.N_stars; i += 4) { x[i] = 5. + 13.*gsl_rng_uniform(r); double logMass, logtau, FeH, tau; bool in_lib = false; while(!in_lib) { logMass = gsl_ran_gaussian_ziggurat(r, 0.5); tau = -1.; while(tau <= 0.) { tau = 1.e9 * (5. + gsl_ran_gaussian_ziggurat(r, 2.)); } logtau = log10(tau); FeH = -1.0 + gsl_ran_gaussian_ziggurat(r, 1.); in_lib = stellar_model.get_sed(logMass, logtau, FeH, sed_tmp); } x[i+1] = logMass; x[i+2] = logtau; x[i+3] = FeH; } params.update_EBV_interp(x); double *lnp_star = new double[params.N_stars]; double lnp_los = logP_los_synth(x, length, params, lnp_star); std::cerr << "# ln p(x_0) = " << lnp_los << std::endl; double *x_tmp = new double[length]; double Theta_tmp[4]; double sigma_Theta[4] = {0.1, 0.1, 0.1, 0.1}; double sigma_RV = 0.05; double sigma_lnEBV = 0.1; double lnp_tmp; double *lnp_star_tmp = new double[params.N_stars]; double p; unsigned int N_steps = 1000000; TChain chain(length, N_steps); TStats EBV_stats(N_DM); // In each step unsigned int N_star = 0; unsigned int N_accept_star = 0; unsigned int N_los = 0; unsigned int N_accept_los = 0; bool accept; bool burn_in = true; for(unsigned int i=0; i<N_steps; i++) { if(i == N_steps/2) { sigma_Theta[0] = 0.05; sigma_Theta[1] = 0.05; sigma_Theta[2] = 0.05; sigma_Theta[3] = 0.05; sigma_RV = 0.005; sigma_lnEBV = 0.05; burn_in = false; } // Step each star for(unsigned int n=0; n<params.N_stars; n++) { if(!burn_in) { N_star++; } rand_gaussian_vector(&Theta_tmp[0], &x[1+N_DM+4*n], &sigma_Theta[0], 4, r); lnp_tmp = logP_single_star_synth(&Theta_tmp[0], params.get_EBV(Theta_tmp[_DM]), x[0], galactic_model, stellar_model, extinction_model, stellar_data.star[n]); accept = false; if(lnp_tmp > lnp_star[n]) { accept = true; } else { p = gsl_rng_uniform(r); if((p > 0.) && (log(p) < lnp_tmp - lnp_star[n])) { accept = true; } } if(accept) { if(!burn_in) { N_accept_star++; } for(size_t k=0; k<4; k++) { x[1+N_DM+4*n+k] = Theta_tmp[k]; } lnp_los += lnp_tmp - lnp_star[n]; lnp_star[n] = lnp_tmp; } } // Step reddening profile if(!burn_in) { N_los++; } for(size_t k=0; k<length; k++) { x_tmp[k] = x[k]; } //if(!burn_in) { x_tmp[0] += gsl_ran_gaussian_ziggurat(r, sigma_RV); } for(unsigned int m=0; m<params.N_DM; m++) { x_tmp[1+m] += gsl_ran_gaussian_ziggurat(r, sigma_lnEBV); } params_tmp.update_EBV_interp(x_tmp); lnp_tmp = logP_los_synth(x_tmp, length, params_tmp, lnp_star_tmp); //if(isinf(lnp_tmp)) { // lnp_tmp = logP_los(x, length, params_tmp, lnp_star_tmp); //} //std::cerr << "# ln p(y) = " << lnp_tmp << std::endl; accept = false; if(lnp_tmp > lnp_los) { accept = true; } else if(log(gsl_rng_uniform(r)) < lnp_tmp - lnp_los) { accept = true; } if(accept) { if(!burn_in) { N_accept_los++; } for(size_t k=0; k<1+N_DM; k++) { x[k] = x_tmp[k]; } for(size_t k=0; k<params.N_stars; k++) { lnp_star[k] = lnp_star_tmp[k]; } lnp_los = lnp_tmp; params.update_EBV_interp(x); //std::cerr << "# ln p(x) = " << lnp_los << std::endl; } if(!burn_in) { chain.add_point(x, lnp_los, 1.); x_tmp[0] = exp(x[1]); for(size_t k=1; k<N_DM; k++) { x_tmp[k] = x_tmp[k-1] + exp(x[k]); } EBV_stats(x_tmp, 1); } } std::cerr << "# ln p(x) = " << lnp_los << std::endl; std::cout.precision(4); std::cerr << std::endl; std::cerr << "# % acceptance: " << 100. * (double)N_accept_star / (double)N_star << " (stars)" << std::endl; std::cerr << " " << 100. * (double)N_accept_los / (double)N_los << " (extinction)" << std::endl; std::cerr << "# R_V = " << x[0] << std::endl << std::endl; std::cerr << "# DM E(B-V)" << std::endl; std::cerr << "# =============" << std::endl; for(double DM=5.; DM<20.; DM+=1.) { std::cerr << "# " << DM << " " << params.get_EBV(DM) << std::endl; } std::cerr << std::endl; EBV_stats.print(); std::cerr << std::endl; delete[] x; delete[] x_tmp; delete[] lnp_star; delete[] lnp_star_tmp; }
double GslRandGen::uniform(void) { return gsl_rng_uniform(r); }
int main(void) { int i; /* loop counter */ int ekisselap; /* elapsed time for ekiss */ int mtelap; /* elapsed time for mt19937 */ int ranlxelap; /* elapsed time for ranlxd2 */ unsigned int dttk; /* combined date, time #ticks */ double tot; /* total points within a circle */ double bot; /* 1 million points */ double ratio; /* estimated 1 / 2pi */ time_t now; /* current date and time */ clock_t clk; /* current number of ticks */ clock_t ekissstart; /* start time for ekiss */ clock_t ekissfin; /* end time for ekiss */ clock_t mtstart; /* start time for mt19937 */ clock_t mtfin; /* end time for mt19937 */ clock_t ranlxstart; /* start time for ranlxd2 */ clock_t ranlxfin; /* end time for ranlxd2 */ struct tms t; /* structure used by times() */ gsl_rng *r; /* GSL RNG structure */ kissfmt *kk; /* ekiss structure */ kk = (kissfmt *) ekissinit(); /* initialize the ekiss structure */ bot = 1000000.0; /* set to 1 million */ /************************************************************/ tot = 0.0; /* initialize total */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ ekissstart = times(&t); /* start time for ekiss */ while (i--) /* loop 1 million times */ { double x; /* horizontal coordinate */ double y; /* vertical coordinate */ double wyy; /* y = cos(x) + 1 */ x = ekissunif(kk) * M_PI; /* uniform number 0-pi */ y = ekissunif(kk) * 2.0; /* uniform number 0-2 */ wyy = cos(x) + 1.0; /* the cosine curve */ if (y < wyy) tot += 1.0; /* if y is under the curve, tally */ } /* for each point above or below a cosine curve */ ratio = 2.0 * M_PI * (tot / bot); /* calculate est. Pi */ ekissfin = times(&t); /* finish time for ekiss */ printf("Monte Carlo Definite Integral of cos(x) + 1\n"); printf(" From zero to Pi\n"); printf(" Expected error is 1/100 (3 digit accuracy)\n"); printf(" n = 1 million\n"); printf(" ekiss %18.15f\n", ratio); free(kk->state); free(kk); /************************************************************/ /* allocate the mt19937 random number generator */ r = (gsl_rng *) gsl_rng_alloc(gsl_rng_mt19937); /* get clock ticks since boot */ clk = times(&t); /* get date & time */ time(&now); /* combine date, time, and ticks into a single UINT */ dttk = (unsigned int) (now ^ clk); /* initialize the GSL Mersenne Twister */ /* random number generator to date,time,#ticks */ gsl_rng_set(r, dttk); /* initialize mt19937 seed */ tot = 0.0; /* initialize total */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ mtstart = times(&t); /* start time for GSL mt19937 */ while (i--) /* loop 1 million times */ { double x; /* horizontal coordinate */ double y; /* vertical coordinate */ double wyy; /* y = cos(x) + 1 */ /* use the mt19937 random number generator this time */ x = gsl_rng_uniform(r) * M_PI; /* uniform number 0-pi */ y = gsl_rng_uniform(r) * 2.0; /* uniform number 0-2 */ wyy = cos(x) + 1.0; /* the cosine curve */ if (y < wyy) tot += 1.0; /* if under the curve, tally */ } /* for each point above or below a cosine curve */ ratio = 2.0 * M_PI * tot / bot; /* calculate est. pi */ mtfin = times(&t); /* finish time for GSL mt19937 */ printf("GSL mt19937 %18.15f\n", ratio); gsl_rng_free(r); /************************************************************/ /* allocate the ranlxd2 random number generator */ r = (gsl_rng *) gsl_rng_alloc(gsl_rng_ranlxd2); /* get clock ticks since boot */ clk = times(&t); /* get date & time */ time(&now); /* combine date, time, and ticks into a single UINT */ dttk = (unsigned int) (now ^ clk); /* initialize the GSL ranlxd2 random number generator */ /* to date,time,#ticks */ gsl_rng_set(r, dttk); /* initialize ranlxd2 seed */ tot = 0.0; /* initialize total */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ ranlxstart = times(&t); /* start time for GSL ranlxd2 */ while (i--) /* loop 1 million times */ { double x; /* horizontal coordinate */ double y; /* vertical coordinate */ double wyy; /* y = cos(x) + 1 */ /* use the ranlxd2 random number generator this time */ x = gsl_rng_uniform(r) * M_PI; /* uniform number 0-pi */ y = gsl_rng_uniform(r) * 2.0; /* uniform number 0-2 */ wyy = cos(x) + 1.0; /* the cosine curve */ if (y < wyy) tot += 1.0; /* if under the curve, tally */ } /* for each point above or below a cosine curve */ ratio = 2.0 * M_PI * (tot / bot); /* calculate est. pi */ ranlxfin = times(&t); /* finish time for GSL ranlxd2 */ printf("GSL ranlxd2 %18.15f\n", ratio); printf(" Actual %18.15f\n", M_PI); ekisselap = ekissfin - ekissstart; mtelap = mtfin - mtstart; ranlxelap = ranlxfin - ranlxstart; printf(" ekiss ticks %6d\n", ekisselap); printf("GSL mt19937 ticks %6d\n", mtelap); printf("GSL ranlxd2 ticks %6d\n", ranlxelap); gsl_rng_free(r); return(0); } /* main */
int mc_move(nn_vec ***r, triple *surf, triple *vac){ if(Nsurf == 0 || Nvac == 0) return 0; if(Nsurf == 1) return 0; int i; double xsi = gsl_rng_uniform(rg); /**********************************INSERTION STEP*************************************************/ if(xsi > 0.5){ //try insertion // printf("Attempting insertion.\n"); int Nstemp = 0; int Nvtemp = 0; unsigned long int m = gsl_rng_uniform_int(rg, (unsigned long int)Nvac); //randomly select vacancy nbs_vec *nbs = (nbs_vec *) calloc((size_t)NN, sizeof(nbs_vec)); //12 nearest neighbors neighbors(r, nbs, vac[m].x, vac[m].y, vac[m].z); int dM=0; //number of bonds that would be created (lowers energy) for(i=0; i<NN; i++){ if(nbs[i].occ == 1) dM++; //find number of bonds that would be created by inserting an atom if(nbs[i].occ == 0 && nbs[i].n == 0) Nvtemp ++; //increase in vacancy atoms if inserted if(nbs[i].occ == 1 && nbs[i].n == 11) Nstemp ++; //decrease in surface atoms if inserted } Nvtemp = Nvtemp - 1; //adding an atom in the vacancy would eliminate the vacancy Nstemp = Nstemp - 1; //adding a surface atom would counteract the decrease by 1 double alpha = 1.0/((Nsurf-Nstemp)/(1.0*Nvac)); double weight = exp(mu*beta + epsilon*dM*beta)*alpha; // printf("alpha: %lf\n", alpha); // printf("Acceptance weight: %.15e\n", weight); if(weight > 1){ //accept it r[vac[m].x][vac[m].y][vac[m].z].occ = 1; //make occupation number = 1 for(i=0; i<NN; i++){ //increase n for the surrounding sites r[nbs[i].x][nbs[i].y][nbs[i].z].n ++; nbs[i].n++; if(nbs[i].occ == 0 && nbs[i].n == 1){ //These sites are now neighbors - add them to vacany list add(vac, &Nvac, nbs[i].x, nbs[i].y, nbs[i].z); } if(nbs[i].occ == 1 && nbs[i].n == 12){ //These atoms are no longer surface atoms - delete them from surface list delete(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); } } //finally, add the new atom to the surface list add(surf, &Nsurf, vac[m].x, vac[m].y, vac[m].z); //and delete the new atom from the vacany list delete(vac, &Nvac, vac[m].x, vac[m].y, vac[m].z); temp_mc++; free(nbs); return 1; }else{ double xsi2 = gsl_rng_uniform(rg); if(weight > xsi2){ //do the same stuff as if weight > 1 r[vac[m].x][vac[m].y][vac[m].z].occ = 1; //make occupation number = 1 for(i=0; i<NN; i++){ //increase n for the surrounding sites r[nbs[i].x][nbs[i].y][nbs[i].z].n ++; nbs[i].n++; if(nbs[i].occ == 0 && nbs[i].n == 1){ //These sites are now neighbors - add them to vacany list add(vac, &Nvac, nbs[i].x, nbs[i].y, nbs[i].z); } if(nbs[i].occ == 1 && nbs[i].n == 12){ //These atoms are no longer surface atoms - delete them from surface list delete(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); } } //finally, add the new atom to the surface list add(surf, &Nsurf, vac[m].x, vac[m].y, vac[m].z); //and delete the new atom from the vacany list delete(vac, &Nvac, vac[m].x, vac[m].y, vac[m].z); temp_mc++; free(nbs); return 1; }else{ free(nbs); return 0; } } } /*******************************************DELETION STEP******************************************/ else{ //try deletion // printf("Attempting deletion.\n"); if(Nsurf==1) return 0; int Nstemp = 0; int Nvtemp = 0; long unsigned int m = gsl_rng_uniform_int(rg, (long unsigned)Nsurf); //randomly select surface atom nbs_vec *nbs = (nbs_vec *) calloc((size_t)NN, sizeof(nbs_vec)); //12 nearest neighbors neighbors(r, nbs, surf[m].x, surf[m].y, surf[m].z); int dM=0; //number of bonds that would be destroyed (increases energy) for(i=0; i<NN; i++){ if(nbs[i].occ == 1) dM++; //find number of bonds that would be destroyed by deleting an atom if(nbs[i].occ == 0 && nbs[i].n == 1) Nvtemp ++; //decrease in vacancy sites if deleted if(nbs[i].occ == 1 && nbs[i].n == 12) Nstemp ++; //increase in surface atoms if inserted } Nvtemp = Nvtemp - 1; //deleting the atom would counteract the vacancy decrease by 1 Nstemp = Nstemp - 1; //deleting the atom would decrease the number of surface atoms by 1 double alpha = 1.0/((Nvac-Nvtemp)/(1.0*Nsurf)); double weight = exp(-mu*beta - epsilon*dM*beta)*alpha; // printf("alpha: %.15e\n", alpha); // printf("Acceptance weight: %.15e\n", weight); if(weight > 1){ //accept it r[surf[m].x][surf[m].y][surf[m].z].occ = 0; //make occupation number = 0 for(i=0; i<NN; i++){ nbs[i].n --; r[nbs[i].x][nbs[i].y][nbs[i].z].n -- ; if(nbs[i].occ == 0 && nbs[i].n == 0){ //These sites are no longer surface vacancies - delete them from vacancy list delete(vac, &Nvac, nbs[i].x, nbs[i].y, nbs[i].z); } if(nbs[i].occ == 1 && nbs[i].n == 11){ //These atoms are now surface atoms - add them to surface list add(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); } if(r[nbs[i].x][nbs[i].y][nbs[i].z].n < 0) printf("Warning - nn less than 0!\n"); } //finally, add the new vacancy to the vacany list if(r[surf[m].x][surf[m].y][surf[m].z].n > 0) add(vac, &Nvac, surf[m].x, surf[m].y, surf[m].z); //and delete the atom from the surface list delete(surf, &Nsurf, surf[m].x, surf[m].y, surf[m].z); //Now, check for lone atoms and delete them and their vacancies for(i=0; i<NN; i++){ if(nbs[i].occ == 1 && nbs[i].n == 0){ //These atoms are now detached from the nanoparticle - delete them from surface list r[nbs[i].x][nbs[i].y][nbs[i].z].occ = 0; delete(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); //Delete vacancies associated with the atom nbs_vec *nbs_temp = (nbs_vec *) calloc((size_t)NN, sizeof(nbs_vec)); neighbors(r, nbs_temp, nbs[i].x, nbs[i].y, nbs[i].z); int q; for(q=0; q<NN; q++){ nbs_temp[q].n--; r[nbs_temp[q].x][nbs_temp[q].y][nbs_temp[q].z].n--; if(nbs_temp[q].n==0) delete(vac, &Nvac, nbs_temp[q].x, nbs_temp[q].y, nbs_temp[q].z); } } } free(nbs); return 2; }else{ double xsi2 = gsl_rng_uniform(rg); if(weight > xsi2){ //do the same stuff as if weight > 1 r[surf[m].x][surf[m].y][surf[m].z].occ = 0; //make occupation number = 0 for(i=0; i<NN; i++){ nbs[i].n --; r[nbs[i].x][nbs[i].y][nbs[i].z].n -- ; if(nbs[i].occ == 0 && nbs[i].n == 0){ //These sites are no longer surface vacancies - delete them from vacancy list delete(vac, &Nvac, nbs[i].x, nbs[i].y, nbs[i].z); } if(nbs[i].occ == 1 && nbs[i].n == 11){ //These atoms are now surface atoms - add them to surface list add(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); } if(r[nbs[i].x][nbs[i].y][nbs[i].z].n < 0) printf("Warning - nn less than 0!\n"); } //finally, add the new vacancy to the vacany list if(r[surf[m].x][surf[m].y][surf[m].z].n > 0) add(vac, &Nvac, surf[m].x, surf[m].y, surf[m].z); //and delete the atom from the surface list delete(surf, &Nsurf, surf[m].x, surf[m].y, surf[m].z); //Now, check for lone atoms and delete them and their vacancies for(i=0; i<NN; i++){ if(nbs[i].occ == 1 && nbs[i].n == 0){ //These atoms are now detached from the nanoparticle - delete them from surface list r[nbs[i].x][nbs[i].y][nbs[i].z].occ = 0; delete(surf, &Nsurf, nbs[i].x, nbs[i].y, nbs[i].z); //Delete vacancies associated with the atom nbs_vec *nbs_temp = (nbs_vec *) calloc((size_t)NN, sizeof(nbs_vec)); neighbors(r, nbs_temp, nbs[i].x, nbs[i].y, nbs[i].z); int q; for(q=0; q<NN; q++){ nbs_temp[q].n--; r[nbs_temp[q].x][nbs_temp[q].y][nbs_temp[q].z].n--; if(nbs_temp[q].n==0) delete(vac, &Nvac, nbs_temp[q].x, nbs_temp[q].y, nbs_temp[q].z); } } } free(nbs); return 2; }else{ free(nbs); return 0; } } } }
int main (int argc, char * argv[]) { /* System parameters */ int ** F; /* The 2D array of spins */ int L = 1000; /* The sidelength of the array */ int N; /* The total number of spins = L*L */ double T = 1.0; /* Dimensionless temperature = (T*k)/J */ /* Run parameters */ int nCycles = 1000000; /* number of MC cycles to run; one cycle is N consecutive attempted spin flips */ int fSamp = 1000; /* Frequency with which samples are taken */ /* Computational variables */ int nSamp; /* Number of samples taken */ int de; /* energy change due to flipping a spin */ double b; /* Boltzman factor */ double x; /* random number */ int i,j,a,c; /* loop counters */ /* Observables */ double s=0.0, ssum=0.0; /* average magnetization */ double e=0.0, esum=0.0; /* average energy per spin */ /* This line creates a random number generator of the "Mersenne Twister" type, which is much better than the default random number generator. */ gsl_rng * r = gsl_rng_alloc(gsl_rng_mt19937); unsigned long int Seed = 23410981; /* Here we parse the command line arguments */ for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-L")) L=atoi(argv[++i]); else if (!strcmp(argv[i],"-T")) T=atof(argv[++i]); else if (!strcmp(argv[i],"-nc")) nCycles = atoi(argv[++i]); else if (!strcmp(argv[i],"-fs")) fSamp = atoi(argv[++i]); else if (!strcmp(argv[i],"-s")) Seed = (unsigned long)atoi(argv[++i]); } /* Output some initial information */ /*fprintf(stdout,"# command: "); for (i=0;i<argc;i++) fprintf(stdout,"%s ",argv[i]); fprintf(stdout,"\n"); fprintf(stdout,"# ISING simulation, NVT Metropolis Monte Carlo\n"); fprintf(stdout,"# L = %i, T = %.3lf, nCycles %i, fSamp %i, Seed %u\n", L,T,nCycles,fSamp,Seed);*/ /* Seed the random number generator */ gsl_rng_set(r,Seed); /* Compute the number of spins */ N=L*L; /* Allocate memory for the system */ F=(int**)malloc(L*sizeof(int*)); for (i=0;i<L;i++) F[i]=(int*)malloc(L*sizeof(int)); /* Generate an initial state */ init(F,L,r); /* For computational efficiency, convert T to reciprocal T */ T=1.0/T; s = 0.0; e = 0.0; nSamp = 0; for (c=0;c<nCycles;c++) { /* Make N flip attempts */ #pragma omp parallel for private(i,j,de,b,x) shared(F) for (a=0;a<N;a++) { /* randomly select a spin */ i=(int)gsl_rng_uniform_int(r,L); j=(int)gsl_rng_uniform_int(r,L); /* get the "new" energy as the incremental change due to flipping spin (i,j) */ de = E(F,L,i,j); /* compute the Boltzmann factor; recall T is now reciprocal temperature */ b = exp(de*T); /* pick a random number between 0 and 1 */ x = gsl_rng_uniform(r); /* accept or reject this flip */ if (x<b) { /* accept */ /* flip it */ F[i][j]*=-1; } } /* Sample and accumulate averages */ if (!(c%fSamp)) { samp(F,L,&s,&e); //fprintf(stdout,"%i %.5le %.5le\n",c,s,e); fflush(stdout); ssum+=s; esum+=e; nSamp++; } #pragma omp barrier } fprintf(stdout,"# The average magnetization is %.5lf\n",ssum/nSamp); fprintf(stdout,"# The average energy per spin is %.5lf\n",esum/nSamp); fprintf(stdout,"# Program ends.\n"); }
int main(int argc, char *argv[]) { char HFile[NCHARMAX],tabledir_aux[NCHARMAX],Tstr[NCHARMAX]; int first_time=0; float pmin,pmax; double tau_ini, x_medium; double pos3d[3]; double s_nH,sx_cont,s_nd; double sq_mu,sq_mu2,sq_b,sq_a,sq_arg; double dust_fac = ext_zstar/zstar,P_H; long ip,i,j,k; const gsl_rng_type * T; time_t t0,t1,t2,t4,tc1,tc2; int NScatRec = 1e4; long ilow,ihigh; double x_1,x_0,H1,H0,xl,Hl,xlow,xhigh,rvp,vpl,vp0l,vp1l,ran0l,ran1l,vp0h,vp1h,ran0h,ran1h,vplow,vphigh; float tot_tab,used_tab; // double Vth=sqrt(2*KB*Temp/MP); int upcone; c = 299792.482; // km s-1 Inv_c = 1./c; Kth=Vth/(c*100000.0); gsl_rng *r; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); if(argc < 3) { printf(" Input parameter missing. \n "); printf(" Usage: > LyaRt [ParFile] [SEED] \n Exiting..."); exit(0); } /* Paramter file is read, it defines most of the variables found in allvars.h */ strcpy(ParFile,argv[1]); Seed0 = atoi(argv[2]); default_parameters(); dprints(OutShort); dprints(OutLong); read_parameters(ParFile); dprints(OutShort); dprints(OutLong); // The following are definitions specific to particular geometries. if (strcmp(GeomName,"Wind2")==0 || strcmp(GeomName,"Wind3")==0) { dr = (RSphere-R_inner) / (NCells-1); NCellSphere = R_inner/dr + 1.0; NCells += NCellSphere; } if (strcmp(GeomName,"Wind4")==0) { NCellSphere = 100; dr = R_Static / (NCellSphere-1); NCells = (long) ((RSphere - R_inner)/dr + 1.0); NCells += NCellSphere+1; if (NCells > 1e4) printf("WARNING: NCells = %ld value too high\n",NCells); } if (strcmp(GeomName,"ThinShell2")==0) { NCellSphere = 500; dr1 = R_inner / (NCellSphere-1); dr2 = (RSphere-R_inner)/(NCells-1); NCells+= NCellSphere; } // --- P = (photon*) malloc(NPhotons * sizeof(photon)); CellArr = (cell*) malloc(NCells * sizeof(cell)); define_geometry(GeomName,CellArr); gsl_rng_set(r,Seed0); //Initializing the random generator with seed Seed0? //Finding range of emission probability in cells pmin = CellArr[0].p_lya; pmax = pmin; for (i=1;i<NCells;i++) { if(CellArr[i].p_lya < pmin) pmin = CellArr[i].p_lya; if(CellArr[i].p_lya > pmax) pmax = CellArr[i].p_lya; } strcpy(tabledir_aux,tabledir); strcat(tabledir_aux,sxfile); strcpy(HFile,tabledir_aux); if (Temp >= 0) sprintf(Tstr,"%.2f",Temp); else sprintf(Tstr,"%.1f",Temp); if (Temp > 0 && Temp < 1) sprintf(Tstr,"%.3f",Temp); strcat(HFile,Tstr); printf(" Storing tabulated data... \n"); HList = (double*) malloc(NTAB2*sizeof(double)*2); DipList = (double*) malloc(NTAB1*2*sizeof(double)); HGList = (float*) malloc(NTAB2*2*sizeof(float)); #ifndef HAPPROX get_H(HFile,HList); printf("GET_H read\n"); #endif get_dipolar(DipList); printf("GET_DIPOLAR read\n"); get_HG(HGList); printf("GET_HG read\n"); // Print parameters read print_parameters(CellArr); #ifdef TEST_RII printf("TESTING REDISTRIBUTION FUNCTION for x0 = %f\n",x_test); #endif //Loop over NPhotons printf(" Loop over %ld photons started...\n",NPhotons); cx = 0.; cy = 0.; cz = 0.; nu0 = 2.47e15; gtype = (strcmp(GeomName,"HomSlab")==0) ? 0 : 1; if (strcmp(GeomName,"HomSphere")==0) gtype = 2; dprinti(gtype); fflush(stdout); nout = 0; #ifdef TCONST TPar = sx_const * pow(CellArr[0].T,-0.5); #endif XArr = (float *) malloc(NPhotons*sizeof(float)); X0Arr = (float *) malloc(NPhotons*sizeof(float)); InterArr = (int *) malloc(NPhotons*sizeof(int)); NscatArr = (int *) malloc(NPhotons*sizeof(int)); #ifdef GETPOSDIR PosArr = (float *) malloc(NPhotons*3*sizeof(float)); AngleArr = (float *) malloc(NPhotons*2*sizeof(float)); PosArrLong = (float *) malloc(NPhotons*NScatRec*3*sizeof(float)); #endif for (i = 0; i< NPhotons; i++) { XArr[i] = 0; X0Arr[i] = 0; InterArr[i] = -1; NscatArr[i] = -1; #ifdef GETPOSDIR PosArr[3*i] = 0; PosArr[3*i+1] = 0; PosArr[3*i+2] = 0; AngleArr[2*i] = 0; AngleArr[2*i+1] = 0; for (j = 0;j<NScatRec;j++) { PosArrLong[0+ 3*i + 3*NPhotons*j] = 0; PosArrLong[1+ 3*i + 3*NPhotons*j] = 0; PosArrLong[2+ 3*i + 3*NPhotons*j] = 0; } #endif } if (b == 0.) { a_par = 4.693e-4 * sqrt(1./CellArr[idc].T); vth = 12.85 * sqrt(CellArr[idc].T); } else { a_par = 4.693e-4 * sqrt(1./CellArr[idc].T); // a_par = 4.693e-4 * (12.85/b); // a_par = 4.7e-4 * (12.85/b); // vth = ; vth = 12.85 * sqrt(CellArr[idc].T); } if (VarXCrit==1) { x_medium = xp0 - vmax/vth; tau_ini = sx_const * ColDens * pow(CellArr[idc].T,-0.5) * voigt(HList,x_medium); if (tau_ini < 1e4) xcrit = 3; if (tau_ini >1e4 && tau_ini < 1e6) xcrit = 6; if (tau_ini > 1e6) xcrit = 10; //printf("1 xcrit: %f \n",xcrit); } (void) time(&t0); for (ip=0;ip < NPhotons;ip++) { nscat = 0; if( ip > 999 & ip % 1000 == 0) { printf("Photon %ld\n",ip); if( first_time==0 ) { first_time=1; printf("Estimated time to finish: %f [min] \n",1000*op_time * (NPhotons - ip) ); } } // Initialise photon's frequency, direction and position. xi0 = gsl_rng_uniform (r); xi1 = gsl_rng_uniform (r); xi2 = gsl_rng_uniform (r); xi3 = gsl_rng_uniform (r); xi4 = gsl_rng_uniform (r); xi5 = gsl_rng_uniform (r); init_photon(P,ip, xi0, xi1, xi2); dnd = (vth*nu0)/c; flag_zero = 0; (void) time(&t1); i = 0; xi1 = gsl_rng_uniform (r); xi2 = gsl_rng_uniform (r); xi3 = gsl_rng_uniform (r); idc_old = 0; while(idc != -1) { t_0 = - log(gsl_rng_uniform (r)); EscCond = 0; P[ip].ni = sin(th0)*cos(ph0); P[ip].nj = sin(th0)*sin(ph0); P[ip].nk = cos(th0); while(t_0 > 0.) { // Shortcut to compute crossing of empty cells, where no optical depth (t_0) is *used*. empty_cells(P,ip); H_x = voigt(HList, P[ip].xp); if(isnan(H_x)) printf("H_x is nan\n"); // H_x = 0.; // H_x disables H scattering. #ifdef TCONST s_nH = TPar * H_x*CellArr[idc].nH; #else s_nH = sx_const * pow(CellArr[idc].T,-0.5)*H_x*CellArr[idc].nH; #endif #ifdef TAUGUIDERDONI s_nd = Ext_Ratio * pow(CellArr[idc].z/zstar,spar) * CellArr[idc].nH/NHConst; #else s_nd = ext_zstar * CellArr[idc].z * CellArr[idc].nH; #endif s_sum = s_nH + s_nd; s = t_0 / s_sum; radius = sqrt( SQR(P[ip].x) + SQR(P[ip].y)+ SQR(P[ip].z)); // The position of the photon after consuming its optical depth is computed here: s_ = crossing_cells(P,gtype,ip); rx0 = P[ip].x; ry0 = P[ip].y; rz0 = P[ip].z; ni = P[ip].ni; nj = P[ip].nj; nk = P[ip].nk; } if (EscCond == 1) { #ifndef TEST_RII idc = -1; #else idc = 0; #endif if (idc == -1) { escape: x = P[ip].xp + (P[ip].ni*vbulk_x + P[ip].nj*vbulk_y + P[ip].nk*vbulk_z)/vth; // x = c*(g*nup - nu0)/(vth*nu0) - g*(nup/nu0)*(ni*vbulk_x + nj*vbulk_y + nk*vbulk_z)/vth; // dprintd(x); // printf("Photon has escaped in %ld scatterings\n",nscat); // ................................ inter = 4; (void) time(&t2); op_time = (float) (t2-t1)/60.; // printf("Total calculation took %f minutes.\n",op_time); if (strcmp(OutMode,"Long")==0) { printf("\n"); record_data_long(nscat,ip,x,P[ip].x,P[ip].y,P[ip].z,r0,upar,uper1,uper2,H_x,P[ip].xp,inter); } else { // record_data_short(nscat,ip,x,rxf,ryf,rzf,radius,H_x,inter,op_time,flag_zero); XArr[ip] = x; X0Arr[ip]=xp0; InterArr[ip] = inter; NscatArr[ip] = nscat; #ifdef GETPOSDIR PosArr[3*ip] = P[ip].x; PosArr[3*ip+1] = P[ip].y; PosArr[3*ip+2] = P[ip].z; AngleArr[2*ip] = P[ip].th; AngleArr[2*ip+1]= P[ip].ph; // record_data_pos(nscat,ip,x,ph0,th0,rxf,ryf,rzf,inter,op_time,flag_zero); //#else // record_data_short(nscat,ip,x,ph0,th0,radius,inter,op_time,flag_zero); #endif } nout++; goto end; break; } } else { rx0 = rxf; ry0 = ryf; rz0 = rzf; } P_H = s_nH / s_sum; xi1 = gsl_rng_uniform (r); if (strcmp(IncDust,"Yes")==0) inter = (xi1 <= P_H)? 1 : 2 ; else inter = 1; switch(inter) // inter = 1 means interacting with hydrogen, inter = 2 means dust. { case 1: #ifdef USEREJECTION upar = -999.0; i = 0; do { xi0 = gsl_rng_uniform (r); xi1 = gsl_rng_uniform (r); xi2 = gsl_rng_uniform (r); upar = vp_rejection(xp,a_par,xi0,xi1,xi2); i++; } while(upar == -999.0); // if (i > 100000) // printf("VP_REJECTION TOOK %d tries to get upar = %f, x = %f, nscatter = %d\n" \ ,i,upar,xp,nscat); #endif xi0 = gsl_rng_uniform (r); xi1 = gsl_rng_uniform (r); xi2 = gsl_rng_uniform (r); xi3 = gsl_rng_uniform (r); xi3 = (xi3 == 0.0) ? gsl_rng_uniform (r) : xi3; xi4 = gsl_rng_uniform (r); xi5 = gsl_rng_uniform (r); xi6 = gsl_rng_uniform (r); xi7 = gsl_rng_uniform (r); scattering_hydrogen(P,ip); break; case 2: xi1 = gsl_rng_uniform (r); xi2 = gsl_rng_uniform (r); xi3 = gsl_rng_uniform (r); dust_interaction(P,ip); if (end_syg ==1) goto end; break; } // dprinti(nscat); /* if (nscat == 1000000 || nscat == 10000000 ) { printf("********************************************\n"); printf("Number of scatterings so far: %ld\n",nscat); printf("Photon's location %f %f %f\n",rxf,ryf,rzf); dprintf(x); dprintf(xp); dprintf(th0); dprintf(ph0); } */ #ifdef WRITEALL if (ip < 1000) { x = P[ip].xp + (P[ip].ni*vbulk_x + P[ip].nj*vbulk_y + P[ip].nk*vbulk_z)/vth; record_data_long(nscat,ip,x,P[ip].x,P[ip].y,P[ip].z,r0,upar,uper1,uper2,H_x,\ P[ip].xp,inter); } #endif if (gtype ==1) { if (r0 < 0.99*R_inner) { printf("scatter %d of photon %d occurs within empty zone. Something is not ok\n",nscat,ip); printf("rx/r_inner %f ry/r_inner %f rz/r_inner %f radius/r_inner %f\nidc %d\n",\ P[ip].x/R_inner,P[ip].y/R_inner,P[ip].z/R_inner,r0/R_inner,idc); } } nscat++; } end: // printf("done\n"); if (strcmp(Set_Tolerance,"yes") == 0) { // if ((ip >= np_min && nout >= nout_max) || \ // (ip >= np_max)) if ((ip >= np_min && nout >= nout_max) || \ (ip >= np_max) ) // (ip >= np_max && nout >= (int) nout_max/5) || \ { printf("Max number of absorbed photons or limit on the number of photons reached, exiting...\n"); #ifdef GETPOSDIR printf("Writing data\n"); record_data_pos(ip); printf("File %s written\n",OutShort); free(PosArr); free(AngleArr); #else record_data_short(); #endif free(HList); free(DipList); free(HGList); free(CellArr); exit(0); } } #ifdef TIMELIMIT (void) time(&t4); t4 = (float) (t4-t0)/60.; if (t4 > MAXTIME) { printf("MAXTIME reached, forcing output and exit\n"); #ifdef GETPOSDIR record_data_pos(ip); printf("File %s written\n",OutShort); free(PosArr); free(AngleArr); #else record_data_short(); #endif exit(0); } #endif //printf("%ld %f\n",ip,xp); }
double draw_rnd(gsl_rng *r, uint64_t min, uint64_t max) { return( min + gsl_rng_uniform(r) * (max - min) ); }
/** main simulation loop */ int main() { // init own parameters. initDerivedParams(); // init random generator gsl_rng_env_setup(); r = gsl_rng_alloc(gsl_rng_default); gsl_rng_set(r, SEED_MAIN); // file handle for xxx file FILE *postF = fopen(FILENAME_POST, FILEPOST_FLAG); // file handle for xxx file FILE *preF = fopen(FILENAME_PRE, "wb"); // set up vectors: // to hold post synaptic potentials [unused??] gsl_vector *psp = gsl_vector_alloc(NPRE); // to hold post synaptic potentials 1st filtered gsl_vector *pspS = gsl_vector_alloc(NPRE); // to hold "excitatory" part of psp for Euler integration gsl_vector *sue = gsl_vector_alloc(NPRE); // to hold "inhibitory" part of psp for Euler integration gsl_vector *sui = gsl_vector_alloc(NPRE); // to hold psp 2nd filter gsl_vector *pspTilde = gsl_vector_alloc(NPRE); // to hold weights gsl_vector *w = gsl_vector_alloc(NPRE); // to hold xxx gsl_vector *pres = gsl_vector_alloc(NPRE); // ?? ou XXX \todo #ifdef PREDICT_OU gsl_vector *ou = gsl_vector_alloc(N_OU); gsl_vector *preU = gsl_vector_calloc(NPRE); gsl_vector *wInput = gsl_vector_alloc(N_OU); gsl_matrix *wPre = gsl_matrix_calloc(NPRE, N_OU); double *preUP = gsl_vector_ptr(preU,0); double *ouP = gsl_vector_ptr(ou,0); double *wInputP = gsl_vector_ptr(wInput,0); double *wPreP = gsl_matrix_ptr(wPre,0,0); #endif // get pointers to array within the gsl_vector data structures above. double *pspP = gsl_vector_ptr(psp,0); double *pspSP = gsl_vector_ptr(pspS,0); double *sueP = gsl_vector_ptr(sue,0); double *suiP = gsl_vector_ptr(sui,0); double *pspTildeP = gsl_vector_ptr(pspTilde,0); double *wP = gsl_vector_ptr(w,0); double *presP = gsl_vector_ptr(pres,0); for(int i=0; i<NPRE; i++) { // init pspP etc to zero *(pspP+i) = 0; *(sueP+i) = 0; *(suiP+i) = 0; #ifdef RANDI_WEIGHTS // Gaussian weights *(wP+i) = gsl_ran_gaussian(r, .1); #else *(wP+i) = 0; #endif } //! OU \todo what for? #ifdef PREDICT_OU for(int j=0; j < N_OU; j++) { *(ouP + j) = gsl_ran_gaussian(r, 1) + M_OU; *(wInputP + j) = gsl_ran_lognormal(r, 0., 2.)/N_OU/exp(2.)/2.; for(int i=0; i < NPRE; i++) *(wPreP + j*NPRE + i) = gsl_ran_lognormal(r, 0., 2.)/N_OU/exp(2.)/2.; } #endif // temp variables for the simulation yyyy double u = 0, // soma potential. uV = 0, // some potential from dendrite only (ie discounted // dendrite potential rU = 0, // instantneou rate rV = 0, // rate on dendritic potential only uI = 0, // soma potential only from somatic inputs rI = 0, // rate on somatic potential only uInput = 0; // for OU? // run simulatio TRAININGCYCLES number of times for( int s = 0; s < TRAININGCYCLES; s++) { // for all TIMEBINS for( int t = 0; t < TIMEBINS; t++) { #ifdef PREDICT_OU for(int i = 0; i < N_OU; i++) { *(ouP+i) = runOU(*(ouP+i), M_OU, GAMMA_OU, S_OU); } gsl_blas_dgemv(CblasNoTrans, 1., wPre, ou, 0., preU); #endif // update PSP of our neurons for inputs from all presynaptic neurons for( int i = 0; i < NPRE; i++) { #ifdef RAMPUPRATE /** just read in the PRE_ACT and generate a spike and store it in presP -- so PRE_ACT has inpretation of potential */ updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = spiking(PRE_ACT[t*NPRE + i], gsl_rng_uniform(r))); #elif defined PREDICT_OU //*(ouP+i) = runOU(*(ouP+i), M_OU, GAMMA_OU, S_OU); // why commented out? updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = DT * phi(*(preUP+i)));//spiking(DT * phi(*(preUP+i)), gsl_rng_uniform(r))); // why commented out? #else // PRE_ACT intepreated as spikes updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = PRE_ACT[t*NPRE + i]); #endif } // endfor NPRE #ifdef PREDICT_OU gsl_blas_ddot(wInput, ou, &uInput); GE[t] = DT * phi(uInput); #endif // now update the membrane potential. updateMembrane(&u, &uV, &uI, w, psp, GE[t], GI[t]); // now calculate rates from from potentials. #ifdef POSTSPIKING // usually switch off as learning is faster when // learning from U // with low-pass filtering of soma potential from actual // generation of spikes (back propgating dentric spikes? rU = GAMMA_POSTS*rU + (1-GAMMA_POSTS)*spiking(DT * phi(u), gsl_rng_uniform(r))/DT; #else // simpler -- direct. rU = phi(u); #endif rV = phi(uV); rI = phi(uI); // now update weights based on rU, RV, the 2nd filtered PSP and // the pspSP for(int i = 0; i < NPRE; i++) { updateWeight(wP + i, rU, *(pspTildeP+i), rV, *(pspSP+i)); } #ifdef TAUEFF /** write rU to postF, but only for the last run of the simulation and then only before the STIM_ONSET time -- ie it is the trained output without somatic drive. */ if(s == TRAININGCYCLES - 1 && t < STIM_ONSET/DT) { fwrite(&rU, sizeof(double), 1, postF); } #else /** for every 10th training cycle write all variables below to postF in order: */ if(s%(TRAININGCYCLES/10)==0) { fwrite(&rU, sizeof(double), 1, postF); fwrite(GE+t, sizeof(double), 1, postF); fwrite(&rV, sizeof(double), 1, postF); fwrite(&rI, sizeof(double), 1, postF); fwrite(&u, sizeof(double), 1, postF); } if(s == TRAININGCYCLES - 1) { #ifdef RECORD_PREACT // for the last cycle also record the activity of the // presynaptic neurons fwrite(PRE_ACT + t * NPRE, sizeof(double), 20, preF); //fwrite(ouP, sizeof(double), 20, preF); fwrite(presP, sizeof(double), 20, preF); #else // and the 1st and 2nd filtered PSP fwrite(pspSP, sizeof(double), 1, preF); fwrite(pspTildeP, sizeof(double), 1, preF); #endif } #endif } } fclose(preF); fclose(postF); return 0; }
int main(void) { int i; /* loop counter */ int etauselap; /* elapsed time for etaus */ int mtelap; /* elapsed time for mt19937 */ int ranlxelap; /* elapsed time for ranlxd2 */ unsigned int dttk; /* combined date, time #ticks */ double tot; /* total points within a circle */ double bot; /* 100 million */ double ratio; /* estimated pi/4 */ time_t now; /* current date and time */ clock_t clk; /* current number of ticks */ clock_t etausstart; /* start time for etaus */ clock_t etausfin; /* end time for etaus */ clock_t mtstart; /* start time for mt19937 */ clock_t mtfin; /* end time for mt19937 */ clock_t ranlxstart; /* start time for ranlxd2 */ clock_t ranlxfin; /* end time for ranlxd2 */ struct tms t; /* structure used by times() */ gsl_rng *r; /* GSL RNG structure */ etfmt *et; /* etaus structure */ et = (etfmt *) etausinit(); /* initialize the etaus structure */ bot = 1000000.0; /* set to 1 million */ /************************************************************/ tot = 0.0; /* initialize total points in a circle */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ etausstart = times(&t); /* start time for etaus */ while (i--) /* loop 100 million times */ { double x; /* horizontal value */ double y; /* vertical value */ double sum; /* sum = x*x + y*y */ x = etausunif(et); /* uniform number 0-1 */ y = etausunif(et); /* uniform number 0-1 */ sum = (x*x) + (y*y); /* calculate the vector length */ if (sum < 1.0) tot += 1.0; /* if within a unit circle, tally */ } /* for each point inside or outside a circle */ ratio = tot / bot; /* calculate est. pi/4 */ etausfin = times(&t); /* finish time for etaus */ printf("Monte Carlo Calculation of Pi/4\n"); printf(" n = 1 million\n"); printf(" etaus Pi/4 %18.15f\n", ratio); /************************************************************/ /* allocate the mt19937 random number generator */ /************************************************************/ r = (gsl_rng *) gsl_rng_alloc(gsl_rng_mt19937); /* get clock ticks since boot */ clk = times(&t); /* get date & time */ time(&now); /* combine date, time, and ticks into a single UINT */ dttk = (unsigned int) (now ^ clk); /* initialize the GSL ranlxd2 random number generator */ /* to date,time,#ticks */ gsl_rng_set(r, dttk); /* initialize mt19937 seed */ tot = 0.0; /* initialize total points in a circle */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ mtstart = times(&t); /* start time for GSL mt19937 */ while (i--) /* loop 1 million times */ { double x; /* horizontal value */ double y; /* vertical value */ double sum; /* sum = x*x + y*y */ /* use the mt19937 random number generator this time */ x = gsl_rng_uniform(r); /* uniform number 0-1 */ y = gsl_rng_uniform(r); /* uniform number 0-1 */ sum = (x*x) + (y*y); /* calculate the vector length */ if (sum < 1.0) tot += 1.0; /* if within a unit circle, tally */ } /* for each point inside or outside a circle */ ratio = tot / bot; /* calculate est. pi/4 */ mtfin = times(&t); /* finish time for GSL mt19937 */ printf("GSL mt19937 Pi/4 %18.15f\n", ratio); gsl_rng_free(r); /************************************************************/ /* allocate the ranlxd2 random number generator */ /************************************************************/ r = (gsl_rng *) gsl_rng_alloc(gsl_rng_ranlxd2); /* get clock ticks since boot */ clk = times(&t); /* get date & time */ time(&now); /* combine date, time, and ticks into a single UINT */ dttk = (unsigned int) (now ^ clk); /* initialize the GSL ranlxd2 random number generator */ /* to date,time,#ticks */ gsl_rng_set(r, dttk); /* initialize ranlxd2 seed */ tot = 0.0; /* initialize total points in a circle */ i = (int) bot; /* set loop counter */ /* get clock ticks since boot */ ranlxstart = times(&t); /* start time for GSL ranlxd2 */ while (i--) /* loop 1 million times */ { double x; /* horizontal value */ double y; /* vertical value */ double sum; /* sum = x*x + y*y */ /* use the ranlxd2 random number generator this time */ x = gsl_rng_uniform(r); /* uniform number 0-1 */ y = gsl_rng_uniform(r); /* uniform number 0-1 */ sum = (x*x) + (y*y); /* calculate the vector length */ if (sum < 1.0) tot += 1.0; /* if within a unit circle, tally */ } /* for each point inside or outside a circle */ ratio = tot / bot; /* calculate est. pi/4 */ ranlxfin = times(&t); /* finish time for GSL ranlxd2 */ printf("GSL ranlxd2 Pi/4 %18.15f\n", ratio); printf(" Actual Pi/4 %18.15f\n", M_PI * 0.25); etauselap = etausfin - etausstart; mtelap = mtfin - mtstart; ranlxelap = ranlxfin - ranlxstart; printf(" etaus ticks %6d\n", etauselap); printf("GSL mt19937 ticks %6d\n", mtelap); printf("GSL ranlxd2 ticks %6d\n", ranlxelap); gsl_rng_free(r); free(et->state); free(et); return(0); } /* main */
///////////////////////////////////////////////////////////////////////////// // GetRand() ///////////////////////////////////////////////////////////////////////////// float clModelMath::GetRand() { return (gsl_rng_uniform(randgen)); }
int main() { const double RScale = 0.1; const double AScale = 1.0; const double IScale = 1e-2; const double MScale = 1.0; const double tVScale = 1.0; const double kScale = 0.1; const double eps = 1e-12; gsl_rng *rng; double SpinSun[3]; double tVSun, kSun, ISun, MSun, RSun; double zerov[3] = {0.0, 0.0, 0.0}; body b; central_body bc; double n; double a2; double adot; double ndot; double mu; double body_rhs[BODY_VECTOR_SIZE]; double sun_rhs[3]; double Ldot[3], hdot[3], bLdot[3], sLdot[3]; int i; rng = gsl_rng_alloc(gsl_rng_ranlxd2); assert(rng); seed_random(rng); init_body_from_elements(&b, MScale*gsl_rng_uniform(rng), AScale*gsl_rng_uniform(rng), gsl_rng_uniform(rng), 180.0*gsl_rng_uniform(rng), 360.0*gsl_rng_uniform(rng), 360.0*gsl_rng_uniform(rng), zerov, tVScale*gsl_rng_uniform(rng), kScale*gsl_rng_uniform(rng), IScale*gsl_rng_uniform(rng), RScale*gsl_rng_uniform(rng)); random_vector(rng, b.spin, 1.0); random_vector(rng, SpinSun, 1.0); tVSun = tVScale*gsl_rng_uniform(rng); kSun = kScale*gsl_rng_uniform(rng); ISun = IScale*gsl_rng_uniform(rng); RSun = RScale*gsl_rng_uniform(rng); init_central_body(&bc, tVSun, kSun, ISun, RSun, SpinSun); tidal_rhs(&b, &bc, body_rhs, sun_rhs); n = mean_motion(&b); a2 = b.a*b.a; adot = body_rhs[BODY_a_INDEX]; ndot = -3.0/2.0*adot/b.a*n; mu = b.m/(1.0+b.m); for (i = 0; i < 3; i++) { hdot[i] = mu*n*a2*(body_rhs[BODY_L_INDEX+i] + 0.5*(adot/b.a)*b.L[i]); bLdot[i] = b.I*body_rhs[BODY_SPIN_INDEX+i]; sLdot[i] = ISun*sun_rhs[i]; Ldot[i] = hdot[i] + bLdot[i] + sLdot[i]; } if (!check_close(eps, eps, norm(Ldot), 0.0)) { fprintf(stderr, "Ldot = {%g, %g, %g} not close to zero!\n", Ldot[0], Ldot[1], Ldot[2]); fprintf(stderr, "mu*hdot = {%g, %g, %g}\n", hdot[0], hdot[1], hdot[2]); fprintf(stderr, "Body LDot = {%g, %g, %g}\n", bLdot[0], bLdot[1], bLdot[2]); fprintf(stderr, "Sun LDot = {%g, %g, %g}\n", sLdot[0], sLdot[1], sLdot[2]); gsl_rng_free(rng); exit(1); } if (!check_close(eps, eps, dot(b.L, body_rhs + BODY_L_INDEX) + dot(b.A, body_rhs + BODY_A_INDEX), 0.0)) { fprintf(stderr, "A^2 + L^2 = 1.0 magnitude constraint violated!\n"); exit(1); } if (!check_close(eps, eps, dot(b.L, body_rhs + BODY_A_INDEX) + dot(b.A, body_rhs + BODY_L_INDEX), 0.0)) { fprintf(stderr, "A*L = 0 constraint violated!\n"); exit(1); } gsl_rng_free(rng); return 0; }
/* return a random double */ __inline double random_double_range(gsl_rng *r,double min, double max) { return ((max-min)*gsl_rng_uniform(r)) + min; }
int MoveAgeClonal::move() { // Propose to change a nodes age // reorder the nodes correctly // change the recedge times // account for factors of 2 in passing other clonal nodes // accept/reject step // if reject, put things back correctly bool usetemper=false;// an indicator as to whether tempering is needed if(!changeTopology)s1=0;// probabilities of the return move won't work unless we do this (because 2 reflecting boundaries) double temperllorig=0,temperllto=0,temperllbase=0,temperllfinal=0; double temperpriororig=0,temperpriorto=0,temperpriorbase=0,temperpriorfinal=0; vector<double> store(param->getData()->getL()); for (int i=0;i<param->getData()->getL();i++) store[i]=param->getLLsite(i); double ll=param->getLL(), lprior=param->getRecTree()->prior(param); if(backuptree == NULL) backuptree = new RecTree(*(param->getRecTree())); else backuptree->assign(*(param->getRecTree())); RecTree* rectree = backuptree; if(rectree==0) throw("Cannot create RecTree in MoveAgeClonal!"); RecTree * oldrectree=param->getRecTree(); param->setRecTree(rectree,true); #if defined DEBUG for(int site=0;site<param->getData()->getL();site++) { if(store[site]!=param->getLLsite(site)) cout<<"LL site "<<site<<" recomputed: "<<param->getLLsite(site)<<" difference "<<store[site]-param->getLLsite(site)<<endl; } if(ll!=param->getLL()) cout<<"LL before "<<ll<<" recomputed: "<<param->getLL()<<" difference "<<ll-param->getLL()<<endl; #endif double oldTT=rectree->getTTotal(); int which=rectree->getN() + gsl_rng_uniform_int(rng,rectree->getN()-1),whichto; // reflecting boundaries at daughter and parent nodes to preserve reversability easily double disttodaughter=max(rectree->getNode(which)->getLeft()->getAge(),rectree->getNode(which)->getRight()->getAge())-rectree->getNode(which)->getAge(); double maxdown= -rectree->getNode(which)->getAge(),maxup=10000.0; if(!changeTopology) { maxdown= disttodaughter; if (which<rectree->getN()*2-2) maxup=rectree->getDist(which); } double dist,logqratfort; if(usenormalprop) {// this is the default now. Control sigma using s0 and s1 (set in the constructor) dist = gsl_ran_gaussian(rng,s0+s1*rectree->getNode(which)->getAge());// normal distance with variable sigma logqratfort=logQrat(rectree->getNode(which)->getAge(),rectree->getNode(which)->getAge()+dist); }else { dist = param->getClonalStepSize() * (gsl_rng_uniform(rng) * 2.0 -1.0);// uniform distance logqratfort=0;// do this for the uniform proposal } while(dist< maxdown || dist>maxup) { if(dist< maxdown) dist = 2.0 * maxdown - dist; else if(dist > maxup) dist = 2.0 * maxup - dist; } // figure out if we have to change topology if(dist< disttodaughter || (dist>rectree->getDist(which) && which!=rectree->getN()*2-2)) { numtopo++; usetemper=true; }else { numcalls++; usetemper=false; } dlog(1)<<"Proposing move of node "<< which <<" from age "<<rectree->getNode(which)->getAge()<<" to age "<<rectree->getNode(which)->getAge()+dist<<"..."; // if tempering, set up the moves Metropolis *movetemp; vector<int> samplespace; vector<int> listLR; if(usetemper) { temperllbase=param->getLL()/tempering; temperpriorbase=rectree->prior(param); rectree->chooseNodePath(which, dist, &listLR, &samplespace); movetemp= new Metropolis(param); movetemp->move(reps,tempering,&samplespace); temperllorig=param->getLL()/tempering; temperpriororig=rectree->prior(param); } // Do the move, which returns the samplespace (i.e. affected clonal edges) int propfactor=rectree->moveNodeTime(which,&whichto,dist,-1,&listLR,&samplespace);// propfactor:number of recedges moved to younger nodes - number moved to older nodes param->computeLikelihood(); rectree->computeTTotal(); double logqratio = propfactor*log(2.0)+rectree->numRecEdge()*log(rectree->getTTotal()/oldTT)+logqratfort; if(usetemper) {// and complete the tempering temperllto=param->getLL()/tempering; temperpriorto=rectree->prior(param); movetemp->move(reps,tempering,&samplespace); if(movetemp!=NULL) delete(movetemp); else throw("Error in MoveAgeClonal: movetemp was null!"); temperllfinal=param->getLL()/tempering; temperpriorfinal=rectree->prior(param); } double llend=param->getLL(); #if defined DEBUG //test its ok so far try { rectree->testNodeAges(); } catch(char * x) { cout<<x<<endl<<"Moveageclonal: proposed new node label was "<<whichto<<endl; exit(1); } try { param->testTree(); } catch(char * x) { cout<<x<<endl<<"Moveageclonal: broke the log liks"<<endl; exit(1); } #endif double newlprior=rectree->prior(param); // accept/reject step //cout<<"origll="<<ll<<" temperllorig="<<temperllorig<<" temperllto="<<temperllto<<" llend="<<llend<<" temperpriorto="<<temperpriorto<<" temperpriororig="<<temperpriororig<<" lprior="<<lprior<<" newlprior="<<newlprior<<endl; if(log(gsl_rng_uniform(rng))>llend-ll+newlprior-lprior + temperllto + temperpriorto - temperllorig - temperpriororig + temperllbase + temperpriorbase - temperllfinal - temperpriorfinal + logqratio) { dlog(1)<<" Rejected!"<<endl; // put back the rectree as it was param->setRecTree(oldrectree,true); rectree=oldrectree; // put back the loglikelihoods as they were for (int i=0;i<param->getData()->getL();i++) param->setlocLL(i,store[i]); param->setLL(ll); // everything should now be back how it was #if defined DEBUG //test its still ok int tmp=0; try { rectree->testNodeAges(); } catch(char * x) { cout<<x<<endl<<"Moveageclonal restore: proposed new node label was "<<whichto<<endl; exit(1); } try { param->testTree(); } catch(char * x) { cout<<x<<endl<<"Moveageclonal restore: broke the log liks"<<endl; exit(1); } if(tmp==1) { cerr<<"Problem replacing after move"<<endl; throw("Move not reversed correctly"); } #endif return(0); } else { backuptree=oldrectree; // becomes our new backup tree and we avoid delete dlog(1)<<"Accepted!"<<endl;// accept the modified tree if(usetemper) numtopoaccept++; else numaccept++; return(1); } }
/////////////////////////////////////////// // The simulation // /////////////////////////////////////////// void *sim(void *parameters) { const Params P = *((Params*)parameters); const int k_gen = P.k_gen; const int kernel = P.kernel; const int communities = P.communities; const int j_per_c = P.j_per_c; const int init_species = P.init_species; const int init_pop_size = j_per_c / init_species; const double mu = P.mu; const double s = P.s; const double eta = P.eta; const double width = P.width; const double width2 = width * width; const double sigma = P.var; const double sigma2 = sigma * sigma; // GSL's Taus generator: gsl_rng *rng = gsl_rng_alloc(gsl_rng_taus2); // Initialize the GSL generator with /dev/urandom: const unsigned int seed = devurandom_get_uint(); gsl_rng_set(rng, seed); // Seed with time printf(" <seed>%u</seed>\n", seed); // Used to name the output file: char *buffer = (char*)malloc(100); // Nme of the file: sprintf(buffer, "%s%u.xml", P.ofilename, seed); // Open the output file: FILE *restrict out = fopen(buffer, "w"); // Store the total num. of species/1000 generations: int *restrict total_species = (int*)malloc(k_gen * sizeof(int)); // Number of speciation events/1000 generations: int *restrict speciation_events = (int*)malloc(k_gen * sizeof(int)); // Number of extinctions/1000 generations: int *restrict extinction_events = (int*)malloc(k_gen * sizeof(int)); // Number of speciation events/vertex: int *restrict speciation_per_c = (int*)malloc(communities * sizeof(int)); // Number of local extinction events/vertex: int *restrict extinction_per_c = (int*)malloc(communities * sizeof(int)); // Store the lifespan of the extinct species: ivector lifespan; ivector_init0(&lifespan); // Store the population size at speciation event: ivector pop_size; ivector_init0(&pop_size); // (x, y) coordinates for the spatial graph: double *restrict x = (double*)malloc(communities * sizeof(double)); double *restrict y = (double*)malloc(communities * sizeof(double)); for (int i = 0; i < communities; ++i) { speciation_per_c[i] = 0; extinction_per_c[i] = 0; } // Initialize an empty list of species: species_list *restrict list = species_list_init(); // Initialize the metacommunity and fill them with the initial species evenly: for (int i = 0; i < init_species; ++i) { // Intialize the species and add it to the list: species_list_add(list, species_init(communities, 0, 3)); } // To iterate the list; slnode *it = list->head; // Fill the communities: while (it != NULL) { for (int i = 0; i < communities; ++i) { it->sp->n[i] = init_pop_size; it->sp->genotypes[0][i] = init_pop_size; } it = it->next; } // To iterate the list; const int remainder = j_per_c - (init_species * init_pop_size); for (int i = 0; i < communities; ++i) { it = list->head; for (int j = 0; j < remainder; ++j, it = it->next) { ++(it->sp->n[i]); ++(it->sp->genotypes[0][i]); } } int sum = 0; it = list->head; while (it != NULL) { sum += species_total(it->sp); it = it->next; } assert(sum == j_per_c * communities); #ifdef NOTTOOCLOSE { int count_c = 0; while (count_c < communities) { bool within = false; const double xx = gsl_rng_uniform(rng); const double yy = gsl_rng_uniform(rng); for (int i = 0; i < count_c; ++i) { if (hypot(x[i] - xx, y[i] - yy) < MINDIST) { within = true; // oh nooo, an evil goto! break; } } if (within == false) { x[count_c] = xx; y[count_c] = yy; ++count_c; } } } #else for (int i = 0; i < communities; ++i) { x[i] = gsl_rng_uniform(rng); y[i] = gsl_rng_uniform(rng); } #endif double **m = (double**)malloc(communities * sizeof(double*)); for (int i = 0; i < communities; ++i) { m[i] = (double*)malloc(communities * sizeof(double)); } for (int i = 0; i < communities; ++i) { for (int j = 0; j < communities; ++j) { const double a = x[i] - x[j]; const double b = y[i] - y[j]; const double x = hypot(a, b); assert(distance >= 0.0); if (kernel == gaussian_k) { m[i][j] = (1.0 / sqrt(2 * M_PI * sigma2)) * exp((-x * x) / (2 * sigma2)); } else { m[i][j] = -(eta + 2)/(2 * M_PI * width2) * pow(1 + (x * x) / width2, eta / 2); } } } // Setup the array for migration: double **cmig = setup_cmig(m, communities); fprintf(out, "<?xml version=\"1.0\"?>\n"); fprintf(out, "<simulation>\n"); if (kernel == gaussian_k) { fprintf(out, " <model>Gaussian</model>\n"); } else { fprintf(out, " <model>Fat-tailed</model>\n"); } fprintf(out, " <seed>%u</seed>\n", seed); fprintf(out, " <metacom_size>%d</metacom_size>\n", j_per_c * communities); fprintf(out, " <k_gen>%d</k_gen>\n", k_gen); fprintf(out, " <num_comm>%d</num_comm>\n", communities); fprintf(out, " <individuals_per_comm>%d</individuals_per_comm>\n", j_per_c); fprintf(out, " <initial_num_species>%d</initial_num_species>\n", init_species); fprintf(out, " <mutation_rate>%.2e</mutation_rate>\n", mu); if (kernel == gaussian_k) { fprintf(out, " <variance>%.8e</variance>\n", sigma); } else { fprintf(out, " <width>%.8e</width>\n", width); fprintf(out, " <eta>%.8e</eta>\n", eta); } // To select the species and genotypes to pick and replace: slnode *s0 = list->head; // species0 slnode *s1 = list->head; // species1 int g0 = 0; int g1 = 0; int v1 = 0; // Vertex of the individual 1 ///////////////////////////////////////////// // Groups of 1 000 generations // ///////////////////////////////////////////// for (int k = 0; k < k_gen; ++k) { extinction_events[k] = 0; speciation_events[k] = 0; ///////////////////////////////////////////// // 1 000 generations // ///////////////////////////////////////////// for (int gen = 0; gen < 1000; ++gen) { const int current_date = (k * 1000) + gen; ///////////////////////////////////////////// // A single generation // ///////////////////////////////////////////// for (int t = 0; t < j_per_c; ++t) { ///////////////////////////////////////////// // A single time step (for each community) // ///////////////////////////////////////////// for (int c = 0; c < communities; ++c) { // Select the species and genotype of the individual to be replaced int position = (int)(gsl_rng_uniform(rng) * j_per_c); s0 = list->head; int index = s0->sp->n[c]; while (index <= position) { s0 = s0->next; index += s0->sp->n[c]; } position = (int)(gsl_rng_uniform(rng) * s0->sp->n[c]); if (position < s0->sp->genotypes[0][c]) { g0 = 0; } else if (position < (s0->sp->genotypes[0][c] + s0->sp->genotypes[1][c])) { g0 = 1; } else { g0 = 2; } // Choose the vertex for the individual const double r_v1 = gsl_rng_uniform(rng); v1 = 0; while (r_v1 > cmig[c][v1]) { ++v1; } // species of the new individual position = (int)(gsl_rng_uniform(rng) * j_per_c); s1 = list->head; index = s1->sp->n[v1]; while (index <= position) { s1 = s1->next; index += s1->sp->n[v1]; } if (v1 == c) // local remplacement { const double r = gsl_rng_uniform(rng); const int aa = s1->sp->genotypes[0][v1]; const int Ab = s1->sp->genotypes[1][v1]; const int AB = s1->sp->genotypes[2][v1]; // The total fitness of the population 'W': const double w = aa + Ab * (1.0 + s) + AB * (1.0 + s) * (1.0 + s); if (r < aa / w) { g1 = gsl_rng_uniform(rng) < mu ? 1 : 0; } else { if (AB == 0 || r < (aa + Ab * (1.0 + s)) / w) { g1 = gsl_rng_uniform(rng) < mu ? 2 : 1; } else { g1 = 2; } } } else { // Migration event g1 = 0; } // Apply the changes s0->sp->n[c]--; s0->sp->genotypes[g0][c]--; s1->sp->n[c]++; s1->sp->genotypes[g1][c]++; //////////////////////////////////////////// // Check for local extinction // //////////////////////////////////////////// if (s0->sp->n[c] == 0) { extinction_per_c[c]++; } //////////////////////////////////////////// // Check for speciation // //////////////////////////////////////////// else if (s0->sp->genotypes[2][c] > 0 && s0->sp->genotypes[0][c] == 0 && s0->sp->genotypes[1][c] == 0) { species_list_add(list, species_init(communities, current_date, 3)); // Add the new species const int pop = s0->sp->n[c]; list->tail->sp->n[c] = pop; list->tail->sp->genotypes[0][c] = pop; s0->sp->n[c] = 0; s0->sp->genotypes[2][c] = 0; // To keep info on patterns of speciation... ivector_add(&pop_size, pop); ++speciation_events[k]; ++speciation_per_c[c]; } } // End 'c' } // End 't' // Remove extinct species from the list and store the number of extinctions. extinction_events[k] += species_list_rmv_extinct2(list, &lifespan, current_date); } // End 'g' total_species[k] = list->size; } // End 'k' ////////////////////////////////////////////////// // PRINT THE FINAL RESULTS // ////////////////////////////////////////////////// fprintf(out, " <global>\n"); fprintf(out, " <avr_lifespan>%.4f</avr_lifespan>\n", imean(lifespan.array, lifespan.size)); fprintf(out, " <median_lifespan>%.4f</median_lifespan>\n", imedian(lifespan.array, lifespan.size)); fprintf(out, " <avr_pop_size_speciation>%.4f</avr_pop_size_speciation>\n", imean(pop_size.array, pop_size.size)); fprintf(out, " <median_pop_size_speciation>%.4f</median_pop_size_speciation>\n", imedian(pop_size.array, pop_size.size)); fprintf(out, " <speciation_per_k_gen>"); int i = 0; for (; i < k_gen - 1; ++i) { fprintf(out, "%d ", speciation_events[i]); } fprintf(out, "%d</speciation_per_k_gen>\n", speciation_events[i]); fprintf(out, " <extinctions_per_k_gen>"); for (i = 0; i < k_gen - 1; ++i) { fprintf(out, "%d ", extinction_events[i]); } fprintf(out, "%d</extinctions_per_k_gen>\n", extinction_events[i]); fprintf(out, " <extant_species_per_k_gen>"); for (i = 0; i < k_gen - 1; ++i) { fprintf(out, "%d ", total_species[i]); } fprintf(out, "%d</extant_species_per_k_gen>\n", total_species[i]); // Print global distribution fprintf(out, " <species_distribution>"); ivector species_distribution; ivector_init1(&species_distribution, 128); it = list->head; while (it != NULL) { ivector_add(&species_distribution, species_total(it->sp)); it = it->next; } ivector_sort_asc(&species_distribution); ivector_print(&species_distribution, out); fprintf(out, "</species_distribution>\n"); double *octaves; int oct_num = biodiversity_octaves(species_distribution.array, species_distribution.size, &octaves); fprintf(out, " <octaves>"); for (i = 0; i < oct_num; ++i) { fprintf(out, "%.2f ", octaves[i]); } fprintf(out, "%.2f</octaves>\n", octaves[i]); fprintf(out, " </global>\n"); // Print info on all vertices double *restrict ric_per_c = (double*)malloc(communities * sizeof(double)); for (int c = 0; c < communities; ++c) { fprintf(out, " <vertex>\n"); fprintf(out, " <id>%d</id>\n", c); fprintf(out, " <xcoor>%.4f</xcoor>\n", x[c]); fprintf(out, " <ycoor>%.4f</ycoor>\n", y[c]); fprintf(out, " <total_mig_rate>%.8f</total_mig_rate>\n", 1.0 - ((c==0)?cmig[0][0]:cmig[c][c]-cmig[c][c-1])); fprintf(out, " <speciation_events>%d</speciation_events>\n", speciation_per_c[c]); fprintf(out, " <extinction_events>%d</extinction_events>\n", extinction_per_c[c]); int vertex_richess = 0; ivector_rmvall(&species_distribution); it = list->head; while (it != NULL) { ivector_add(&species_distribution, it->sp->n[c]); it = it->next; } // Sort the species distribution and remove the 0s ivector_sort_asc(&species_distribution); ivector_trim_small(&species_distribution, 1); ric_per_c[c] = (double)species_distribution.size; fprintf(out, " <species_richess>%d</species_richess>\n", species_distribution.size); fprintf(out, " <species_distribution>"); ivector_print(&species_distribution, out); fprintf(out, "</species_distribution>\n"); // Print octaves free(octaves); oct_num = biodiversity_octaves(species_distribution.array, species_distribution.size, &octaves); fprintf(out, " <octaves>"); for (i = 0; i < oct_num - 1; ++i) { fprintf(out, "%.2f ", octaves[i]); } fprintf(out, "%.2f</octaves>\n", octaves[i]); fprintf(out, " </vertex>\n"); } fprintf(out, "</simulation>\n"); sprintf(buffer, "%s%u-bc.xml", P.ofilename, seed); FILE *restrict obc = fopen(buffer, "w"); fprintf(obc, "<dissimilarity>\n"); for (int i = 0; i < communities; ++i) { for (int j = 0; j < communities - i; ++j) { const double a = x[i] - x[j]; const double b = y[i] - y[j]; int sum = 0; s0 = list->head; while (s0 != NULL) { const int n_a = s0->sp->n[i]; const int n_b = s0->sp->n[j]; if (n_a > 0 && n_b > 0) { sum += MIN(n_a, n_b); } s0 = s0->next; } const double bray_curtis = ((double)sum) / j_per_c; fprintf(obc, " <pair><distance>%.8f</distance><bc>%.8f</bc></pair>\n", hypot(a, b), bray_curtis); } } fprintf(obc, "</dissimilarity>\n"); ////////////////////////////////////////////////// // EPILOGUE... // ////////////////////////////////////////////////// // Close files; fclose(out); fclose(obc); // Free arrays; free(x); free(y); free(ric_per_c); //free(spe_per_c); free(buffer); free(total_species); free(octaves); free(speciation_per_c); free(extinction_per_c); free(speciation_events); free(extinction_events); // Free structs; species_list_free(list); ivector_free(&species_distribution); ivector_free(&lifespan); ivector_free(&pop_size); gsl_rng_free(rng); return NULL; }