I would like to generate numbers into an array that has normal distribution. Is there any function in objective-c or c that can help to get the result easily without any math?
-
You are true, but I thought there is some methods that can help this achieve a lot easier – Infinite Possibilities Mar 03 '13 at 13:31
-
3This might help: http://stackoverflow.com/questions/12948293/ios-gaussian-distribution-of-random-numbers – Khaled Barazi Mar 03 '13 at 13:44
2 Answers
Use the the Box-Muller-Transformation:
1.) you need two uniform distributed random numbers u and v as doubles in the interval (0,1] (0 needs to be excluded):
double u =(double)(random() %100000 + 1)/100000; //for precision
double v =(double)(random() %100000 + 1)/100000; //for precision
2.) calculate the uniform distributed value with average of 0 and the standard deviation sigma of 1:
double x = sqrt(-2*log(u))*cos(2*pi*v); //or sin(2*pi*v)
3.) if needed add sigma and average for your target distribution like this:
double y = x * sigmaValue + averageValue;
4.) put it in an array
[randomNumberArray addObject:[NSNumber numberWithDouble:y]]
There is no function norminv
for objc. So, math is needed here.
Edit: I like using random()
to be able to seed the random value generator

- 2,992
- 3
- 37
- 48
-
This is really a great solution, but one questions: will this order the numbers? – Infinite Possibilities Mar 03 '13 at 20:30
-
Unfortunately it won't. And (for large arrays) please consider to check and exclude u and v for the value 0 and 1. Otherwise the log-function won't work. – JFS Mar 03 '13 at 20:39
-
What is wrong with sorting it with `[randomNumberArray sortedArrayUsingSelector:@selector(compare:)]` afterwards? – JFS Mar 04 '13 at 07:25
-
-
1@dwbrito, it will generate negative numbers as well. If you follow the equations until step 2 it will generate normal distributed values with the average of zero (example: http://www.regentsprep.org/Regents/math/algtrig/ATS2/normal67.gif). So, there will be positive and negative values. – JFS May 20 '13 at 08:54
-
@JFS, I thought it was only negative. I ended up using the Ziggurat algorithm – dwbrito May 20 '13 at 09:52
-
1@dwbrito, no it is not just generating negative values. The Ziggurat algorithm is actually similar but not as easy to implement than the Box-Muller transformation. – JFS May 20 '13 at 17:50
Let me preface this by saying, please, correct me if I'm wrong!
It's my understanding that the Box-Muller Transformation relies on the source numbers being them selves uniformly distributed, thus using random() or rand() as the source data-set for Box-Muller will NOT necessarily produce a uniform distribution.
It is instead intended to take a generic set of uniformly distributed random numbers, and produce independent pairs of random numbers uniformly distributed in a 2D coordinate system.
Wikipedia: Box-Muller Transform
There is however another way:
On most Unix systems (and thus Objective C on iOS or OSX) using the rand48 library of functions:
double drand48(void);
void srand48(long int seedval);
srand48() seeds the generator, and drand48() produces random numbers uniformly distributed over the interval [0.0 - 1.0]

- 25,966
- 23
- 76
- 87
-
thank you for the interesting discussion. As long as there are two independent uniform distributed values in the interval of (0,1] the Box-Muller approach should generate normal distributed values. But I agree that the source quality for random number generator has an effect on the results. I don't like the quality of `random()` but I need to create the same sequence with normal distributed numbers. That's why I can't use arc4random() or other better approaches. How would I implement these Unix function in iOS? – JFS Sep 06 '13 at 08:04
-