यादृच्छिक गाऊसी चर


118

क्या .NET के मानक पुस्तकालय में एक वर्ग है जो मुझे यादृच्छिक चर बनाने की कार्यक्षमता देता है जो गौसियन वितरण का पालन करता है?


http://mathworld.wolfram.com/Box-MullerTransformation.html दो यादृच्छिक चर का उपयोग करके, आप एक गाऊसी वितरण के साथ यादृच्छिक मान उत्पन्न कर सकते हैं। यह मुश्किल काम नहीं है।
जरेट मेयर

1
मैं एक गणितीय परिणाम जोड़ना चाहूंगा जो सामान्य वितरण के लिए तुरंत उपयोगी नहीं है (जटिल सीडीएफ के कारण), लेकिन कई अन्य वितरणों के लिए उपयोगी है। यदि आप Random.NextDouble()किसी भी वितरण के CDF के व्युत्क्रम में [0,1] (साथ ) में समान रूप से वितरित यादृच्छिक संख्याएँ डालते हैं , तो आपको यादृच्छिक संख्याएँ मिलेंगी जो THAT वितरण का अनुसरण करती हैं। यदि आपके आवेदन को सामान्य रूप से वितरित चर की आवश्यकता नहीं है, तो लॉजिस्टिक वितरण सामान्य के बहुत करीब है और आसानी से उलटा सीडीएफ है।
ओजाह

1
MedallionRandom NuGet पैकेज एक से सामान्य रूप से वितरित मान वापस लाने के लिए एक विस्तार विधि शामिल Randomबॉक्स मुलर को बदलने का उपयोग कर (नीचे कई जवाब में बताया गया)।
चेसमैडलियन

जवाबों:


181

एक त्वरित और गंदे समाधान के लिए बॉक्स-मुलर ट्रांसफॉर्म का उपयोग करने का जरेट का सुझाव अच्छा है। एक साधारण कार्यान्वयन:

Random rand = new Random(); //reuse this if you are generating many
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 + stdDev * randStdNormal; //random normal(mean,stdDev^2)

3
मैंने इसका परीक्षण किया और मैथनेट के मेरसेन ट्विस्टर आरएनजी और नॉर्मडिस्ट्रिएशन की तुलना में। आपका संस्करण दो बार से अधिक तेज़ है और अंतिम परिणाम मूल रूप से एक ही है ("घंटियाँ" का दृश्य निरीक्षण)।
जोहान जेरेल

4
@ जोहान, यदि आप शुद्ध गति की तलाश कर रहे हैं, तो ज़िगोरैट एल्गोरिथ्म को आमतौर पर सबसे तेज़ दृष्टिकोण के रूप में पहचाना जाता है। इसके अलावा, उपरोक्त दृष्टिकोण को एक कॉल से अगले तक एक मूल्य ले जाने से तेज किया जा सकता है।
ड्रू नोक

नमस्ते, stdDevचर को किस पर सेट किया जाना चाहिए ? मैं समझता हूं कि इसे विशिष्ट आवश्यकताओं के लिए कॉन्फ़िगर किया जा सकता है, लेकिन क्या कोई सीमाएं हैं (यानी अधिकतम / मिनट मान)?
hofnarwillie

@hofnarwillie stdDev सामान्य वितरण का पैमाना है, जो कि कोई भी सकारात्मक संख्या हो सकती है। यह जितना बड़ा होगा, उत्पन्न संख्या उतनी ही अधिक फैल जाएगी। एक मानक सामान्य वितरण उपयोग के लिए मापदंडों का मतलब है = 0 और stdDev = 1।
योयॉयोसेफ

1
@ जेक मुझे ऐसा नहीं लगता। केवल -2 * Math.Log (u1) sqrt के अंदर है, और लॉग हमेशा नकारात्मक या शून्य होगा क्योंकि u1 <= 1
yoyoyoyosef

62

यह प्रश्न .NET Gaussian जनरेशन के लिए Google के ऊपर ले जाया गया प्रतीत होता है, इसलिए मुझे लगा कि मैं एक उत्तर पोस्ट करूंगा।

मैंने .NET रैंडम वर्ग के लिए कुछ विस्तार विधियां बनाई हैं , जिसमें बॉक्स-मुलर ट्रांसफॉर्मेशन का कार्यान्वयन शामिल है। चूंकि वे एक्सटेंशन हैं, इसलिए जब तक परियोजना शामिल है (या आप संकलित DLL का संदर्भ देते हैं), तब भी आप कर सकते हैं

