Trac: Status: new to needs_review Description: Currently, sample_laplace_distribution() takes a random double as input, and then extracts the following random values:
Instead, the function could take a random boolean sign and p, and the transform becomes:
{{
result = mu - b * (sign ? 1.0 : -1.0)
* tor_mathlog(1.0 - p);
}}
This would increase the precision by one bit, plus whatever precision is lost in 2.0 * fabs(p - 0.5).
This may have been introduced in dad5eb7.
to
Currently, sample_laplace_distribution() takes a random double as input, and then extracts the following random values:
Wouldn't it be better to have a function that outputs a random double in (-1.0, +1.0)? If you're only using 53 bits of entropy from a RNG call that generates 64, there are spare bits to use for generating the sign.
Wouldn't it be better to have a function that outputs a random double in (-1.0, +1.0)? If you're only using 53 bits of entropy from a RNG call that generates 64, there are spare bits to use for generating the sign.
sample_laplace_distribution() takes the log of a strictly positive floating point number, and then applies a random sign.
We could use sgn() and abs() to decompose [-1.0, 1.0] into {+, -} and [0.0, 1.0], but we'd still have to reject 0.0 before doing the log, and then apply the sign. So it seems more complex than the alternative.
That works, too: it costs us another random double function, but saves us an argument, and some complexity in the callers. Want to write the patch, or should I?
Produces random values in the range (-1.0, 1.0), with similar semantics to my other routine. Timing characteristics depend on how copysign() is implemented, though I expect most libms to use bit twiddling of some sort.
doubleuint64_to_dbl_neg1_1(uint64_t x) {#if DBL_MANT_DIG > 63#error System double mantissa is unexpectedly large.#endif return copysign(uint64_to_dbl_0_1(x), 0.0 - (x >> 63));}
Edit: The routine can produce both 0.0 and -0.0, which is probably not what you want. If that's a problem the caller should re-sample entropy on either 0 or 1 << 63 depending on which zero you want it to return.
The good news is that we probably don't need to care about extreme values or binning, because properly implemented noise has known limits, and doesn't need binning.