2012-03-31 14 views
1

Box-Muller法を使用して正規分布から値を生成する小さな関数を作成していますが、負の値を取得しています。ここで Box-Mullerメソッドを使用した正規分布からの値の生成

は、私のソースコードである

import random 

def generate_normal(mu, sigma): 
    u = random.random() 
    v = random.random() 

    z1 = sqrt(-2 * log(u)) * sin(2 * pi * v) 
    z2 = sqrt(-2 * log(u)) * cos(2 * pi * v) 

    x1 = mu + z1 * sigma 
    x2 = mu + z2 * sigma 

    return x2 

WAHTは、私が行方不明ですか?x1x2の両方で負の値が表示されています。例えば:

mu: 400 
sigma: 150 
u: 7.27333176449e-05 
v: 0.642384573173 
z1: -3.40497345242 
x1: -110.746017863 

と:

x2: -9.79324023117 

答えて

6

ユニットnormal distributionがゼロを中心に、プラスとマイナスの無限大へ外小さな尾部を有する両面。 99.7% of your valuesは3標準偏差以内にあり、他の0.3%はそうではありません。この例では

enter image description here

、400の平均および150の標準偏差と、あなたの値の99.7%は、平均の3つの標準偏差内に入る - 負含む間隔[-50850]数字。したがって、バットからすぐに負の数が来ると期待してください。

他の値の0.3%については、数字の3/1000ということを忘れないでください。

有限のサポートで「ベル・カーベイ」分布を使用する場合は、beta distributionを試してみてください。

最後に、これが学問的な練習でない限り、numpy.random.normal()に相当する自分自身をロールする必要はありません。

+0

どのように私はそれを逃したのか分からない。私はちょうどその問題に焦点を当てていました、そして**非常に**有名なN(0,1) ':)のグラフィックを完全に忘れました。どうもありがとうございます! –

+0

私たちは皆小さな逃げ道を持っています。 ;)つまり、numpy.random.normal()を使用していない理由は何ですか? –

+0

OPは必ずNumPyを使用しているわけではありませんが、標準ライブラリはこれを 'random.gauss'(速いですがスレッドセーフではありません)または' random.normalvariate'として提供しています。つまり、与えられた方法は数値的に不安定になりがちです(単位平方でランダムな座標を選択し、重み付けされたランダムな半径とランダムな角度を選択するのではなく、単位平方の外にあればそれを拒否する方が良い)。有効な結果の半分を投げ捨てる( 'x1'は' x2'と同じくらい無作為で、独立しています;この値を覚えておいて、それを毎回返す方が良いでしょう。 –

0

ランダム生成値がゼロに非常に近い場合、Box-Muller変換に安定性の問題があります。 random.random()をガウス分布に置き換えて、平均と標準偏差に影響を与えることをお勧めします。

関連する問題