It's been a bit quiet round here recently due to project work at the office primarily with little Grasshopper work and little in the way of interesting snippets. However, one which I've decided to put here for future use is a function to calculate a log normal value from a given average and a given standard deviation from that average. I've used this function a few times now for one thing or another and keep having to refer to old code to find it when I need it again. That being inefficient, I decided to drop the function on here for later use, and maybe for someone else to find useful as well.
Function for calculating
The function takes two inputs, the average and the value representing one standard deviation from the average. If this values are more global in your code you can of course remove the parameters accordingly.
double LogNormalValue(double average, double stdDev)
const int iSum = 12;
double mu = average;
double sigma = stdDev;
double mu2 = mu * mu;
double sigma2 = sigma * sigma;
double sq = Math.Sqrt(Math.Log(1 + sigma2/mu2)); //Standard deviation of normal distribution being put into log normal
double mean = Math.Log(mu) - (sq * sq)/2; //Mean of the normal distribution put into log normal
double x = 0; //Random value to generate
//Normal distribution generation based on Baker Triech
for(int a = 0; a < iSum; a++)
x+= (double)RandomValue / Random_Max;
//In C++, this can be achieved using the rand() method (x += (double)rand() / RAND_MAX;
//In C# you have to be careful with the random number generator seeding, it's better to use a static Random variable in the class and use like so:
//x += (double)rand.next() / Int32.MaxValue;
x -= iSum / 2.0;
return Math.Exp(x * sq + mean); //Return log normal value
This is a pseudo-code implementation of generating a log normal value, mainly due to different languages having different implementations of generating random numbers.
C# seeding issue
Remember not to declare a new random instance in the for loop if you're doing this in C#, as you'll encounter difficulties from how the seeding works. If you intend to call this method often (e.g. within a for loop generating a load of log normal values) then I would strongly recommend putting the random instance as a global variable and calling it that way.