![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
in news:40995621@news.povray.org Andrew C on Mozilla wrote:
> Any idea how to transform these into normally distributed numbers?
>
From "rand.inc"
Rand_Normal(Mu, Sigma, Stream). Normal distribution.
Parameters:
Mu = Mean.
Sigma = Standard deviation.
Stream = Random number stream.
Rand_Gauss(Mu, Sigma, Stream). Gaussian distribution. Like Rand_Normal
(), but a bit faster.
Parameters:
Mu = Mean.
Sigma = Standard deviation.
Stream = Random number stream.
Ingo
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
-[You can approximate a normal distribution of numbers...]-
...but this is an inefficient method. The standard method is the Box-Muller
transform, given here in C.
float v1,v2,rsq,fac;
do
{
v1=rand()*2.0-1.0; v2=rand()*2.0-1.0;
rsq=v1*v1+v2*v2;
} while (rsq>=1.0 || rsq==0.0)
fac=sqrt(-2.0*log(rsq)/rsq);
This generates two independent normal deviates (v1*fac) and (v2*fac) (with
zero mean and unit variance). The "rand()" function here generates uniform
deviates between 0 and 1.
-[...and dividing the result by n]-
Actually, with this method you need to divide by sqrt(n) if you want to keep
the variance independent of n.
-Chris
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>>POV-Ray's random number generator gives uniformly distributed real numbers.
>
> Actually no. It gives uniformly distributed real numbers between 0 and 1,
> which is a slightly different thing.
Well yeah, but you know what I *mean* ;-)
> (And we can also split hairs by noting that floating points numbers aren't
> real numbers but a finite set of rational numbers, but would not be relevant
> here... :) )
True. (I do recall asking how far apart these numbers are, but never
really got an answer...)
>>Any idea how to transform these into normally distributed numbers?
>
> You can approximate a normal distribution of numbers between 0 and 1
> by taking the sum of n equally-distributed numbers and dividing the
> result by n. The higher the n, the more closely it resembles normal
> distribution, but for practical purposes you don't need a very large n.
> Even n=3 already gives a pretty good distribution.
...because the means of different samples from a given population are
normally distributed around the true mean of the population? (And the
true mean of a *truely* uniform distribution from 0 to 1 would be 0.5)
Andrew @ home.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> From "rand.inc"
>
> Rand_Normal(Mu, Sigma, Stream). Normal distribution.
> Parameters:
> Mu = Mean.
> Sigma = Standard deviation.
> Stream = Random number stream.
>
> Rand_Gauss(Mu, Sigma, Stream). Gaussian distribution. Like Rand_Normal
> (), but a bit faster.
> Parameters:
> Mu = Mean.
> Sigma = Standard deviation.
> Stream = Random number stream.
Ah... yes, that's easier! ;-)
Andrew @ home
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
-[I do recall asking how far apart these numbers are]-
Pov-ray uses the IEEE double floating point standard (unless you're
compiling it on a DEC VAX or something obscure), which has 52 bits of
fractional precision, which gives about 2^-52 as the distance between random
numbers. However, pov-ray actually uses a 32-bit linear congruential random
number generator, which only uses 32 bits of precision.
-[because the means of different samples from a given population are
normally distributed around the true mean of the population]-
Yes - or rather, they approach a normal distribution as the number in each
sample tends to infinity (the Central Limit Theorem)
-Chris
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <4099991b$1@news.povray.org>,
"Chris Johnson" <chris(at)chris-j(dot)co(dot)uk> wrote:
> -[You can approximate a normal distribution of numbers...]-
> ...but this is an inefficient method. The standard method is the Box-Muller
> transform, given here in C.
If you can easily generate a few random numbers and don't need a very
close approximation, the averaging method can be faster. The problem
isn't really efficiency, it's accuracy...the result isn't all that close
to a normal distribution unless you use lots of points and rescale the
numbers to get out of the range of the original numbers.
> -[...and dividing the result by n]-
> Actually, with this method you need to divide by sqrt(n) if you want to keep
> the variance independent of n.
In the places where this approximation is used, that is rarely a
problem. It's often more useful to have a known range that the random
numbers are limited to. It's a very fast and easy way to get objects to
bunch up around a point with a roughly Gaussian distribution.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <409aa06c@news.povray.org>,
"Chris Johnson" <chris(at)chris-j(dot)co(dot)uk> wrote:
> -[I do recall asking how far apart these numbers are]-
> Pov-ray uses the IEEE double floating point standard (unless you're
> compiling it on a DEC VAX or something obscure), which has 52 bits of
> fractional precision, which gives about 2^-52 as the distance between random
> numbers.
Not quite correct. You're forgetting that floating point numbers are not
fixed point...they're quite a bit more complicated. In addition to the
52-bit plus-one mantissa, IEEE 754 double precision numbers also have an
11 bit exponent, which can go down to -1023 and up to 1024. You end up
with a pretty complex distribution of possible numbers...just how big a
step there is between a value and the next possible larger or smaller
value depends on what that value is.
> However, pov-ray actually uses a 32-bit linear congruential random
> number generator, which only uses 32 bits of precision.
At most, it may be even less. Assuming it fills the entire 32 bit range,
that gives you 2^32 steps, 4294967296 steps with 2.328306436538696e-10
between each step.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
-[Not quite correct]-
That's why I said "about 2^-52" not "2^-52". I wasn't going to go into the
details of floating point when it is rendered irrelevant by the fixed-point
form of the random number generator.
-[At most, it may be even less]-
It wouldn't be a 32-bit linear congruential generator if it didn't use
32-bits. I looked at the pov-ray source before I posted to make sure it was
a 32-bit generator, rather than the C library rand() function, which is
often only 15- or 16-bit.
-Chris
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <409befe5$1@news.povray.org>,
"Chris Johnson" <chris(at)chris-j(dot)co(dot)uk> wrote:
> -[At most, it may be even less]-
> It wouldn't be a 32-bit linear congruential generator if it didn't use
> 32-bits. I looked at the pov-ray source before I posted to make sure it was
> a 32-bit generator, rather than the C library rand() function, which is
> often only 15- or 16-bit.
However, it may not be full period, meaning it may cycle through a
subset of that range. There are various choices for the different
coefficients that will give full period generators, and a small mistake
in choosing them will cause the generator to only cycle through some
numbers in the range before repeating.
POV-Ray's PRNG actually isn't a typical LCG generator. Such generators
are of the form:
r[n] = (r[n - 1]*a + c) mod m
POV-Ray's generator lets overflow wraparound take care of the modulus,
and then takes a subset of the bits of the resulting number for the
result. It uses "12345" for c, which makes me think the coder didn't put
much work into choosing the parameters. It uses a non-prime m due to the
way it works around computing a modulus, and I'm pretty sure that alone
makes it non-full period. Finally, and most important to this
discussion, it does a bit shift and bitwise AND with 0x7FFF on the
result of the LCG, and thus can not return numbers out of the range [0,
32767].
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> -[because the means of different samples from a given population are
> normally distributed around the true mean of the population]-
>
> Yes - or rather, they approach a normal distribution as the number in each
> sample tends to infinity (the Central Limit Theorem)
Ah... I *knew* reading an entire book on statistics would be useful one
day! :-)
Andrew @ home.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |