[
https://issues.apache.org/jira/browse/RNG-195?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18106798#comment-18106798
]
Alex Herbert commented on RNG-195:
----------------------------------
The DirichletSampler uses gamma samples with concentration alpha and the other
parameter theta=1.0. I have investigated the values of alpha that can cause an
issue with the Dirichlet sample.
Note that the Dirichlet distribution has at least 2 gamma samples that are
added together. The maximum number of samples to add is limited by an integer
(2^31 - 1).
h2. Small Alpha
Uses the Ahrens Dieter algorithm.
Statistics from 100000 random gamma samples counting the number of samples
equal to zero:
||log2(alpha)||alpha||p(x=0)||
|-1|0.500|0.0|
|-2|0.250|0.0|
|-3|0.125|0.0|
|-4|0.0625|0.0|
|-5|0.0313|0.0|
|-6|0.0156|1.0E-5|
|-7|0.00781|0.00294|
|-8|0.00391|0.05539|
|-9|0.00195|0.23584|
|-10|0.000977|0.48614|
|-11|0.000488|0.69803|
|-12|0.000244|0.83681|
|-13|0.000122|0.91541|
|-14|6.10e-05|0.95657|
|-15|3.05e-05|0.97797|
|-16|1.53e-05|0.98897|
|-17|7.63e-06|0.99446|
|-18|3.81e-06|0.9971|
|-19|1.91e-06|0.99848|
|-20|9.54e-07|0.99924|
|-21|4.77e-07|0.99967|
|-22|2.38e-07|0.99986|
|-23|1.19e-07|0.99994|
|-24|5.96e-08|0.99997|
|-25|2.98e-08|0.99998|
|-26|1.49e-08|0.99998|
|-27|7.45e-09|0.99999|
|-28|3.73e-09|1.0|
|-29|1.86e-09|1.0|
|-30|9.31e-10|1.0|
For example as the alpha parameter drops below 1e-4 there is above 90% chance
of generating a zero. For k concentration parameters the chance of all zeros is
p^k. This will always be true when the concentration parameter is very small.
The algorithm internally uses some predefined constants:
{noformat}
1 / alpha
1 + alpha / Math.E{noformat}
The second constant is multiplied by u in [0, 1) to generate p and compared to
1 to make a branch decision. When alpha / Math.E is less than machine precision
this branch is always chosen as p <= 1. Inside the branch the sampled p is
raised to the power of 1/alpha. This will tend towards zero for small alpha,
e.g.
{noformat}
Math.pow(Math.nextDown(1.0), 1e19) == 0{noformat}
An alpha value of 1e-19 cannot possibly generate a non-zero gamma sample.
However higher values can and there is no definitive cut-off.
h2. Large Alpha
Uses the Marsaglia Tsang algorithm.
Statistics from 100000 random gamma samples counting the number of samples
equal to alpha:
||log2(alpha)||alpha||p(x=alpha)||
|90| 1.24e+27| 0.00681|
|91| 2.48e+27| 0.00984|
|92| 4.95e+27| 0.01395|
|93| 9.90e+27| 0.02002|
|94| 1.98e+28| 0.02858|
|95| 3.96e+28| 0.04056|
|96| 7.92e+28| 0.05705|
|97| 1.58e+29| 0.08035|
|98| 3.17e+29| 0.11332|
|99| 6.34e+29| 0.15954|
|100| 1.27e+30| 0.22434|
|101| 2.54e+30| 0.31304|
|102| 5.07e+30| 0.42942|
|103| 1.01e+31| 0.57461|
|104| 2.03e+31| 0.73523|
|105| 4.06e+31| 0.86778|
|106| 8.11e+31| 0.95787|
|107| 1.62e+32| 0.99845|
|108| 3.25e+32| 1.0|
|109| 6.49e+32| 1.0|
|110| 1.30e+33| 1.0|
Internally the algorithm uses 2 constants:
{noformat}
dOptim = alpha - 1/3
cOptim = 1/3 / sqrt(dOptim)
{noformat}
When alpha -> 3e32 then
* dOptim = alpha
* cOptim = (1 / (3 * sqrt(alpha)) -> 0
The sample is generated from a random Gaussian sample using:
{noformat}
oPcTx = 1 + cOptim * Gauss(X)
v = oPcTx * oPcTx * oPcTx{noformat}
If conditions are satisfied the sample is:
{noformat}
theta * dOptim * v{noformat}
When alpha is large v=1, dOptim=alpha and theta=1 results in all samples being
alpha.
Note that in the DirichletSampler as at least 2 gamma samples are added. So if
alpha=2^1023 then the sum will overflow to infinity and the sampler enters
unbounded recursion. This situation can be predicted: if all concentration
parameters are large then if they sum to infinity then the sampler will
generate stack overflow error for every sample. However the practical threshold
for a valid sampler is much lower. A sampler created using a large but not
excessive alpha will return constant samples, e.g.:
{code:java}
UniformRandomProvider rng = ...
int k = 2;
double alpha = 1e35;
// Generates constant output
DirichletSampler.symmetric(rng, k, alpha) {code}
h2. Conclusion
The DirichletSampler uses an underlying gamma sampler.
The gamma sampler will output all zeros when the alpha parameter is small (<
1e-19), and is very likely to output zeros with alpha < 1e-10. This will
invalidate the Dirichlet sample algorithm. The current behaviour is a stack
overflow error on sample generation.
The gamma sampler will output all samples equal to the alpha parameter when
alpha > 1e33 (approx). The gamma sampler, and consequently the
DirichletSampler, is thus invalid with large alpha as it does not sample a
distribution but a constant. When the sum of Dirichlet concentration parameters
is infinite then the sampler will generate a stack overflow error, otherwise it
will output a constant.
Since the sampler uses a source of randomness it is possible that as these
alpha limits are approached the rejection algorithm can still generate samples.
Adding a hard limit to the upper bound for alpha would be possible to avoid the
sampler emitting constant values. But this could still occur below the hard
limit and provides little value beyond catching a grossly misconfigured
sampler. The same goes for the lower limit. It may avoid an obviously broken
sampler from unbounded recursion, but this would still be possible above the
hard limit.
There are at least two options:
# Impose hard limits where the sampler is known to be non-functional. Document
it could still be non-functional within these limits.
# Leave the behaviour as is; document the known limits and advise the user to
expect stack overflow errors if they approach these extremes.
> DirichletSampler has unbounded recursion and stack overflow for small alpha
> parameters
> --------------------------------------------------------------------------------------
>
> Key: RNG-195
> URL: https://issues.apache.org/jira/browse/RNG-195
> Project: Commons RNG
> Issue Type: Bug
> Components: sampling
> Affects Versions: 1.3
> Reporter: Alex Herbert
> Priority: Minor
>
> The DirichletSampler uses a rejection method to sample. A gamma sample is
> obtained for each concentration parameter alpha. The vector of k samples is
> normalised to unit length. When the sum of the samples is zero or infinite
> the sample cannot be normalised and recursion occurs to generate another
> sample.
> If the alpha parameters are very small the gamma samples are always zero and
> a stack overflow error occurs.
> Note that recursion is expected to be used to indicate a non-functional RNG
> underlying the sampler. It was not the original intention to use a stack
> overflow error to indicate a badly parameterised sampler where samples are
> impossible.
> Issue identified using a security scan.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)