var r = new Random();
var x = r.NextGaussian();

आशा है कि कोई भी बेशर्म प्लग को याद नहीं करेगा।

परिणामों का नमूना हिस्टोग्राम (इसे शामिल करने के लिए एक डेमो ऐप शामिल है):

यहां छवि विवरण दर्ज करें


आपके विस्तार वर्ग के पास कुछ चीजें हैं जिनकी मुझे तलाश थी! धन्यवाद!
थॉमस

1
आपके पास अपने NextGaussian पद्धति में एक छोटा बग है। NextDouble () एक यादृच्छिक फ़्लोटिंग-पॉइंट संख्या देता है जो 0.0 से अधिक या बराबर है, और 1.0 से कम है। तो आपके पास u1 = 1.0 होना चाहिए - NextDouble () .... अन्य लॉग (0) उड़ा देगा
मिच गेहूं

21

Math.NET यह कार्यक्षमता प्रदान करता है। ऐसे:

double mean = 100;
double stdDev = 10;

MathNet.Numerics.Distributions.Normal normalDist = new Normal(mean, stdDev);
double randomGaussianValue=   normalDist.Sample();

आप यहाँ प्रलेखन पा सकते हैं: http://numerics.mathdotnet.com/api/MathNet.Numerics.Distributions/Normal.htm


बहुत बढ़िया जवाब! यह फ़ंक्शन MathNet.Numerics पैकेज में NuGet पर उपलब्ध है । हमेशा अपने खुद के रोल करने के लिए महान नहीं है।
jpmc26

8

मैंने Microsoft Connect पर ऐसी सुविधा के लिए एक अनुरोध बनाया है। यदि यह ऐसी चीज है जिसे आप ढूंढ रहे हैं, तो कृपया इसे वोट करें और इसकी दृश्यता बढ़ाएं।

https://connect.microsoft.com/VisualStudio/feedback/details/634346/guassian-normal-distribution-random-numbers

यह सुविधा जावा एसडीके में शामिल है। इसका कार्यान्वयन प्रलेखन के भाग के रूप में उपलब्ध है और इसे आसानी से C # या अन्य .NET भाषाओं में पोर्ट किया जाता है।

यदि आप शुद्ध गति की तलाश कर रहे हैं, तो Zigorat Algorithm को आमतौर पर सबसे तेज़ दृष्टिकोण के रूप में पहचाना जाता है।

मैं इस विषय का विशेषज्ञ नहीं हूँ, हालांकि - मैं अपने रोबोअप 3 डी सिम्युलेटेड रोबोटिक फुटबॉल लाइब्रेरी के लिए एक कण फ़िल्टर को लागू करते समय इसके लिए आवश्यकता पर आया था और जब यह फ्रेमवर्क में शामिल नहीं किया गया था तो आश्चर्यचकित था।


इस बीच, इसके लिए एक रैपर Randomबॉक्स मुलर ध्रुवीय विधि का कुशल कार्यान्वयन प्रदान करता है:

public sealed class GaussianRandom
{
    private bool _hasDeviate;
    private double _storedDeviate;
    private readonly Random _random;

    public GaussianRandom(Random random = null)
    {
        _random = random ?? new Random();
    }

    /// <summary>
    /// Obtains normally (Gaussian) distributed random numbers, using the Box-Muller
    /// transformation.  This transformation takes two uniformly distributed deviates
    /// within the unit circle, and transforms them into two independently
    /// distributed normal deviates.
    /// </summary>
    /// <param name="mu">The mean of the distribution.  Default is zero.</param>
    /// <param name="sigma">The standard deviation of the distribution.  Default is one.</param>
    /// <returns></returns>
    public double NextGaussian(double mu = 0, double sigma = 1)
    {
        if (sigma <= 0)
            throw new ArgumentOutOfRangeException("sigma", "Must be greater than zero.");

        if (_hasDeviate)
        {
            _hasDeviate = false;
            return _storedDeviate*sigma + mu;
        }

        double v1, v2, rSquared;
        do
        {
            // two random values between -1.0 and 1.0
            v1 = 2*_random.NextDouble() - 1;
            v2 = 2*_random.NextDouble() - 1;
            rSquared = v1*v1 + v2*v2;
            // ensure within the unit circle
        } while (rSquared >= 1 || rSquared == 0);

        // calculate polar tranformation for each deviate
        var polar = Math.Sqrt(-2*Math.Log(rSquared)/rSquared);
        // store first deviate
        _storedDeviate = v2*polar;
        _hasDeviate = true;
        // return second deviate
        return v1*polar*sigma + mu;
    }
}

