void Random::sphere(Real & x, Real & y, Real & z) { // Adapted from: Robert E. Knop, "Algorithm 381: Random Vectors Uniform in Solid Angle", CACM, 13, p326, 1970. // It uses the fact that the projection of the uniform 2-sphere distribution onto any axis (in this case the Z axis) is // uniform. Real m2; // squared magnitude do { x = 2 * uniform01() - 1; y = 2 * uniform01() - 1; m2 = x * x + y * y; } while (m2 > 1 || m2 < 1e-10); // The squared length happens to be uniformly distributed in [0, 1]. Since the projection of the 2-sphere distribution onto // the Z axis is uniform (can be derived from the observation that the area of a spherical cap is linear in its height), we // can use the squared length, rescaled to [-1, 1], as the Z value (latitude). z = 2 * m2 - 1; // x and y now locate the longitude of the point after scaling to lie on the sphere Real s = 2 * std::sqrt(1 - m2); // this factor ensures x^2 + y^2 + z^2 = 1 x *= s; y *= s; }
void RNG::disk(double r_min, double r_max, double& x, double& y) { double a = uniform01(); double b = uniform01(); double r = std::sqrt(a * r_max * r_max + (1 - a) * r_min * r_min); double theta = 2 * boost::math::constants::pi<double>() * b; x = r * std::cos(theta); y = r * std::sin(theta); }
/** Randomly rounds a float up or down s.t. the expected value is the given value */ inline unsigned int RandomRound(float x) { if(x <= 0.0f) { return 0; } float a = std::floor(x); float r = x - a; boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > uniform01( Rnd(), boost::uniform_real<float>(0.0f,1.0f)); return a + (uniform01() >= r ? 0.0f : 1.0f); }
void Random::cosPowHemi(Real const k, Real & x, Real & y, Real & z) { Real const e1 = uniform01(); Real const e2 = uniform01(); Real const cos_theta = std::pow(e1, 1.0f / (k + 1.0f)); Real const sin_theta = std::sqrt(1.0f - Math::square(cos_theta)); Real const phi = 6.28318531f * e2; x = std::cos(phi) * sin_theta; y = std::sin(phi) * sin_theta; z = cos_theta; }
void Tree::generate(uint8_t limit) { const uint8_t m_trunkHeight = uniformUINT8(MIN_TRUNK, limit); bool smalltree = false; uint8_t type = 0; if (m_trunkHeight < BRANCHING_HEIGHT) { smalltree = true; } if (uniform01() > 0.5) // 1/2 chance { ++type; if (uniform01() > 0.5) // 1/4 { ++type; } } for (unsigned int i = 0; i + 1 < m_trunkHeight /* Trunk Height */; ++i) { if (smalltree) { const TrunkPtr v(new Trunk(_x, _y + i, _z, _map, type)); if (i >= MIN_TRUNK - 1) { m_Branch[n_branches++] = v; } } else { const TrunkPtr v(new Trunk(_x, _y + i, _z, _map, type)); if (i > BRANCHING_HEIGHT - 1) { generateBranches(v); m_Branch[n_branches++] = v; } } } const TrunkPtr v(new Trunk(_x, _y + m_trunkHeight - 1, _z, _map, type)); generateBranches(v); generateCanopy(); m_Branch[n_branches++] = v; }
double simulator::drawNextEventInterval() { /// Draw the next event time // Infection double A_S = _beta*_count_I*_count_S/_popSize; //DEBUG if(_count_I !=_prevalence[_prevalence.size()-1]){ cout<< "_count_I:"<<_count_I << "; prevalence[t]:"<<_prevalence[_prevalence.size()-1]<<endl; } // Latency progressions double A_E = 0.0; for(int i=1; i<=_nE; i++) A_E += _sigma[i-1]*census_status(i); // Infectiousness progressions // and ultimately recovery double A_I = 0.0; for(int i=_nE+1; i<=_nE+_nI; i++) A_I += _gamma[i-1-_nE]*census_status(i); // Sum of all rates double A = A_S+A_E+A_I; double u = uniform01(); return -log(u)/A; }
void RNG::ball(double r_min, double r_max, double& x, double& y, double& z) { double a = uniform01(); double b = uniform01(); double c = uniform01(); double r = std::pow(a * r_max * r_max * r_max + (1 - a) * r_min * r_min * r_min, 1 / 3.0); double theta = std::acos(1 - 2 * b); double phi = 2 * boost::math::constants::pi<double>() * c; double costheta = std::cos(theta); double sintheta = std::sin(theta); double cosphi = std::cos(phi); double sinphi = std::sin(phi); x = r * costheta; y = r * sintheta * cosphi; z = r * sintheta * sinphi; }
static double pareto(double xm, double k, double max) { // xm > 0 and k > 0 double r; do r = xm / std::pow(uniform01(), 1.0 / k); while (r > max); return r; }
std::vector<int> RNG::NchooseM(int n, int m) { std::vector<int> ret(m, 100); int ctr = m; for (int i = 0; i < n; i++) if (uniform01(gen) < ctr * 1.0 / (n - i)) ret[m - ctr--] = i; return ret; }
void Tree::generateCanopy() { uint8_t block, meta; uint8_t canopySize; uint8_t canopy_type = 0; int32_t t_posx, t_posy, t_posz; if (uniform01() > 0.5) // 1/2 { canopy_type++; if (uniform01() > 0.5) // 1/4 { canopy_type++; } } canopySize = 3; //canopySize = (BetterRand()*(MAX_CANOPY - MIN_CANOPY)) + MIN_CANOPY; for (uint8_t i = 0; i < n_branches; i++) { for (int8_t xi = (-canopySize); xi <= canopySize; xi++) { for (int8_t yi = (-canopySize); yi <= canopySize; yi++) { for (int8_t zi = (-canopySize); zi <= canopySize; zi++) { if (abs(xi) + abs(yi) + abs(zi) <= canopySize) { t_posx = m_Branch[i]->_x + xi; t_posy = m_Branch[i]->_y + yi; t_posz = m_Branch[i]->_z + zi; if (ServerInstance->map(_map)->getBlock(t_posx, t_posy, t_posz, &block, &meta, true) && block == BLOCK_AIR) { Canopy u(t_posx, t_posy, t_posz, _map, canopy_type); } } } } } } }
void Random::cosHemi(Real & x, Real & y, Real & z) { Real const e1 = uniform01(); Real const e2 = uniform01(); // Jensen's method Real const sin_theta = std::sqrt(1.0f - e1); Real const cos_theta = std::sqrt(e1); Real const phi = 6.28318531f * e2; x = std::cos(phi) * sin_theta; y = std::sin(phi) * sin_theta; z = cos_theta; // We could also use Malley's method (pbrt p.657), since they are the same cost: // // r = sqrt(e1); // t = 2*pi*e2; // x = cos(t)*r; // y = sin(t)*r; // z = sqrt(1.0 - x*x + y*y); }
void Tree::generateBranches(TrunkPtr wrap) { int32_t x = wrap->_x; uint8_t y = wrap->_y; int32_t z = wrap->_z; uint32_t schanse = BRANCHING_CHANCE; if (uniform01() > 1.0 - (1.0 / BRANCHING_CHANCE)) { const double r = uniform01(); if (r < 0.2) { x--; } else if (r < 0.4) { x++; } else if (r < 0.6) { z++; } else if (r < 0.8) { z--; } if (r > 0.5) { y++; } const TrunkPtr v(new Trunk(x, y, z, _map)); m_Branch[n_branches++] = v; generateBranches(v); } }
void NetherGen::AddDeposit(int x, int y, int z, int map, uint8_t block, int depotSize) { for (int bX = x; bX < x + depotSize; bX++) { for (int bY = y; bY < y + depotSize; bY++) { for (int bZ = z; bZ < z + depotSize; bZ++) { if (uniform01() < 0.5) { ServerInstance->map(map)->sendBlockChange(bX, bY, bZ, block, 0); ServerInstance->map(map)->setBlock(bX, bY, bZ, block, 0); } } } } }
// Return a random int in interval [min, max] with step static int uniform(int min, int max, int step = 1) { int r = min + step * ((int)std::ceil(std::floor((double)(max - min) / (double)step + 1.0) * uniform01()) - 1); return r; }
double tools_uniform01() { return uniform01(); }
unsigned int simulator::drawEventType() { /// Determine which event type occurs /// (after an event time has been drawn) vector<double> x; // sufficiently small such that probability to fall // b/w x and x+tiny is pratically 0 but large enough // that a 'double comparison' recognizes it // (used when no indiv in a given status) double tiny = 1E-10; // Anchor at 0 x.push_back(0.0); // New infection event double tmp = at_least_one_S_and_I()?_beta*_count_I*_count_S/_popSize:tiny; x.push_back(tmp); // Migrations through the E[k] for(int i=0; i<_nE; i++) { double tmp = (census_status(i+1)>0)?_sigma[i]*census_status(i+1):tiny; x.push_back(tmp); } // Migrations through the I[k] for(int i=0; i<_nI; i++) { double tmp = (census_status(_nE+1+i)>0)?_gamma[i]*census_status(_nE+1+i):tiny; x.push_back(tmp); } // draw a uniform on sum of all rates and // see where it lands -> that's the drawn event type double u = uniform01()*sumElements(x); // cout<<"drawEventType: "<<u<<" :: " <<sumElements(x)<<endl; // vector of cumulative sum of x elements vector<double> cumx; for(int i=0; i<x.size(); i++) { // initialize sum at 0 cumx.push_back(0.0); // Calculate cumulative value for(int j=0; j<=i; j++) cumx[i]+=x[j]; } unsigned int idx = 0; bool found = false; for(int i=0; i<cumx.size(); i++) { if(cumx[i]<u) { idx = i; found = true; } } stopif(!found, "can't find index"); // Make sure there is an individual // in the drawn event (they may be very close, see 'tiny') if (census_status(idx)==0) { unsigned int idx2 = idx; while (census_status(idx2)==0) idx2=idx2-1; idx=idx2; } return idx; }
static double exponential(double mean) { double r = - std::log(uniform01()) * mean; return r; }
// Return a random double in interval (min, max] static double uniform(double min, double max) { double r = min + (max - min) * uniform01(); return r; }
int RNG::bernoulli(float p) { if (uniform01(gen) < p) return 1; else return 0; }
float RNG::uniform(float a, float b) { return a + (b - a) * uniform01(gen); }
void BiomeGen::AddTrees(int x, int z, int map) { int32_t xBlockpos = x << 4; int32_t zBlockpos = z << 4; int blockX, blockZ; uint8_t blockY, block, meta; bool empty[16][16]; // is block empty memset(empty, 1, 256); uint8_t trees = uint8_t(uniform01() * 7 + 13); uint8_t i = 0; while (i < trees) { uint8_t a = uint8_t(uniform01() * 16); uint8_t b = uint8_t(uniform01() * 16); if (empty[a][b]) { blockX = a + xBlockpos; blockZ = b + zBlockpos; blockY = heightmap_pointer[(b<<4)+a]; // Another dirty haxx! if (blockY > 120) { i++; continue; } ServerInstance->map(map)->getBlock(blockX, blockY, blockZ, &block, &meta); int biome = int(BiomeSelect.GetValue(blockX / 100.0, 0, blockZ / 100.0)); if (biome == 1 && treenoise.GetValue(blockX, 0, blockZ) > -0.3 && ((rand() % 16) < 7)) // Dirty haxx! { // Desert, make cactus int count = 3; if ((count + blockY) > 126) { continue; } //LOGLF("testing reed area"); ServerInstance->map(map)->getBlock(blockX, (blockY + i), blockZ, &block, &meta); if(block == BLOCK_SAND){ ServerInstance->map(map)->setBlock(blockX, (blockY + 1 + i), blockZ, (char)BLOCK_CACTUS, (char)meta); ServerInstance->map(map)->setBlock(blockX, (blockY + 2 + i), blockZ, (char)BLOCK_CACTUS, (char)meta); ServerInstance->map(map)->setBlock(blockX, (blockY + 3 + i), blockZ, (char)BLOCK_CACTUS, (char)meta); //printf("successful cactus! x%d y%d z%d\n", blockX, blockY, blockZ); } // Check that it's not in water /*ServerInstance->map(map)->getBlock(blockX, ++blockY, blockZ, &block, &meta); if (!(block == BLOCK_WATER || block == BLOCK_STATIONARY_WATER)) { sChunk* chunk = ServerInstance->map(map)->getChunk(x, z); uint8_t* curBlock; int count = (fastrand() % 3) + 3; if (count + blockY > 127) { continue; } curBlock = &(chunk->blocks[(a << 7) + (b << 11) + blockY]); for (int i = 0; i < count; i++) { curBlock[i] = BLOCK_CACTUS; } }*/ } else if (biome == 4 && block != BLOCK_WATER && block != BLOCK_STATIONARY_WATER && treenoise.GetValue(blockX, 0, blockZ) > -0.2) { //Reed forest int count = 3; if ((count + blockY) > 126) { continue; } //LOGLF("testing reed area"); int xOffset = 0; ServerInstance->map(map)->getBlock(blockX + xOffset, (blockY + i), blockZ, &block, &meta); if(block == BLOCK_DIRT || block == BLOCK_REED || block == BLOCK_GRASS){ if(block == BLOCK_GRASS){ ServerInstance->map(map)->setBlock(blockX + xOffset, (blockY + i), blockZ, (char)BLOCK_DIRT, (char)meta); block = BLOCK_DIRT; } ServerInstance->map(map)->setBlock(blockX + xOffset, (blockY + 1 + i), blockZ, (char)BLOCK_REED, (char)meta); ServerInstance->map(map)->setBlock(blockX + xOffset, (blockY + 2 + i), blockZ, (char)BLOCK_REED, (char)meta); ServerInstance->map(map)->setBlock(blockX + xOffset, (blockY + 3 + i), blockZ, (char)BLOCK_REED, (char)meta); //printf("successful reed! x%d y%d z%d\n", blockX + xOffset, blockY, blockZ); } } else if (biome == 2 || biome == 3) { if (block == BLOCK_DIRT || block == BLOCK_GRASS) { // Trees only grow on dirt and grass? =b ServerInstance->map(map)->getBlock(blockX, ++blockY, blockZ, &block, &meta); if (block == BLOCK_AIR || block == BLOCK_SNOW) { if (treenoise.GetValue(blockX, 0, blockZ) > -0.4) { Tree tree(blockX, blockY, blockZ, map); } } } } for (int8_t u = -2; u < 2; u++) { for (int8_t v = -2; v < 2; v++) { //Check for array boundaries if((a+u) >= 0 && (b+v) >= 0 && (a+u) < 16 && (b+v) < 16) { empty[a+u][b+v] = false; } } } i++; } } }
void KmeansClusterer::chooseInitialClusterCenters(RefArrayXXd sample, RefArrayXXd centers, unsigned int Nclusters) { unsigned int Npoints = sample.cols(); // Set up a some random generators uniform_real_distribution<> uniform01(0.0, 1.0); uniform_int_distribution<> uniform(0, Npoints-1); // Picking the initial centers randomly is prone to leading to a local rather than // the global minumum. Choosing k centers as far away from each other as possible // is prone to outliers. We therefore adopt the method of Arthur & Vassilvitskii (2007) // which instead of always choosing a new center farthest from those picked so far, // chooses each center at random with a probability proportional to its (squared) // distance from the centers chosen already. // Choose the first center randomly int randomPointIndex = uniform(engine); int k; double distanceToClosestCenter[Npoints]; double sumOfDistancesToClosestCenters; double distance; double uniform01Number; double cumulativeDistance; centers.col(0) = sample.col(randomPointIndex); // Select the other initial centers probabilistically for (int n = 1; n < Nclusters; ++n) { // For each of the points in the sample, determine the distance to // its closest center sumOfDistancesToClosestCenters = 0.0; for (int k = 0; k < Npoints; ++k) { for (int j = 0; j < n; ++j) { distance = metric.distance(sample.col(k), centers.col(j)); if (j == 0) { // This is the very first center we're checking, so let's adopt // this initially as the closest center. distanceToClosestCenter[k] = distance; } else { // Compare with the previous distance to the closest center. // If it is even smaller, we've found an even closer center. // In that case, keep the distance value. if (distance < distanceToClosestCenter[k]) { distanceToClosestCenter[k] = distance; } } } sumOfDistancesToClosestCenters += distanceToClosestCenter[k]; } // Normalize the distances for (int k = 0; k < Npoints; ++k) { distanceToClosestCenter[k] /= sumOfDistancesToClosestCenters; } // Generate a uniform random number between 0 and 1 uniform01Number = uniform01(engine); // Select the point that makes the cumulative distance greater than the random // number. Those points with a larger distance to their closest center, will have // a greater chance to be chosen as the next cluster center point, than the others. cumulativeDistance = distanceToClosestCenter[0]; k = 0; while (cumulativeDistance < uniform01Number) { k++; cumulativeDistance += distanceToClosestCenter[k]; } centers.col(n) = sample.col(k); } // end loop of selecting initial cluster centers }
static double normal(double mu, double sigma) { const double pi = 3.14159265358979323846; //approximate value of pi double r = mu + sigma * std::sqrt(-2.0 * std::log(uniform01())) * std::cos(2.0 * pi * uniform01()); return r; }