Suppose I have some floats that are normal distributed around 0. I need to serialize this into a uint8, but I would like to "give more" of the uint8 to the center of the distribution, and lose resolution around the edges.
For example: 127
would correspond to 0.0
and 255
to 1.0
. But 191
would not be 0.5
— instead, it would be something like 0.3
because we're stretching it so that most of the numbers correspond to values near 0.
In practice, I'm actually going to have a random uint32
being generated and converted to an float
. But when testing a linear mapping, the extremes (near -1.0 and 1.0) came up too frequently, and I'd like to center this around 0.0
.
I'm aware that I can use the Box–Muller transform
, but that's actually not suitable here because:
We can cap out at -1.0 and 1.0, no need to have an unbounded output.
We only have one number to sample from, not two.
Thanks
The quantile function (also known as the inverse CDF) maps uniform random numbers in [0, 1] to numbers that follow a distribution (such as the normal distribution).
However, in the case of the normal distribution there are certain things to know (call the quantile function Q(u) from now on):
for k in 0..255
c=0.001+(0.999-0.001)*(k*1.0/256)
print([k, Q(c)]) // print the uint8 value followed by the quantile
end