You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: QtSLiM/help/EidosHelpFunctions.html
+2Lines changed: 2 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -194,6 +194,8 @@
194
194
<pclass="p5">Returns a vector of <spanclass="s2">n</span><b>random draws from a Laplace distribution</b> with shape parameter <spanclass="s2">b</span>.<spanclass="Apple-converted-space"></span>The <spanclass="s2">b</span> parameter may either be a singleton, specifying a single value to be used for all of the draws, or it may be a vector of length <spanclass="s2">n</span>, specifying a value for each draw.</p>
<pclass="p3">Returns a vector of <spanclass="s2">n</span><b>random draws from a lognormal distribution</b> with mean <spanclass="s2">meanlog</span> and standard deviation <spanclass="s2">sdlog</span>, specified on the log scale.<spanclass="Apple-converted-space"></span>The <spanclass="s2">meanlog</span> and <spanclass="s2">sdlog</span> parameters may either be singletons, specifying a single value to be used for all of the draws, or they may be vectors of length <spanclass="s2">n</span>, specifying a value for each draw.</p>
197
+
<pclass="p4">(integer)rmultinom(integer$ n, integer$ size, numeric prob)</p>
198
+
<pclass="p5">Returns a matrix of <spanclass="s2">n</span><b>random vectors from the specified multinomial distribution</b>.<spanclass="Apple-converted-space"></span>For each random vector drawn from the multinomial distribution, <spanclass="s2">size</span> objects will be put into <i>k</i> boxes, where <spanclass="s2">prob</span> is a vector of probabilities of length <i>k</i> specifying the probability for each box.<spanclass="Apple-converted-space"></span>If <spanclass="s2">prob</span> is not normalized to sum to <spanclass="s2">1.0</span>, its entries are treated as weights and normalized appropriately.<spanclass="Apple-converted-space"></span>The draws are returned as a matrix with <i>k</i> rows (one row per box) and <spanclass="s2">n</span> columns (one column per drawn random vector).</p>
197
199
<pclass="p4"><spanclass="s5">(float)rmvnorm(integer$ n, numeric mu, numeric sigma)</span></p>
198
200
<pclass="p5"><spanclass="s5">Returns a matrix of </span><spanclass="s9">n</span><spanclass="s5"><b>random draws from a <i>k</i>-dimensional multivariate normal distribution</b> with a length <i>k</i> mean vector </span><spanclass="s9">mu</span><spanclass="s5"> and a <i>k</i> × <i>k</i> variance-covariance matrix </span><spanclass="s9">sigma</span><spanclass="s5">.<spanclass="Apple-converted-space"></span>The </span><spanclass="s9">mu</span><spanclass="s5"> and </span><spanclass="s9">sigma</span><spanclass="s5"> parameters are used for all </span><spanclass="s9">n</span><spanclass="s5"> draws.<spanclass="Apple-converted-space"></span>The draws are returned as a matrix with </span><spanclass="s9">n</span><spanclass="s5"> rows (one row per draw) and <i>k</i> columns (one column per dimension).<spanclass="Apple-converted-space"></span>The number of dimensions <i>k</i> must be at least two; for <i>k</i>=1, use </span><spanclass="s9">rnorm()</span><spanclass="s5">.</span></p>
199
201
<pclass="p5"><spanclass="s5">Cholesky decomposition of the variance-covariance matrix </span><spanclass="s9">sigma</span><spanclass="s5"> is involved as an internal step, and this requires that </span><spanclass="s9">sigma</span><spanclass="s5"> be positive-definite; if it is not, an error will result.<spanclass="Apple-converted-space"></span>When more than one draw is needed, it is much more efficient to call </span><spanclass="s9">rmvnorm()</span><spanclass="s5"> once to generate all of the draws, since the Cholesky decomposition of </span><spanclass="s9">sigma</span><spanclass="s5"> can then be done just once.</span></p>
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires n to be greater than or equal to 1 (" << num_draws << " supplied)." << EidosTerminate(nullptr);
1673
+
1674
+
// get and check the size of each multinomial draw
1675
+
// the upper limit is because the GSL requires size to be cast down to unsigned int
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires size to be greater than or equal to 0." << EidosTerminate(nullptr);
1680
+
if (size > 1000000000)
1681
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires size to be less than or equal to 1000000000." << EidosTerminate(nullptr);
1682
+
1683
+
// get and check the number of "boxes", i.e., the number of probabilities supplied
1684
+
// the upper limit is arbitrary, but it seems wise to have a limit
1685
+
int k = arg_prob->Count();
1686
+
1687
+
if (k <= 0)
1688
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires prob to be of length 1 or greater." << EidosTerminate(nullptr);
1689
+
if (k > 1000000)
1690
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires prob to be of length 1000000 or less." << EidosTerminate(nullptr);
1691
+
1692
+
// fetch the probability vector into a local static buffer, checking as we go; note the gsl normalizes prob_vec for us
1693
+
double prob_sum = 0.0;
1694
+
static std::vector<double> prob_vec;
1695
+
prob_vec.reserve(k);
1696
+
prob_vec.resize(0);
1697
+
1698
+
for (int prob_index = 0; prob_index < k; ++prob_index)
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires all probabilities in prob to be >= 0.0." << EidosTerminate(nullptr);
1704
+
if (!std::isfinite(prob))
1705
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires all probabilities in prob to be finite (not INF or NAN)." << EidosTerminate(nullptr);
1706
+
1707
+
prob_sum += prob;
1708
+
prob_vec.push_back(prob);
1709
+
}
1710
+
1711
+
if (prob_sum == 0.0)
1712
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() requires the sum of prob to be greater than zero; there must be at least one non-zero probability." << EidosTerminate(nullptr);
1713
+
if (!std::isfinite(prob_sum))
1714
+
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_rmultinom): function rmultinom() could not compute the multinomial draws because the sum of prob overflowed to infinity." << EidosTerminate(nullptr);
1715
+
1716
+
if (k == 1)
1717
+
{
1718
+
// If k == 1, every object goes into the same single box, so the result is trivial
1719
+
EidosValue_Int *int_result = (new (gEidosValuePool->AllocateChunk()) EidosValue_Int())->resize_no_initialize((int)num_draws);
1720
+
result_SP = EidosValue_SP(int_result);
1721
+
1722
+
for (int draw_index = 0; draw_index < num_draws; ++draw_index)
1723
+
int_result->set_int_no_check(size, draw_index);
1724
+
}
1725
+
elseif (size == 0)
1726
+
{
1727
+
// if size == 0, zero objects are drawn in each multinomial trial, so the result is trivial
1728
+
EidosValue_Int *int_result = (new (gEidosValuePool->AllocateChunk()) EidosValue_Int())->reserve((int)num_draws * k);
1729
+
result_SP = EidosValue_SP(int_result);
1730
+
1731
+
for (int draw_index = 0; draw_index < num_draws; ++draw_index)
1732
+
for (int k_index = 0; k_index < k; ++k_index)
1733
+
int_result->push_int_no_check(0);
1734
+
}
1735
+
else
1736
+
{
1737
+
// the main case, where we need to call gsl_ran_multinomial() to do the work
1738
+
// we put the drawn values into a local static buffer, and then copy them into the Eidos result
if (sum(abs(r-expected)) >300000) stop('Mismatch in expectation vs. realization of rmultinom() - could be random chance (but very unlikely), rerun test');
0 commit comments