हालांकि मुझे इसके कुछ मूल्य मिले। क्या कोई जांच सकता है कि क्या गलत है?
mk7

@ mk7, शून्य के आसपास केंद्रित एक गाऊसी संभाव्यता फ़ंक्शन नकारात्मक मान देने की संभावना है क्योंकि यह सकारात्मक मान देता है।
ड्रू नॉक

आप सही हे! चूंकि मैं गौसियन पीडीएफ के साथ एक विशिष्ट जनसंख्या में वजन की एक सूची प्राप्त करना चाहता हूं, मैं म्यू को 75, [किलो में] और सिग्मा को 10. पर सेट कर रहा हूं। हर यादृच्छिक वजन?
mk7

आप एक उदाहरण से ड्राइंग नमूने रख सकते हैं।
आकर्षित नोक

5

Math.NET Iridium "गैर-समान यादृच्छिक जनरेटर (सामान्य, पॉइसन, द्विपद, ...)" को लागू करने का दावा करता है।


ठीक से काम नहीं कर रहा है। यह साजिश रचने की कोशिश की, वर्दी यादृच्छिक यादृच्छिक नहीं।
निखिल चिलवंत

4

यहां यादृच्छिक चर उत्पन्न करने के लिए एक और त्वरित और गंदा समाधान है जो सामान्य वितरित हैं । यह कुछ यादृच्छिक बिंदु (x, y) खींचता है और जांचता है कि क्या यह बिंदु आपके प्रायिकता घनत्व फ़ंक्शन की वक्र के नीचे है, अन्यथा दोहराएं।

बोनस: आप केवल घनत्व फ़ंक्शन को बदलकर किसी भी अन्य वितरण (जैसे घातीय वितरण या पॉसन वितरण ) के लिए यादृच्छिक चर उत्पन्न कर सकते हैं ।

    static Random _rand = new Random();

    public static double Draw()
    {
        while (true)
        {
            // Get random values from interval [0,1]
            var x = _rand.NextDouble(); 
            var y = _rand.NextDouble(); 

            // Is the point (x,y) under the curve of the density function?
            if (y < f(x)) 
                return x;
        }
    }

    // Normal (or gauss) distribution function
    public static double f(double x, double μ = 0.5, double σ = 0.5)
    {
        return 1d / Math.Sqrt(2 * σ * σ * Math.PI) * Math.Exp(-((x - μ) * (x - μ)) / (2 * σ * σ));
    }

महत्वपूर्ण: के अंतराल y और मानकों σ और μ ताकि समारोह की वक्र यह अधिकतम / न्यूनतम अंक पर कटऑफ नहीं है (उदाहरण के लिए एक्स = मतलब पर)। एक बाउंडिंग बॉक्स के रूप में x और y के अंतराल के बारे में सोचें , जिसमें वक्र को फिट होना चाहिए।


4
स्पर्शजन्य, लेकिन यह वास्तव में पहली बार मुझे एहसास हुआ है कि आप यूस्बोड प्रतीकों का उपयोग कर सकते हैं जैसे कि कुछ गूंगा जैसे कि _sigma या _phi ...
Slothario

@Slothario मैं 'कुछ गूंगा' का उपयोग करने के लिए हर जगह डेवलपर्स को धन्यवाद देता हूं: |
user2864740

2

मैं @ yoyoyoyosef के उत्तर को और भी तेज़ बनाकर और एक आवरण वर्ग लिखना चाहता हूँ। ओवरहेड का मतलब दो बार उपवास के रूप में नहीं हो सकता है, लेकिन मुझे लगता है कि यह लगभग दो बार उपवास के रूप में होना चाहिए । यह थ्रेड-सुरक्षित नहीं है, हालांकि।

public class Gaussian
{
     private bool _available;
     private double _nextGauss;
     private Random _rng;

     public Gaussian()
     {
         _rng = new Random();
     }

     public double RandomGauss()
     {
        if (_available)
        {
            _available = false;
            return _nextGauss;
        }

        double u1 = _rng.NextDouble();
        double u2 = _rng.NextDouble();
        double temp1 = Math.Sqrt(-2.0*Math.Log(u1));
        double temp2 = 2.0*Math.PI*u2;

        _nextGauss = temp1 * Math.Sin(temp2);
        _available = true;
        return temp1*Math.Cos(temp2);
     }

