Exemplo n.º 1
0
void Sporulation::SporeSpreadDisp(Img& S_umca, Img& S_oaks, Img& I_umca, Img& I_oaks, Img& lvtree_rast, 
	Rtype rtype, double *weather, double scale1, int kappa, Direction wdir, 
	double scale2,double gamma){

	//unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  	//std::default_random_engine generator(seed);
  	std::cauchy_distribution<double> distribution_cauchy_one(0.0,scale1);
  	std::cauchy_distribution<double> distribution_cauchy_two(0.0,scale2);
  	std::bernoulli_distribution distribution_bern(gamma);
  	std::uniform_real_distribution<double> distribution_uniform(0.0,1.0);


	int height = S_umca.getHeight();
	int width = S_umca.getWidth();
	int w_e_res = S_umca.getWEResolution();
	int n_s_res = S_umca.getNSResolution();

	double dist=0;
	double theta = 0;

	if(!sp){
		cerr << "The spore matrix is empty!" << endl;
		return;	
	}

	for(int i=0;i<height;i++){
		for(int j=0;j<width;j++){
			if(sp[i][j]>0){
				for(int k=0;k<sp[i][j];k++){

					// generate the distance from cauchy distribution or cauchy mixture distribution
					if(rtype == CAUCHY){
						dist = abs(distribution_cauchy_one(generator));
					}else if(rtype == CAUCHY_MIX){
						if(gamma >= 1 || gamma <= 0){
							cerr << "The parameter gamma must be in the range (0~1)" << endl;
							return;
						}
						// use bernoulli distribution to act as the sampling with prob(gamma,1-gamma)
						if(distribution_bern(generator))
							dist = abs(distribution_cauchy_one(generator));
						else
							dist = abs(distribution_cauchy_two(generator));
					}else{
						cerr << "The paramter Rtype muse be set as either CAUCHY OR CAUCHY_MIX" << endl;
						exit(EXIT_FAILURE);
					}

					if(wdir == NO){
						kappa = 0;
					}

					theta = vonmisesvariate(wdir*PI/180,kappa);

					int row = i - round(dist*cos(theta) / n_s_res);
					int col = j + round(dist*sin(theta) / w_e_res);

					if(row<0 || row>=height) continue;
					if(col<0 || col>= width) continue;

					if(row == i && col == j){
						if(S_umca.data[row][col] >0 || S_oaks.data[row][col] >0){
							double prob = (double)(S_umca.data[row][col]+S_oaks.data[row][col]) / lvtree_rast.data[row][col];

							double U = distribution_uniform(generator);
							prob = prob*weather[row*width+col];

							// if U < prob, then one host will become infected
							if(U<prob){
								double prob_S_umca = (double)(S_umca.data[row][col]) / (
										S_umca.data[row][col]+S_oaks.data[row][col]);
								double prob_S_oaks = (double)(S_oaks.data[row][col]) / (
										S_umca.data[row][col]+S_oaks.data[row][col]);

								std::bernoulli_distribution distribution_bern_prob(prob_S_umca);
								if(distribution_bern_prob(generator)){
									I_umca.data[row][col] +=1;
									S_umca.data[row][col] -=1;
								}else{
									I_oaks.data[row][col] +=1;
									S_oaks.data[row][col] -=1;
								}
							}
						}
					}else{
						if(S_umca.data[row][col]>0){
							double prob_S_umca = (double)(S_umca.data[row][col]) / lvtree_rast.data[row][col];
							double U = distribution_uniform(generator);
							prob_S_umca *= weather[row*width+col];
							if(U<prob_S_umca){
								I_umca.data[row][col] +=1;
								S_umca.data[row][col] -=1;
							}
						}
					}
				}
			}
		}
	}
}