Re: Random normal distribution values

2019-12-26 Thread Arnaud de Montard via 4D_Tech

> Le 24 déc. 2019 à 23:59, Kirk Brooks via 4D_Tech <4d_tech@lists.4d.com> a 
> écrit :
> 
> Who doesn't like an(other) discussion about random numbers?

Hi Kirk, 
I like  ;-)  

If you need a fast random function, calling 'Random' 16 times at once may 
result in poor performances; but the main problem is the use of 'Random' 
itself, see here:

From the 2 graphs that look like growing grass, the upper one uses 'Random', 
the lower uses 'Generate uuid'. The 'Random' function returns a majority of 
small values, while using uuid gives a good distribution (the opposite would be 
unexpected and boring…). If you're interested, there's a link to a small test 
4db at the bottom of the tread, it's quite easy to add another generator and 
try it. 

-- 
Arnaud de Montard 




**
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Random normal distribution values

2019-12-24 Thread Kirk Brooks via 4D_Tech
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:4d_tech-unsubscr...@lists.4d.com
**