    public double RandomGauss(double mu, double sigma)
    {
        return mu + sigma*RandomGauss();
    }

    public double RandomGauss(double sigma)
    {
        return sigma*RandomGauss();
    }
}

2

@ नोक्स और @ हैमर के उत्तर के विस्तार के कारण, मैंने 'गॉसियन' क्लास भी लागू किया है, लेकिन मेमोरी स्पेस को सरल बनाने के लिए, मैंने इसे रैंडम क्लास का बच्चा बनाया है ताकि आप बेसिक नेक्स्ट (), नेक्स्टड डबल () भी कॉल कर सकें। , आदि गौसियन वर्ग से और साथ ही इसे संभालने के लिए एक अतिरिक्त रैंडम ऑब्जेक्ट बनाने के लिए बिना। मैंने वैश्विक स्तर के गुणों के _available, और _nextgauss को भी समाप्त कर दिया, क्योंकि मैंने उन्हें नहीं देखा था क्योंकि यह वर्ग उदाहरण आधारित है, यह थ्रेड-सुरक्षित होना चाहिए, यदि आप प्रत्येक थ्रेड को अपनी गॉसियन ऑब्जेक्ट देते हैं। मैंने सभी रन-टाइम आवंटित चर को फ़ंक्शन से बाहर स्थानांतरित कर दिया और उन्हें वर्ग गुण बना दिया, इससे मेमोरी मैनेजर को कॉल की संख्या कम हो जाएगी क्योंकि 4 डबल्स को सैद्धांतिक रूप से कभी भी तब तक आवंटित नहीं किया जाना चाहिए जब तक कि ऑब्जेक्ट नष्ट न हो जाए।

public class Gaussian : Random
{

    private double u1;
    private double u2;
    private double temp1;
    private double temp2;

    public Gaussian(int seed):base(seed)
    {
    }

    public Gaussian() : base()
    {
    }

    /// <summary>
    /// Obtains normally (Gaussian) distrubuted random numbers, using the Box-Muller
    /// transformation.  This transformation takes two uniformly distributed deviates
    /// within the unit circle, and transforms them into two independently distributed normal deviates.
    /// </summary>
    /// <param name="mu">The mean of the distribution.  Default is zero</param>
    /// <param name="sigma">The standard deviation of the distribution.  Default is one.</param>
    /// <returns></returns>

    public double RandomGauss(double mu = 0, double sigma = 1)
    {
        if (sigma <= 0)
            throw new ArgumentOutOfRangeException("sigma", "Must be greater than zero.");

        u1 = base.NextDouble();
        u2 = base.NextDouble();
        temp1 = Math.Sqrt(-2 * Math.Log(u1));
        temp2 = 2 * Math.PI * u2;

        return mu + sigma*(temp1 * Math.Cos(temp2));
    }
}

स्थानीय चर भी दोस्त हैं।
user2864740

1

ड्रू नोक के जवाब पर विस्तार करते हुए, यदि आपको बॉक्स-मुलर (लगभग 50-75% तेजी से) से बेहतर प्रदर्शन की आवश्यकता है, तो कॉलिन ग्रीन ने सी # में ज़िगगुरैट एल्गोरिथ्म का कार्यान्वयन साझा किया है, जिसे आप यहां पा सकते हैं:

http://heliosphan.org/zigguratalgorithm/zigguratalgorithm.html

ज़िगगुरैट वक्र से काफी दूर गिरने वाले मूल्यों को संभालने के लिए एक लुकअप टेबल का उपयोग करता है, जिसे वह जल्दी स्वीकार या अस्वीकार कर देगा। लगभग 2.5% समय में, यह निर्धारित करने के लिए आगे की गणना करनी है कि एक नंबर पर वक्र के किस तरफ है।


0

आप Infer.NET की कोशिश कर सकते हैं। यह अभी तक वाणिज्यिक लाइसेंस प्राप्त नहीं है। यहाँ लिंक है

यह .NET के लिए एक संभाव्य ढांचा है। मेरे Microsoft अनुसंधान का विकास हुआ। उनके पास बर्नौली, बीटा, गामा, गौसियन, पॉइसन के वितरण के लिए .NET प्रकार हैं, और शायद कुछ और जो मैंने छोड़ दिए हैं।

आप जो चाहते हैं वह पूरा हो सकता है। धन्यवाद।


0

