2016-10-25 23 views
2

私はコードの最初に立ち往生しているので、私は本当に助けが必要です。Pythonの指数分布ランダムジェネレータ(ログ関数)?

ヒストグラムの指数分布を調べる関数を作成するように求められます。関数はx = -log(1-y)/λです。 λは定数であり、コード中のlamdrと呼ばれ、単純に10を与えた。私はN(乱数の数)10を与え、コードを実行したが、結果と生成された乱数はまったく異なる結果をもたらした。あなたはコードを見つけることができます、私は間違っていたか分からない、あなたが私を助けることができることを願って!あなたが提供されているコードを表示した後

import random 
import math 

N = raw_input('How many random numbers you request?: ') 
N = int(N) 
lamdr = raw_input('Enter a value:') 
lamdr = int(lamdr) 

def exprand(lamdr): 
    y = [] 
    for i in range(N): 
     y.append(random.uniform(0,1)) 
    return y 
y = exprand(lamdr) 
print 'Randomly generated numbers:', (y) 

x = [] 
for w in y: 
    x.append((math.log((1 - w)/lamdr)) * -1) 
print 'Results:', x 
+0

とは何ですか?あなたはそれを2回実行し、毎回異なる結果を得ることを意味しますか? –

+0

乱数と2つのリストが得られますが、これは与えられた式に依存しますが、一致しません。例えば、ランダムに生成されたy値のx値が完全に得られます – aleatha

+0

'lambdr'あなたの 'random.uniform()'のシード値を呼び出しますか?もしそうなら 'random.seed(lambdr)'で最初にシードする必要があります。次に、指定された 'lambdr'値に対して同じシーケンスの数字が得られます。上記の – eddiem

答えて

4

(私はPythonの2を使用する)あなたが必要な部分を持っていますが、それらを一緒に入れていないように、それが見えます。

指定された数式を使用して関数exprand(lambdr)を作成するように求められました。 Pythonはすでに指数関数を生成するためにrandom.expovariate(lambd)という関数を提供していますが、それでも何ができるのでしょうか?あなたの計算式には、0と1の間の一様分布を持つyの「ランダム」値が必要です。 The documentation for the random moduleは、random.random()が均一な(0,1)分布を与えることを示しています。

def exprand(lambdr): 
    return -math.log(1.0 - random.random())/lambdr 

歴史ノート:数学的には、yが均一(0,1)分布を持っているのであれば、私たちがしなければならないすべては、その関数の呼び出しを式でyを交換し、私たちが大切にしていますです、それで1-yもそうです。 1950年代のアルゴリズムの実装は、この事実を利用して計算を簡素化して-math.log(random.random())/lambdrにすることがよくあります。数学的には、これは連続的な確率変数Xと定数cについてP {X = c} = 0なので、分散的に正しい結果を与えるが、計算上は、から0を得る1の2のの出現のためにPythonで爆発する。これを行うための歴史的根拠の1つは、コンピュータが現在よりも数桁も遅い場合、追加の算術演算を省略することは、わずかなリスクしか負担しないと考えられていたことです。もう一つは、その時に普及していたPrime Modulus Multiplicative PRNGが決してゼロを生み出さないということでした。最近では、主に歴史的関心事であり、数学とコンピューティングが時々異なるところにあるという興味深い例です。

手元の問題に戻ってください。今度はその関数Nを呼び出して、結果をどこかに保存するだけです。これを行う可能性が高い候補は、ループまたはリストの理解です。後者の例があります:

abuncha_exponentials = [exprand(0.2) for _ in range(5)] 

これは、λ= 0.2の5つの指数のリストを作成します。 0.2と5を適切な値に置き換えてください。リストを印刷し、ヒストグラムを作成し、何か他のものへの入力としてそれを使用する...

はリスト内包でexpovariateexporandを交換すると、Pythonの組み込みの指数関数発生器を使用して同等の結果が得られるはずです。それは抽象化としての機能の美しさです。誰かがそれを書いたら、あなたの心のコンテンツに使うことができます。

乱数を使用するため、ランダムジェネレータを毎回同じ値に「シード」しない限り、実行するたびに異なる結果が得られることに注意してください。

2

@pjsが書いたものは、ある点に当てはまります。ステートメントmathematically, if y has a uniform(0,1) distribution, so does 1-yは正しいようですが、コードを-math.log(random.random())/lambdrに置き換えるという提案は間違っています。どうして?Python randomモジュールは、(0,1)の範囲で(hereのように)U(0,1)を提供するので、そのような置換は同等ではありません。あなたのU(0,1)が実際に[0,1)の範囲内の数値を生成している場合より、素人用語で

は、その後、コード

import random 
def exprand(lambda): 
    return -math.log(1.0 - random.random())/lambda 

は正しいのですが、コード

import random 
def exprand(lambda): 
    return -math.log(random.random())/lambda 

は間違っている、それlog(0)と呼ばれるようにNaN /例外を生成することがあります

+1

コメント編集は下位投票よりも適切な応答のように思えます。 – pjs

+0

@pjsええ、mea culpa。コメントのために大きすぎます... –

関連する問題