void Sporulation::SporeGen(Img& I, double *weather, double rate){ //unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); //std::default_random_engine generator(seed); int height = I.getHeight(); int width = I.getWidth(); if(!sp){ sp = (int **)CPLMalloc(sizeof(int *) * height); int *stream = (int *)CPLMalloc(sizeof(int)*width*height); for(int i=0;i<height;i++){ sp[i] = &stream[i*width]; } } for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ if(I.data[i][j]>0){ double lambda = rate * weather[i*width+j]; int sum=0; poisson_distribution<int> distribution(lambda); for(int k=0;k<I.data[i][j];k++){ sum += distribution(generator); } sp[i][j] = sum; } } } }
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; } } } } } } } }