ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm a little stuck trying to write function to generate a Gaussian Random number with range cut-offs. I've google'd my ass off, believe me, and I'm close to my answer but not quite there. Here's what I got so far:
Code:
// Returns a random number between [-1, 1)
float UnitRV() {
return 2 * ((float) rand()/RAND_MAX) - 1;
}
// Uses the Polar method to generate a normal distribution with mean 0 and standard deviation 1
// http://ct.radiology.uiowa.edu/~jiang...ml/node41.html
float GaussianValue(int mean, int range) {
static int iset = 0;
static float gset;
float fac, rsq, v1, v2;
float result;
int true_range;
if (iset == 0) {
do {
v1 = 2.0 * UnitRV() - 1.0;
v2 = 2.0 * UnitRV() - 1.0;
rsq = v1 * v1 + v2 * v2;
} while (rsq >= 1.0 || rsq == 0.0);
fac = sqrt (-2.0 * log (rsq) / rsq);
gset = v1 * fac;
iset = 1;
result = v2 * fac;
}
else {
iset = 0;
result = gset;
}
return result;
}
The mean and range arguments in the GaussianValue function are what need to be used. Obviously to change the mean of the normal distribution I just have to add the mean argument to result, that's easy.
The hard thing is that I want to change the standard distribution so that sigma ~= range / 3. (So range will be the boundary of the 3rd standard deviation). I couldn't find any details on how this function computes the standard deviation. Does anyone know how it work? The GaussianValue function is currently almost the exact same as the source where I got it at. Thanks for any help
let X~N(mu,sigma) then z=((x-mu)/sigma)~N(0,1) this is basic normal dist stuff now lets do it backwards ie let z~N(0,1) then X=(sigma*z + mu)~N(mu,sigma) so there ya go. with a N(0,1) generator to make it N(mu, sigma) transform it by sigma*X + mu.
you can prove this without too much trouble by writing E[X] as integral(x*p(x)) (for continuous, obviously sum for discrete) and showing E[aX+b] = aE[X] + b and then considering variance as E[X^2] - E^2[X]
also your code is wrong, it works by writing the normal distribution integral in 2d space and picking a point(v1,v2) in the unit circle which is why you reject if v1^2 + v2^2 > 1. so v1,v2 should lie between -1 and 1 which is why the code calls UnitRV() which should return a value between 0 and 1 however your UnitRV returns a value between -1 and 1 putting v1 and v2 in the range -3 to 1 which shouldnt effect your numbers (i think) but will require more numbers to be generated per each (x1,x2)
<edit>
ive just looked at the maths for generating a N(mu,sigma) distribution closely instead of guessing(as i did originally), you have to do a translated elliptical substitution (x-a=q*cos t, y-b=r*sin t rather than the much simpler polar subsition x=r*cos t,y=r*sin t) into the double integral and its far too much work when you can just multiply by variance and add mean to the resulting N(0,1) numbers.
**i deleted the paragraph that was here cos it was a load of nonsense
</edit>
my masters project is based on random number generation so i do know quite a bit about it and have probably assumed too much knowledge on your part, if theres anything you dont get then please ask.
Thanks kev, that made perfect sense. I really need to review my mathematics, you made it seem so easy. As for your concerns on the function for finding N(1,0), I did change it a little after reading some more (made it simpler) and I've done several test runs on it and it seemed good enough for me. If I introduce eliptical geometry all of those trigonometric calls to the math library are going to consume CPU cycles, and this function doesn't have to be entirely accurate for my purposes. Its accurate enough as it is now, but thanks for your concern.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.