यह मेरा सरल बॉक्स मुलर प्रेरित कार्यान्वयन है। आप अपनी आवश्यकताओं को पूरा करने के लिए संकल्प को बढ़ा सकते हैं। हालांकि यह मेरे लिए बहुत अच्छा काम करता है, यह एक सीमित श्रेणी का अनुमान है, इसलिए ध्यान रखें कि पूंछ बंद और परिमित हैं, लेकिन निश्चित रूप से आप आवश्यकतानुसार उनका विस्तार कर सकते हैं।

    //
    // by Dan
    // islandTraderFX
    // copyright 2015
    // Siesta Key, FL
    //    
// 0.0  3231 ********************************
// 0.1  1981 *******************
// 0.2  1411 **************
// 0.3  1048 **********
// 0.4  810 ********
// 0.5  573 *****
// 0.6  464 ****
// 0.7  262 **
// 0.8  161 *
// 0.9  59 
//Total: 10000

double g()
{
   double res = 1000000;
   return random.Next(0, (int)(res * random.NextDouble()) + 1) / res;
}

public static class RandomProvider
{
   public static int seed = Environment.TickCount;

   private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
       new Random(Interlocked.Increment(ref seed))
   );

   public static Random GetThreadRandom()
   {
       return randomWrapper.Value;
   }
} 

यह मेरा सरल बॉक्स मुलर प्रेरित कार्यान्वयन है। आप अपनी आवश्यकताओं को पूरा करने के लिए संकल्प को बढ़ा सकते हैं। यह बहुत तेज़, सरल है, और मेरे न्यूरल नेट ऐप्स के लिए काम करता है, जिन्हें काम पाने के लिए लगभग घनत्व प्रकार के प्रायिकता घनत्व फ़ंक्शन की आवश्यकता होती है। आशा है कि यह किसी को समय और सीपीयू चक्र को बचाने में मदद करता है। हालांकि यह मेरे लिए बहुत अच्छा काम करता है, यह एक सीमित श्रेणी का अनुमान है, इसलिए ध्यान रखें कि पूंछ बंद और परिमित हैं, लेकिन निश्चित रूप से आप आवश्यकतानुसार उनका विस्तार कर सकते हैं।
डैनियल हावर्ड

1
हे डैनियल, मैंने एक संपादन का सुझाव दिया है जो आपकी टिप्पणी से विवरण को उत्तर में ही शामिल करता है। यह उस '//' को भी हटा देता है जो आपके उत्तर में वास्तविक कोड टिप्पणी कर रहा था। आप अपने आप को संपादित कर सकते हैं यदि आप चाहते हैं / यदि यह अस्वीकृत हो जाता है :)
जुलाब

-1

मुझे नहीं लगता कि वहाँ है। और मैं वास्तव में आशा करता हूं कि ऐसा नहीं है, क्योंकि फ्रेमवर्क पहले से ही पर्याप्त रूप से फूला हुआ है, बिना ऐसी विशेष कार्यक्षमता के इसे और भी अधिक भरना है।

यद्यपि एक तीसरे पक्ष के .NET समाधान के लिए http://www.extremeoptimization.com/Statistics/UsersGuide/ContinuousDistributions/NormalDistribution.aspx और http://www.vbforums.com/showthread.php?t/488959 पर एक नज़र डालें ।


7
गौसियन वितरण 'विशेष' कब से है? AJAX या डेटाटेबल्स की तुलना में यह कहीं अधिक सामान्य है।
ट्रामापॉनी

@TraumaPony: क्या आप गंभीरता से सुझाव दे रहे हैं कि नियमित आधार पर AJAX के उपयोग की तुलना में अधिक डेवलपर गौसियन वितरण का उपयोग करें?
डेविड अर्नो

3
संभवत:; मैं यह कह रहा हूं कि यह कहीं अधिक विशिष्ट है। इसका केवल एक उपयोग है- वेब ऐप। गाऊसी वितरण के असंबद्ध उपयोगों की एक अविश्वसनीय संख्या है।
ट्रॉमापोनी

@DavidArno, क्या आप गंभीरता से सुझाव दे रहे हैं कि कम कार्यक्षमता एक रूपरेखा में सुधार करती है।
जोडरेल

1
@Jodrell, एक विशिष्ट उदाहरण का हवाला देते हुए, मुझे लगता है कि MVC को एक अलग फ्रेमवर्क बनाने का निर्णय लिया गया था, बल्कि मुख्य .NET फ्रेमवर्क के हिस्से के रूप में, एक अच्छा था।
डेविड अरनो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.