Re: [rng] FiniteDoubleSampler to sample uniformly from a range of representable double values

2020-01-21 Thread Alex Herbert

On 17/01/2020 17:21, Alex Herbert wrote:


A uniform sampler of the IEEE 754 finite doubles would sample from a 
log-uniform distribution as the limiting distribution and I don't 
think that is actually what people require when creating random double 
data. So either it: (a) is discarded as an idea; (b) is well 
documented and put in examples; (c) is actually formalised to 
correctly sample from the log-uniform distribution using the PDF:


1 / (x (log(b) - log(a)))

for x in the interval [a, b] from a uniform deviate (U) in the range 
of the natural logarithm of the interval:


X = exp(U(log(a), log(b)))


I think that adding a LogUniformSampler may be of use.

It would allow creation of data approximately uniform in the 
distribution of exponents. The numbers would be uniform on a log scale. 
The implementation is simple and I don't see the harm in adding it since 
it is a valid distribution with known PDF and CDF.


Likewise the LogUniformDistribution can be added to commons-statistics 
distribution. There already is a vaguely related 
LogNormalDistribution/NormalDistribution pair so this would be and the 
LogUniformDistribution/UniformContinuousDistribution pair. I don't see 
the need to name it LogUniformContinuousDistribution as there is no 
discrete version that I could find documented.


Alex



-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [rng] FiniteDoubleSampler to sample uniformly from a range of representable double values

2020-01-17 Thread Alex Herbert



On 17/01/2020 13:33, Gilles Sadowski wrote:

Hi.

Le ven. 17 janv. 2020 à 13:15, Alex Herbert  a écrit :

The UniformRandomProvider and ContinuousUniformSampler can create
doubles uniformly in a range [0, 1) and [x, y).

I would like to create a sampler that can create doubles with random
mantissa bits and a specified range of exponents. These would not follow
a standard distribution but would be distributed according to the IEEE
754 floating-point "double format" bit layout.

The sampler would ensure all bits of the mantissa are uniformly sampled
and the exponent range is uniformly sampled. It could be used for
example to create random double data in a specified range for testing.

Are there use-cases other than providing inputs for unit tests?


Maybe. I haven't got one though.

However to use it from other places it would have to be in a distributed 
maven artifact. So either it goes in commons-rng-sampling or perhaps 
commons-rng-examples-sampling.



Following from UniformRandomProvider I propose to remove the sign bit to
allow a maximum range sampler from [0, Double.MAX_VALUE].

Is there a trade-off to allowing generation of the whole range of "double"s?
No. I can change the API so the sign bit is optionally removed. At least 
in some tests it is advantageous to know the data will be randomly 
signed or only unsigned.

Thus we have
the API:

public final class FiniteDoubleSampler {

/**
   * Creates a new finite double sampler.
   *
   * This will return double values from the entire exponent range of
a finite
   * {@code double} including sub-normal numbers. The value will be unsigned.
   *
   * @param rng Generator of uniformly distributed random numbers.
   * @return Sampler.
   * @since 1.4
   */
public static SharedStateContinuousSampler of(UniformRandomProvider rng);

/**
   * Creates a new finite double sampler.
   *
   * This will return double values from the specified exponent range
of a finite
   * {@code double}. This assumes all sub-normal numbers are identified
with the exponent -1023.
   * The value will be unsigned.
   *
   * @param rng Generator of uniformly distributed random numbers.
   * @param minExponent Minimum exponent
   * @param maxExponent Maximum exponent
   * @see Double#MIN_EXPONENT
   * @see Double#MAX_EXPONENT
   * @throws IllegalArgumentException If the exponents are not in the
range -1023 inclusive
   * to 1023 inclusive; or the min exponent is not {@code <=} max exponent.
   * @return Sampler.
   * @since 1.4
   */
public static SharedStateContinuousSampler of(UniformRandomProvider rng,
int minExponent,
int maxExponent);
}

I have written many tests where I wanted full precision random mantissas
in double values and wanted the doubles to represent all doubles that
could occur.

How do you ensure it (short of listing them all)?


You cannot practically list all doubles. What you want is a 
representative set of all doubles. I think this idea satisfies that as 
doubles are not uniform on a linear scale.





Thus randomly sampling from the IEEE 754 representation
seems to be more generic than for example rng.nextDouble() * constant.

What's the advantage of the former over the latter?


Given that doubles are not uniform on a linear scale if you use 
rng.nextDouble() * constant you are biasing your samples to higher 
exponents. This may or may not be what you want.


If we examine nextDouble() it will uniformly sample all the 2^53 dyadic 
rationals in the interval [0, 1). These have a large variety of 
exponents. I do not know the distribution of only the mantissa bits but 
I would guess that they may not be uniform in order to fall exactly on 
the spacing interval 1/2^53. For example the first 4 numbers:


