/** * @brief Gets a random double that follows the gaussian distribution. */ double rand_double_gaussian (void) { double theta, rsq; theta = rand_double_range( 0., 2.*M_PI ); rsq = rand_double_exponential( 0.5 ); return (sqrt(rsq) * cos(theta)); }
void randomvals_int (t_randomvals *x, t_atom_long value) { t_rand_gen *gen = &x->gen; double *means = x->means; double *devs = x->devs; double *weights = x->weights; double *lo_bounds = x->lo_bounds; double *hi_bounds = x->hi_bounds; double randval, mean, dev, lo_bound, hi_bound; long i; long num_params = x->num_params; if (value >= 2) { // Summed windowed gaussians random distribution // Choose a mean and dev pair based on weighting randval = rand_double_n(gen, weights[num_params - 1]); for (i = 0; i < num_params - 1; i++) if (randval < weights[i]) break; // Generate a windowed gaussian number (between 0 and 1) using a fast implementation mean = means[i]; dev = devs[i]; lo_bound = lo_bounds[i]; hi_bound = hi_bounds[i]; randval = ltqnorm(0.5 + 0.5 * rand_double_range(gen, lo_bound, hi_bound)) * dev + mean; if (randval > 1.) randval = 1.; if (randval < 0.) randval = 0.; } else { // Generate a flat distribution random number between 0 and 1 randval = rand_double(gen); } outlet_float(x->the_outlet, randval); }
/** * @brief Gets an int in range [low,high]. */ int rand_int_range( int low, int high ) { return (int)round( rand_double_range( (double)low, (double)high ) ); }
void randomvals_perform64 (t_randomvals *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long vec_size, long flags, void *userparam) { // Set pointers double *in = ins[0]; double *out = outs[0]; t_rand_gen *gen = &x->gen; double *means = x->means; double *devs = x->devs; double *weights = x->weights; double *lo_bounds = x->lo_bounds; double *hi_bounds = x->hi_bounds; double randval, mean, dev, lo_bound, hi_bound; long test, i; long num_params = x->num_params; while (vec_size--) { test = *in++; if (test >= 1) { if (test >= 2) { // Summed windowed gaussians random distribution // Choose a mean and dev pair based on weighting randval = rand_double_n(gen, weights[num_params - 1]); for (i = 0; i < num_params - 1; i++) if (randval < weights[i]) break; // Generate a windowed gaussian number (between 0 and 1) using a fast implementation mean = means[i]; dev = devs[i]; lo_bound = lo_bounds[i]; hi_bound = hi_bounds[i]; randval = ltqnorm(0.5 + 0.5 * rand_double_range(gen, lo_bound, hi_bound)) * dev + mean; if (randval > 1.) randval = 1.; if (randval < 0.) randval = 0.; } else { // Generate a flat distribution random number between 0 and 1 randval = rand_double(gen); } } else { // Output zeros randval = 0; } *out++ = randval; } }
t_int *randomvals_perform (t_int *w) { // Set pointers float *in = (float *) w[1]; float *out = (float *) w[2]; long vec_size = w[3]; t_randomvals *x = (t_randomvals *) w[4]; t_rand_gen *gen = &x->gen; double *means = x->means; double *devs = x->devs; double *weights = x->weights; double *lo_bounds = x->lo_bounds; double *hi_bounds = x->hi_bounds; double randval, mean, dev, lo_bound, hi_bound; long test, i; long num_params = x->num_params; while (vec_size--) { test = *in++; if (test >= 1) { if (test >= 2) { // Summed windowed gaussians random distribution // Choose a mean and dev pair based on weighting randval = rand_double_n(gen, weights[num_params - 1]); for (i = 0; i < num_params - 1; i++) if (randval < weights[i]) break; // Generate a windowed gaussian number (between 0 and 1) using a fast implementation mean = means[i]; dev = devs[i]; lo_bound = lo_bounds[i]; hi_bound = hi_bounds[i]; randval = ltqnorm(0.5 + 0.5 * rand_double_range(gen, lo_bound, hi_bound)) * dev + mean; if (randval > 1.) randval = 1.; if (randval < 0.) randval = 0.; } else { // Generate a flat distribution random number between 0 and 1 randval = rand_double(gen); } } else { // Output zeros randval = 0; } *out++ = randval; } return w + 5; }