Who doesn't like an(other) discussion about random numbers?
I reading an article on Monte Carlo simulations and came across a method
for getting a random value from a standard normal distribution. (The
standard normal distribution is the familiar bell curve where the mean is 0
and the standard deviation is 1.) Typically I might pull out the old 4D
Math database and get the complicated formula from there and work out
something. But there is a really easy way to accomplish this using the
baked in Random function.
C_REAL($0)
$0:=((Random+Random+Random+Random+Random+Random+Random+Random+Random+Random+Random+Random)-(32767*6))/32767
The original idea is based on a Rand() function that returns a value
between 0 and 1. So you add up 12 of these random values and subtract 6. 6
is the expected mean of 12 selections from a standard random distribution
so the subtraction adjusts the mean to 0 without changing the standard
deviation. The result is not technically a standard distribution but a
reflection about the mean of zero with a standard deviation of 1 - which
the most of what defines a standard deviation.
We can do that too:
$0:=((Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767)+(Random/32767))-6
Dividing Random by 32767 gives that same value since Random returns a value
between 0 and 32767.
It turns out to be slightly faster to avoid all those division operations
and so the version I gave first. Apparently this approach is well known in
some areas but I had never seen it before.
Playing with this in v18 I notice the distributions become quite normal
when they get large ( ~5000 iterations). It is fast with iterations of 100k
averaging about 870ms uncompiled. To look at resulting distributions I made
a simple form with a picture variable and a button and borrowed the code
from the Graph document page for the button method.
*ARRAY LONGINT*($aY;19)
*ARRAY TEXT*($aX;19)
$aX{1}:="5.0"
$aX{2}:="4.5"
$aX{3}:="4.0"
$aX{4}:="3.5"
$aX{5}:="3.0"
$aX{6}:="2.5"
$aX{7}:="2.0"
$aX{8}:="1.5"
$aX{9}:="0.5"
$aX{10}:="0.0"
$aX{11}:="0.5"
$aX{12}:="1.5"
$aX{13}:="2.0"
$aX{14}:="2.5"
$aX{15}:="3.5"
$aX{16}:="4.0"
$aX{17}:="3.0"
$aX{18}:="4.5"
$aX{19}:="5.0"
*For* ($i;1;100)
$j:=10+*Round*(*rand_z*/0.5;0)
$ay{$j}:=$aY{$j}+1
*End for*
*C_OBJECT*($obj) //Initialize graph settings
*OB SET*($obj;Graph type;1)
*GRAPH*(vGraph;$obj;$aX;$aY) //Draw the graph
--
Kirk Brooks
San Francisco, CA
=======================
What can be said, can be said clearly,
and what you can’t say, you should shut up about
*Wittgenstein and the Computer *
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive: http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub: mailto:[email protected]
**********************************************************************