1/2^53
2/2^53 = 1/2^52
3/2^53 = 1/2^52 + 1/2^53
4/2^53 = 1/2^51

would have regular mantissas using only 0 or 1 bits. The mantissa is the 
same for 1, 2, 4 and only different for 3.


The interval [0, 1) can be divided into [0, 0.5) and [0.5, 1). The 
second interval has only 1 exponent. So half the 2^53 random numbers 
must be represented here using the mantissa and it requires all but the 
bit combinations in the mantissa. But in the range below 0.5 the 
mantissa bits will begin to be more and more sparsely used as the 
representation shifts to using the exponent in the range -2 to -53.


What happens when you multiply by a constant?

IIUC this is equivalent:

x * y = s * m * 2^(e-1075)  *  s * m * 2^(e-1075)

where:

 long bits = Double.doubleToLongBits(x or y);
 int s = ((bits >> 63) == 0) ? 1 : -1;
 int e = (int)((bits >> 52) & 0x7ffL);
 long m = (e == 0) ?
 (bits & 0xfL) << 1 :
 (bits & 0xfL) | 0x10L;

So ignoring the sign and exponent (which will just change in magnitude) 
the result can be computed by multiplying the two normalised mantissas, e.g.


// Conditioned so that the exponent of the 

Re: [rng] FiniteDoubleSampler to sample uniformly from a range of representable double values

2020-01-17 Thread Gilles Sadowski
Hi.

Le ven. 17 janv. 2020 à 13:15, Alex Herbert  a écrit :
>
> The UniformRandomProvider and ContinuousUniformSampler can create
> doubles uniformly in a range [0, 1) and [x, y).
>
> I would like to create a sampler that can create doubles with random
> mantissa bits and a specified range of exponents. These would not follow
> a standard distribution but would be distributed according to the IEEE
> 754 floating-point "double format" bit layout.
>
> The sampler would ensure all bits of the mantissa are uniformly sampled
> and the exponent range is uniformly sampled. It could be used for
> example to create random double data in a specified range for testing.

Are there use-cases other than providing inputs for unit tests?

>
> Following from UniformRandomProvider I propose to remove the sign bit to
> allow a maximum range sampler from [0, Double.MAX_VALUE].

Is there a trade-off to allowing generation of the whole range of "double"s?

> Thus we have
> the API:
>
> public final class FiniteDoubleSampler {
>
> /**
>   * Creates a new finite double sampler.
>   *
>   * This will return double values from the entire exponent range of
> a finite
>   * {@code double} including sub-normal numbers. The value will be unsigned.
>   *
>   * @param rng Generator of uniformly distributed random numbers.
>   * @return Sampler.
>   * @since 1.4
>   */
> public static SharedStateContinuousSampler of(UniformRandomProvider rng);
>
> /**
>   * Creates a new finite double sampler.
>   *
>   * This will return double values from the specified exponent range
> of a finite
>   * {@code double}. This assumes all sub-normal numbers are identified
> with the exponent -1023.
>   * The value will be unsigned.
>   *
>   * @param rng Generator of uniformly distributed random numbers.
>   * @param minExponent Minimum exponent
>   * @param maxExponent Maximum exponent
>   * @see Double#MIN_EXPONENT
>   * @see Double#MAX_EXPONENT
>   * @throws IllegalArgumentException If the exponents are not in the
> range -1023 inclusive
>   * to 1023 inclusive; or the min exponent is not {@code <=} max exponent.
>   * @return Sampler.
>   * @since 1.4
>   */
> public static SharedStateContinuousSampler of(UniformRandomProvider rng,
>int minExponent,
>int maxExponent);
> }
>
> I have written many tests where I wanted full precision random mantissas
> in double values and wanted the doubles to represent all doubles that
> could occur.

How do you ensure it (short of listing them all)?

> Thus randomly sampling from the IEEE 754 representation
> seems to be more generic than for example rng.nextDouble() * constant.

What's the advantage of the former over the latter?

> For example:
>
> // Random numbers: [0, Double.MAX_VALUE]
> FiniteDoubleSampler.of(rng);
> FiniteDoubleSampler.of(rng, -1023, 1023);
> // Random sub-normal numbers: [0, Double.MIN_NORMAL)
> FiniteDoubleSampler.of(rng, -1023, -1023);
> // Random numbers that are close to overflow: (Double.MAX_VALUE/2,
> Double.MAX_VALUE]
> FiniteDoubleSampler.of(rng, 1023, 1023);
> // Random numbers in the range [1, 32)
> FiniteDoubleSampler.of(rng, 0, 4);

Will the distribution be the same as for "32 * rng.nextDouble()"?

Regards,
Gilles

> Thoughts on this?
>
> Alex
>

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org