Jump to content


Photo

Normaly distributed random number


  • Please log in to reply
6 replies to this topic

#1 None

None
  • Members
  • 3199 posts

Posted 12 March 2011 - 05:02 AM

Generating values from normal distribution:
An easy to program approximate approach, that relies on the central limit theorem, is as follows: generate 12 uniform U(0,1) deviates, add them all up, and subtract 6 — the resulting random variable will have approximately standard normal distribution. In truth, the distribution will be Irwin–Hall, which is a 12-section eleventh-order polynomial approximation to the normal distribution. This random deviate will have a limited range of (-6, 6).

NormalRand(x,y,int=1) { ;x lower y upper int for integer return
Loop 12
 {
 Random, var,0.0,1
 Num+=var
 }
norm := (int) ? Round((y+x)/2+((Num-6)*(y-x))/6) : (y+x)/2+((Num-6)*(y-x))/6
Return norm < x ? x : norm > y ? y : norm
}
MsgBox % NormalRand(0,10) ;random integer between 0 and 10
MsgBox % NormalRand(5,20,0) ;random float between 5 and 20
I thought a Graphic representation of the difference might help
Posted Image
the first is just random numbers (every point in the range has same probability) and the second has a normal distribution (points further from the center less likely)
SetMouseDelay, -1 ;this code generated that picture by having it click in paint
SetBatchLines, -1
#a::
MouseGetPos, x, y
Loop 5000
 Click % Rand(x-170,x-10) ", " Rand(y-80,y+80)
Loop 5000
 Click % NormalRand(x+10,x+170) ", " NormalRand(y-80,y+80)
Return

NormalRand(x,y,int=1) { ;x lower y upper int for integer return
Loop 12
 {
 Random, var,0.0,1
 Num+=var
 }
norm := (int) ? Round((y+x)/2+((Num-6)*(y-x))/6) : (y+x)/2+((Num-6)*(y-x))/6
Return norm < x ? x : norm > y ? y : norm
}

Rand(x,y) { ;just a random wrappr
Random, var,%x%,%y%
Return var
}

Edit: added picture and more example code
Edit: added some code to prevent it from returning values outside the range

#2 MasterFocus

MasterFocus
  • Moderators
  • 4126 posts

Posted 12 March 2011 - 07:04 AM

Possibly related:
--- Bell curve?
--- Box-Muller

#3 G. Sperotto

G. Sperotto
  • Members
  • 464 posts

Posted 05 July 2012 - 02:48 PM

I don't whant to revive an old topic, but this topic was commented on <!-- l --><a class="postlink-local" href="http://www.autohotkey.com/community/viewtopic.php?f=15&t=88079&p=548324#p548324">viewtopic.php?f=15&t=88079&p=548324#p548324</a><!-- l --> and i think the script is actually very useful.

So i whanted to say Congratulations on the work and thanks for sharing None! :)

#4 Wicked

Wicked
  • Members
  • 479 posts

Posted 07 July 2012 - 08:59 AM

I was messing around with this, getting random values from 0-25, msgboxing them in a loop. It seemed to be OK, but then returned a 26. O_o

After looping 1 million from 0-25, 622 were greater ten 25. >.<

#5 None

None
  • Members
  • 3199 posts

Posted 07 July 2012 - 04:47 PM

I was messing around with this, getting random values from 0-25, msgboxing them in a loop. It seemed to be OK, but then returned a 26. O_o

After looping 1 million from 0-25, 622 were greater ten 25. >.<

Oops, I Fixed it.

#6 Wicked

Wicked
  • Members
  • 479 posts

Posted 15 July 2012 - 05:03 AM

I hope you don't mind, but I simply rewrote it like:
nrand(x,y){
   f:=a_formatfloat
   setformat,float,0.6
   loop 12
      n+=rand(0.0,1)
   setformat,float,% f
   return (z:=((y>x ? y:x)+(x<y ? x:y))/2+((n-6)*((y>x ? y:x)-(x<y ? x:y)))/6)<(y>x ? y:x) ? z<(x<y ? x:y) ? (x<y ? x:y):z:(y>x ? y:x)
}

rand(x,y){
   random,v,% x,% y
   return v
}

When I tried yours, if x was greater then y, it always defaulted to the higher. :p. I know mine is very jumbled and not heavily optimised, but it's 1AM and I haven't slept in about 40 hours. :p.

#7 VxE

VxE
  • Fellows
  • 3504 posts

Posted 15 July 2012 - 09:28 AM

Consider this:
NormRand( lo=0.0, hi=1 ) {

	Static x := 0x7FFFFFFF

	Return lo + ( hi - lo ) * (Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)

			+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+Rand(-x,x)+12*x) / (24*x)

}



Rand( lo=0.0, hi=1 ) {

	Random, r, lo, hi

	Return r

}
Unnecessary loops will drive you loopy. :p