C# Normal Random Number [duplicate]
I would like to create a function that accepts Double mean
, Double deviation
and returns a random number with a normal distribution.
Example: if I pass in 5.00 as the mean and 2.00 as the deviation, 68% of the time I will get a number between 3.00 and 7.00
My statistics is a little weak…. Anyone have an idea how I should approach this? My implementation will be C# 2.0 but feel free to answer in your language of choice as long as the math functions are standard.
I think this might actually be what I am looking for. Any help converting this to code?
Thanks in advance for your help.
See this CodeProject article: Simple Random Number Generation. The code is very short, and it generates samples from uniform, normal, and exponential distributions.
You might be interested in Math.NET, specifically the Numerics package.
Caveat: The numerics package targets .NET 3.5. You may need to use the Iridium package if you are targeting an earlier version...
Here is some C that returns two values (rand1 and rand2), just because the algorithm efficiently does so. It is the polar form of the Box-Muller transform.
void RandVal (double mean1, double sigma1, double *rand1, double mean2, double sigma2, double *rand2)
{
double u1, u2, v1, v2, s, z1, z2;
do {
u1 = Random (0., 1.); // a uniform random number from 0 to 1
u2 = Random (0., 1.);
v1 = 2.*u1 - 1.;
v2 = 2.*u2 - 1.;
s = v1*v1 + v2*v2;
} while (s > 1. || s==0.);
z1 = sqrt (-2.*log(s)/s)*v1;
z2 = sqrt (-2.*log(s)/s)*v2;
*rand1 = (z1*sigma1 + mean1);
*rand2 = (z2*sigma2 + mean2);
return;
}
This library is pretty good also:
.NET random number generators and distributions
Sorry I don't have any code for you but I can point you to some algorithms on Wikipedia. The algorithm you choose I guess depends on how accurate you want it and how fast it needs to be.
For those referencing this question, an easy solution might be:
Random rand = new Random();
double normRand = alglib.invnormaldistribution(rand.NextDouble())
scale by mu and sigma as needed.
The alglib library is available at www.alglib.net
MathNet
from second top answer
public static double GenerateRandomVariant(double mean,double deviation,System.Random rand=null, int factor=1)
{
rand = rand ?? new Random();
double randNormal=(MathNet.Numerics.Distributions.Normal.Sample(rand, mean , deviation));
return factor * randNormal;
}
Box-Mueller Transform
from top answer via link (twice as fast?)
by u/yoyoyoyosef Random Gaussian Variables
public static double GenerateRandomVariant(double mean, double deviation, System.Random rand=null, int factor = 1)
{
rand = rand ?? new Random();
double u1 = 1.0 - rand.NextDouble(); //uniform(0,1] random doubles
double u2 = 1.0 - rand.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal=(
mean + deviation * randStdNormal); //random normal(mean,stdDev^2)
return randNormal * factor;
}
The MetaNumerics library, also .NET, will calculate a normal distribution (and just about anything else from statistics), super quickly. Have a look at the Feature's page for more details. The Codeplex page is here: http://metanumerics.codeplex.com/.
I know this post is a little old but I would like to share a small project I created yesterday. I think the easier way is to use C++ 11 and create a .dll in Managed C++. There's a link to the source and a zip containing the dll already compiled.
And the code I made :
// NormalDistributionRandom.h
#include <random>
#pragma once
using namespace System;
namespace NormalDistribution
{
class _NormalDistributionRandom
{
std::default_random_engine engine;
std::normal_distribution<double> distribution;
public:
_NormalDistributionRandom(double mean, double deviation) : distribution(mean, deviation)
{
}
double Next()
{
return distribution(engine);
}
};
public ref class NormalDistributionRandom
{
private:
void* Distribution;
public:
NormalDistributionRandom( double mean, double deviation)
{
Distribution = new _NormalDistributionRandom(mean, deviation);
}
double Next()
{
return ((_NormalDistributionRandom*)Distribution)->Next();
}
~NormalDistributionRandom()
{
this->!NormalDistributionRandom();
}
protected:
!NormalDistributionRandom()
{
if (Distribution != nullptr)
{
delete (_NormalDistributionRandom*)Distribution;
Distribution = nullptr;
}
}
};
}
精彩评论