static GnmValue * gnumeric_randexp (GnmFuncEvalInfo *ei, GnmValue const * const *argv) { gnm_float x = value_get_as_float (argv[0]); return value_new_float (random_exponential (x)); }
static gboolean tool_random_engine_run_exponential (data_analysis_output_t *dao, tools_data_random_t *info, exponential_random_tool_t *param) { int i, n; for (i = 0; i < info->n_vars; i++) { for (n = 0; n < info->count; n++) { gnm_float v; v = random_exponential (param->b); dao_set_cell_float (dao, i, n, v); } } return FALSE; }
// This function samples a stable variable of parameters (alpha,beta) // // The algorithm is copied verbatim from formulas (2.3) and (2.4) in // Chambers, J. M.; Mallows, C. L.; Stuck, B. W. (1976). // "A Method for Simulating Stable Random Variables". // Journal of the American Statistical Association 71 (354): 340–344. // doi:10.1080/01621459.1976.10480344. // // Observation: the algorithm is numerically imprecise when alpha approaches 1. // TODO: implement appropriate rearrangements as suggested in the article. static double random_stable(double alpha, double beta) { double U = (random_uniform() - 0.5) * M_PI; double W = random_exponential(); double z = -beta * tan(M_PI * alpha / 2); double x = alpha == 1 ? M_PI/2 : atan(-z) / alpha; //fprintf(stderr, "U=%g W=%g z=%g x=%g\t\t", U, W, z, x); double r = NAN; if (alpha == 1) { double a = (M_PI/2 + beta * U) * tan(U); double b = log(((M_PI/2) * W * cos(U)) / ((M_PI/2) + beta * U)); //fprintf(stderr, "a=%g b=%g\n", a, b); r = (a - beta * b) / x; } else { double a = pow(1 + z * z, 1 / (2*alpha)); double b = sin(alpha * (U + x)) / pow(cos(U), 1/alpha); double c = pow(cos(U - alpha*(U + x)) / W, (1 - alpha) / alpha); //fprintf(stderr, "a=%g b=%g c=%g\n", a, b, c); r = a * b * c; } //fprintf(stderr, "s(%g,%g) = %g\n", alpha, beta, r); return r; }
static double random_pareto(void) { return exp(random_exponential()); }
StochasticSEATIRDSchedule::StochasticSEATIRDSchedule(const double &now, MTRand &rand, const std::vector<int> &stratificationValues) { stratificationValues_ = stratificationValues; // the individual starts as exposed state_ = E; // the schedule can later be canceled, but starts out active canceled_ = false; // generate all transitions starting from "exposed" // time to progress from exposed to asymptomatic double Ta = now + random_exponential(1. / g_parameters.getTau(), &rand); // infected period begins at asymptomatic infectedTMin_ = Ta; // infected periods ends at recovery / death and is set inline below eventQueue_.push(StochasticSEATIRDEvent(now, Ta, EtoA, stratificationValues, stratificationValues)); // compute nu (rate) from nu (CFR) double nu = -1./g_parameters.getGamma() * log(1. - g_parameters.getNu(stratificationValues[0])); // asymptomatic transition: -> treatable, -> recovered, or -> deceased double Tt = Ta + random_exponential(1. / g_parameters.getKappa(), &rand); // time to progress from asymptomatic to treatable double Tr_a = Ta + random_exponential(1. / g_parameters.getGamma(), &rand); // time to recover from asymptomatic double Td_a = Ta + random_exponential(nu, &rand); // time to death from asymptomatic if(Tt < Tr_a && Tt < Td_a) { // -> treatable eventQueue_.push(StochasticSEATIRDEvent(Ta, Tt, AtoT, stratificationValues, stratificationValues)); // treatable transitions: -> infectious, -> recovered, or -> deceased double Ti = Tt + g_parameters.getChi(); // time to progress from treatable to infectious double Tr_ti = Tt + random_exponential(1. / g_parameters.getGamma(), &rand); // time to recover from treatable/infectious double Td_ti = Tt + random_exponential(nu, &rand); // time to death from treatable/infectious if(Ti < Tr_ti && Ti < Td_ti) { // -> infectious eventQueue_.push(StochasticSEATIRDEvent(Tt, Ti, TtoI, stratificationValues, stratificationValues)); // infectious transitions: -> recovered, or -> deceased if(Tr_ti < Td_ti) { // -> recovered infectedTMax_ = Tr_ti; eventQueue_.push(StochasticSEATIRDEvent(Ti, Tr_ti, ItoR, stratificationValues, stratificationValues)); } else // Td_ti < Tr_ti { // -> deceased infectedTMax_ = Td_ti; eventQueue_.push(StochasticSEATIRDEvent(Ti, Td_ti, ItoD, stratificationValues, stratificationValues)); } } else if(Tr_ti < Td_ti) { // -> recovered infectedTMax_ = Tr_ti; eventQueue_.push(StochasticSEATIRDEvent(Tt, Tr_ti, TtoR, stratificationValues, stratificationValues)); } else // Td_ti < Tr_ti { // -> deceased infectedTMax_ = Td_ti; eventQueue_.push(StochasticSEATIRDEvent(Tt, Td_ti, TtoD, stratificationValues, stratificationValues)); } } else if(Tr_a < Td_a) { // -> recovered infectedTMax_ = Tr_a; eventQueue_.push(StochasticSEATIRDEvent(Ta, Tr_a, AtoR, stratificationValues, stratificationValues)); } else // Td_a < Tr_a { // -> deceased infectedTMax_ = Td_a; eventQueue_.push(StochasticSEATIRDEvent(Ta, Td_a, AtoD, stratificationValues, stratificationValues)); } }