Getting normal distributions out of random(number)
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
Getting normal distributions out of random(number)
Hi Livecode!
I'm trying to use the random(X) function to draw numbers from a normal distribution. However, it appears that the random function on it's own gives every integer up to the limit specified an equal chance of being drawn (i.e., a flat distribution).
Any tips on how to get the numbers pulled to be more normative?
I'm trying to use the random(X) function to draw numbers from a normal distribution. However, it appears that the random function on it's own gives every integer up to the limit specified an equal chance of being drawn (i.e., a flat distribution).
Any tips on how to get the numbers pulled to be more normative?
-
- VIP Livecode Opensource Backer
- Posts: 9567
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Getting normal distributions out of random(number)
But a normal distribution is a statistical construct, and has nothing to do with generating random numbers.
On the complete other hand, if you do collect a dataset of random numbers, is that you want to create a normal distribution from them?
Craig newman
On the complete other hand, if you do collect a dataset of random numbers, is that you want to create a normal distribution from them?
Craig newman
-
- VIP Livecode Opensource Backer
- Posts: 9567
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Getting normal distributions out of random(number)
I re-read your post.
Is it that you want to take a normal distribution dataset, and extract values from it derived from random numbers within the distribution range? That is easy, if true.
Craig
Is it that you want to take a normal distribution dataset, and extract values from it derived from random numbers within the distribution range? That is easy, if true.
Craig
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Getting normal distributions out of random(number)
Hi all.
This is a general principle in mathematical statistics.
One starts always with (real) random numbers out of range [0,1] which are uniformly distributed.
These are easily generated in LiveCode by dividing:
For example, set maxx=10^9. Then take v= (random(maxx+1)-1)/maxx.
Then one takes the x such that F(x)=v (i.e. x=the inverse value of v of the distribution function F). These x values have the distribution function F, if F is an invertible distribution function.
Now we have to approximate, because the distribution function of the normal distribution is not invertible. (It is not that math doesn't know the inverse, but it is proved, that there is no inverse.)
A method that is well known to be "good enough" and easy to implement is the "marsaglia polar method", see https://en.wikipedia.org/wiki/Marsaglia_polar_method
Scroll the wiki page down to see the java code and use it as "pseudocode" for your LC implementation.
[If you need help with that, come back to here.]
This is a general principle in mathematical statistics.
One starts always with (real) random numbers out of range [0,1] which are uniformly distributed.
These are easily generated in LiveCode by dividing:
For example, set maxx=10^9. Then take v= (random(maxx+1)-1)/maxx.
Then one takes the x such that F(x)=v (i.e. x=the inverse value of v of the distribution function F). These x values have the distribution function F, if F is an invertible distribution function.
Now we have to approximate, because the distribution function of the normal distribution is not invertible. (It is not that math doesn't know the inverse, but it is proved, that there is no inverse.)
A method that is well known to be "good enough" and easy to implement is the "marsaglia polar method", see https://en.wikipedia.org/wiki/Marsaglia_polar_method
Scroll the wiki page down to see the java code and use it as "pseudocode" for your LC implementation.
[If you need help with that, come back to here.]
shiftLock happens
-
- VIP Livecode Opensource Backer
- Posts: 9567
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Getting normal distributions out of random(number)
How did I know that Hermann was going to be the next one to post?
Craig
Craig
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Getting normal distributions out of random(number)
Perhaps I told you some time ago that mathematical statistics is a field in math I know a bit more than nothing (after 30 years of learning in that field, with my job).dunbarx wrote:How did I know that Hermann was going to be the next one to post?
p.s. @totb
I forgot that the polar method starts from "tranformed" uniform distributed values in interval [-1,1].
So, for example, set maxx=10^9. Then get such values by v1= 2*(random(maxx+1)-1)/maxx -1.
shiftLock happens
Re: Getting normal distributions out of random(number)
I see, let me explain what I'm trying to do a bit.
I'm trying to get Livecode to spit out a number between 1-100 that is normally distributed around 60 with a standard deviation of 10. The random function sounds like the wrong one to be using now that you've pointed it out to me. Before I dive into some of the more complex stuff mentioned, is there a simpler way to get at what I'm trying to do?
I'm trying to get Livecode to spit out a number between 1-100 that is normally distributed around 60 with a standard deviation of 10. The random function sounds like the wrong one to be using now that you've pointed it out to me. Before I dive into some of the more complex stuff mentioned, is there a simpler way to get at what I'm trying to do?
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Getting normal distributions out of random(number)
I gave you already all essential help. The rest is simple.
Are you bachelor student and is this your homework (a typical bachelor homework in year 2)?
If not I'll publish a stack that gives you such numbers with a click.
I already implemented it, LC 6.7.11 generates 10000 such numbers in at about 180 millisecs, LC 8.1.9 and LC 9.0.0-dp11 need at about 540 ms for that.
The result is not too bad, here a typical outcome:
The sample density of 25000 random numbers out of a normal (60,10)-distribution.
Are you bachelor student and is this your homework (a typical bachelor homework in year 2)?
If not I'll publish a stack that gives you such numbers with a click.
I already implemented it, LC 6.7.11 generates 10000 such numbers in at about 180 millisecs, LC 8.1.9 and LC 9.0.0-dp11 need at about 540 ms for that.
The result is not too bad, here a typical outcome:
The sample density of 25000 random numbers out of a normal (60,10)-distribution.
- Attachments
-
- Red: the frequencies over the single integers. Gray: the theoretical density.
- normalDistributedNums.png (18.82 KiB) Viewed 4657 times
shiftLock happens
Re: Getting normal distributions out of random(number)
Definitely not an undergrad doing this for homework, just trying to get something working for a replication study. I'd greatly appreciate if you could post your stack so I can work backwards from it!
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Getting normal distributions out of random(number)
I'll publish a stack in the Raspi stacks collection with a graphical display for several more distribution functions within the next weeks.
For now make a new stack with a field "out" and a field "out1".
Then script a button with the following.
This generates with each click N=25000 random numbers out of a normal distribution with Mean=60 and StdDev=10 (fld "out") and categorizes them to integers (histogram values, fld "out1").
You can adjust N, Mean and StdDev. The integer-categories make only sense while StdDev > 4.
You use best LC 6.7.11 for that. This is for such computations at least twice as fast as later versions: LC 6.7.11 needs at about 500 millisecs for the above on a medium fast machine.
For now make a new stack with a field "out" and a field "out1".
Then script a button with the following.
This generates with each click N=25000 random numbers out of a normal distribution with Mean=60 and StdDev=10 (fld "out") and categorizes them to integers (histogram values, fld "out1").
You can adjust N, Mean and StdDev. The integer-categories make only sense while StdDev > 4.
Code: Select all
constant mx=1000000000
local spare, isSpareReady=false
-- This is the Marsaglia-polar-method
-- Returns a random Normal(m,s) number
function getGaussian m,s
if isSpareReady then
put false into isSpareReady
return m+s*spare
else
repeat while q >= 1 or q=0
put 2*(random(mx+1)-1)/mx - 1 into u
put 2*(random(mx+1)-1)/mx - 1 into v
put u*u + v*v into q
end repeat
put true into isSpareReady
put sqrt(-2*ln(q)/q) into mul
put v*mul into spare
return m+s*u*mul
end if
end getGaussian
on mouseUp
lock screen; lock messages
set the randomseed to the seconds
put 25000 into nbs -- sample size
put 60 into tMean
put 10 into tStd
repeat nbs -- compute and display 6 decimals
put cr & format("%.6f", getGaussian(tMean,tStd)) after vs
end repeat
put char 2 to -1 of vs into vs
sort vs numeric
put vs into fld "out"
-- categorize to integers
repeat for each line L in vs
add 1 to hstgrm[trunc(L)]
end repeat
-- list (value,frequency) = histogram values
repeat for each line k in the keys of hstgrm
put cr & (k,hstgrm[k]) after vs1
end repeat
put char 2 to -1 of vs1 into vs1
sort vs1 numeric
put vs1 into fld "out1"
unlock screen; unlock messages
end mouseUp
shiftLock happens
Re: Getting normal distributions out of random(number)
That helps a great deal; thanks!