[ 
https://issues.apache.org/jira/browse/RNG-145?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17363222#comment-17363222
 ] 

Alex Herbert edited comment on RNG-145 at 6/14/21, 9:23 PM:
------------------------------------------------------------

h2. Fixing the test for an open interval

I tried the obvious solution of testing the number of doubles in the range 
between low and high. This can be done using the raw long bits of the double 
and obtaining the difference between the two in a robust way that accounts for 
the sign. This gap must be at least 1.

This mostly works. It does not work for this case:

{code:java}
double x = Double.MIN_VALUE;
ContinuousUniformSampler.of(rng, -x, x, true).sample()
{code}
The issue is that the only value of u that will create a sample of 0.0 is 0.5:

{code:java}
double x = Double.MIN_VALUE;
// OK
Assert.assertEquals(0.0, 0.5 * -x +  0.5 * x, 0.0);
// Fails to create the sample ...
Assert.assertNotEquals(0.0, Math.nextAfter(0.5, 1) * -x +  Math.nextAfter(0.5, 
-1) * x, 0.0);
// ... due to rounding
Assert.assertEquals(-x, Math.nextAfter(0.5, 1) * -x, 0.0);
Assert.assertEquals(0.0, Math.nextAfter(0.5, -1) * x, 0.0);
{code}

A sample can be create for other sub-normal ranges:

{code:java}
double x = Double.MIN_VALUE;
ContinuousUniformSampler.of(rng, 0.0, x*2, true).sample()
ContinuousUniformSampler.of(rng, x, x*3, true).sample()
{code}

In this case the lower and upper bounds have the same sign. The case of 2 ULP 
difference not working for sub-normal numbers is when the sign changes.

I have updated the sampler to check the ULP is 2 if the lower and upper are the 
same sign, otherwise the gap must be 3 ULP. This works and can create samples 
that are not at the bounds.


was (Author: alexherbert):
h2. Fixing the test for an open interval

I tried the obvious solution of testing the number of doubles in the range 
between low and high. This can be done using the raw long bits of the double 
and obtaining the difference between the two in a robust way that accounts for 
the sign. This gap must be at least 1.

This mostly works. It does not work for this case:

{code:java}
double x = Double.MIN_VALUE;
ContinuousUniformSampler.of(rng, -x, x, true).sample()
{code}
The issue is that the only value of u that will create a sample of 0.0 is 0.5:

{code:java}
double x = Double.MIN_VALUE;
// OK
Assert.assertEquals(0.0, 0.5 * -x +  0.5 * x, 0.0);
// Fails to create the sample ...
Assert.assertNotEquals(0.0, Math.nextAfter(0.5, 1) * -x +  Math.nextAfter(0.5, 
-1) * x, 0.0);
// ... due to rounding
Assert.assertEquals(-x, Math.nextAfter(0.5, 1) * -x, 0.0);
Assert.assertEquals(0.0, Math.nextAfter(0.5, -1) * x, 0.0);
{code}

A sample can be create for other sub-normal ranges:

{code:java}
double x = Double.MIN_VALUE;
ContinuousUniformSampler.of(rng, 0.0, x*2, true).sample()
ContinuousUniformSampler.of(rng, x, x*3, true).sample()
{code}

In this case the lower and upper bounds have the same sign. The case of 2 ULP 
difference not working for sub-normal numbers is when the sign changes.

I have updated the sampler to check the ULP is 2 if the lower and upper are the 
same sign, otherwise the gap must be 3 ULP. This works are can create samples 
that are not at the bounds.

> "ContinuousUniformSampler" with both bounds excluded
> ----------------------------------------------------
>
>                 Key: RNG-145
>                 URL: https://issues.apache.org/jira/browse/RNG-145
>             Project: Commons RNG
>          Issue Type: New Feature
>          Components: sampling
>            Reporter: Gilles Sadowski
>            Priority: Major
>             Fix For: 1.4
>
>
> In class {{RandomUtils}}, Commons Math provides
> {code}
> public double nextUniform(double lo, double hi) { /* ... */ }
> {code}
> where both bounds are excluded.
> Should the feature be added to {{ContinuousUniformSampler}}?



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to