Ejemplo n.º 1
0
  /**
   * @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);
  }
Ejemplo n.º 2
0
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];
    }
}
Ejemplo n.º 3
0
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);  
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
		/*!**********************************************************************
		 * \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;
			}
		}
Ejemplo n.º 6
0
float randf()
{
    return gsl_rng_uniform(r);
}
Ejemplo n.º 7
0
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;
		}
Ejemplo n.º 9
0
int GSLRNG_uniform(stEval *args, stEval *result, void *i) {
    gsl_rng *r = STPOINTER(&args[0]);
    STDOUBLE(result) = gsl_rng_uniform(r);
    return EC_OK;
}
Ejemplo n.º 10
0
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_++;
}
Ejemplo n.º 11
0
double Random::uniform()
{
	return gsl_rng_uniform(this->randomGeneratorHandle);
}
Ejemplo n.º 12
0
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;
	}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
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); }
}
Ejemplo n.º 15
0
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);
    }
  }
}
Ejemplo n.º 16
0
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]);
	}
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
double GslRandGen::uniform(void)
{
  return  gsl_rng_uniform(r);
}
Ejemplo n.º 19
0
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 */
Ejemplo n.º 20
0
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; 
      }   
   }
  } 
}
Ejemplo n.º 21
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");
}
Ejemplo n.º 22
0
Archivo: main.c Proyecto: jemejia/LyaRT
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);


	}
Ejemplo n.º 23
0
double draw_rnd(gsl_rng *r, uint64_t min, uint64_t max) {
  return( min + gsl_rng_uniform(r) * (max - min) );
}
Ejemplo n.º 24
0
/**
 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;
}
Ejemplo n.º 25
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 */
Ejemplo n.º 26
0
/////////////////////////////////////////////////////////////////////////////
// GetRand()
/////////////////////////////////////////////////////////////////////////////
float clModelMath::GetRand() {
  return (gsl_rng_uniform(randgen));
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
0
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);
    }
}
Ejemplo n.º 30
0
Archivo: main.c Proyecto: PhDP/jsm
///////////////////////////////////////////
// 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;
}