2011-04-25 118 views
2

GBM的基本模擬似乎不起作用。我究竟做錯了什麼?下面的代碼始終輸出值小於1E-20,而不是什麼1.0左右隨機分佈:基於Python的 python:幾何布朗運動模擬

的ActivePython 3.1.2.3(ActiveState的軟件公司):

import math 
import random 

p = 1 
dt = 1 
mu = 0 
sigma = 1 
for k in range(100): 
    p *= math.exp((mu - sigma * sigma/2) * dt + 
     sigma * random.normalvariate(0, dt * dt)) 
print(p) 

我跑3.1.2(r312:79147,Mar 22 2010,12:30:45)[MSC v.1500 64 bit(AMD64)] on win32

我的操作系統是i7-930 CPU上的Windows 7 Professional(64-位)。

我很樂意在我的機器上運行任何其他測試來找出問題。

+0

你正在運行什麼Python版本?一些機器信息會很有用。 – Blender 2011-04-25 01:40:08

回答

3

我找到了答案。代碼沒有問題。只是由此產生的對數正態分佈具有巨大的尺度參數= 1 * sqrt(100)= 10。在10的尺度下,偏度是瘋狂的。

因此,即使分佈的均值爲1。0,它會花費我數十億次迭代(如果不是億十億)看到一個單一的數字大於1.0。

0

似乎罰款:

import math 
import random 

def compute(): 
    p = 1 
    dt = 1 
    mu = 0 
    sigma = 1 
    for k in range(100): 
     p *= math.exp((mu - sigma * sigma/2) * dt + 
         sigma * random.normalvariate(0, dt * dt)) 
    return p 

print [compute() for x in range(20)] 

給出:

[118.85952235362008, 7.3312246638859059e-14, 29.509674994408684, 1.8720575806397408, 1.5882398997219834e-05, 2967.524471541024, 0.0031130343677571093, 19942.669293314699, 0.00011878818261757498, 5382.80288111769, 0.22867624175360118, 0.028535167622775418, 12.6324011631628, 20.604456159054738, 0.0034504567371058613, 6.5804828930878056e-06, 6398.0493448486704, 0.0014978345496292245, 721546.38343724841, 1285.546939393781] 

這是使用Python 2.6.1

+0

格式揭掉代碼,請... – Blender 2011-04-25 01:39:52

+0

在x64上使用的ActiveState的Python 3.1.2.3 Windows 7中,我越來越:2.88084588316e-26 1.79846330571e-29 5.33216495039e-16 3.65633773649e-24 1.4585366594e-20 5.89100557394e-29 6.54803262332e-22 6.4358184422e-26 5.84172579131e-16 1.54534837363e-20 1.80941931541e-21 1.1932380739e-19 2.05849658827e-19 2.72778662212e-26 5.76789574386e-11 1.28691566317e-20 2.0417208905e-17 1.0618463823 8e-28 8.75599425267e-26 9.76030276598e-24 – max 2011-04-25 01:58:33

0

運行在Python代碼2.6.6得到合理的答案,而在運行它Python 3.1.2提供了你描述的小數字。我認爲這是因爲在Python 2.x中,劃分運算符在分割兩個整數時給出了整數結果,而在Python 3.x中,它給出了相同情況下的浮點結果。因此,根據版本的不同,計算中的除以2會得到不同的結果。

爲了使其一致,分工的強制輸出整數:

p *= math.exp(int(mu - sigma * sigma/2)) * dt + 
    sigma * random.normalvariate(0, dt * dt)) 

這使得輸出兩個2.x和3.x的相同我的機器上設置輸出的一個例子是:

0.0243898032782,6126.78299771,0.00450839758621,1.17316856812,0.00479489258202,4.88995369021e-06,0.033957530608,29.9492464423,3.16953460691

這似乎是在球場你在找什麼對於。

+0

但是我的sigma是1.所以'sigma * sigma/2'將在Python 2.6中等於'0'。這當然不是我想要的。我遵循標準的GBM公式,我需要使用float division來複制它。 – max 2011-04-25 02:04:36

0

在Python使用浮動分裂(//),而不是整數除法(/)3.1作品:

import math 
import random 

p = 1 
dt = 1 
mu = 0 
sigma = 1 
for k in range(100): 
    p *= math.exp((mu - sigma * sigma // 2) * dt + 
     sigma * random.normalvariate(0, dt * dt)) 
print(p) 

上的示例來看,我得到了以下數字:

0.0989269233704
2536660.91466
2146.09989782
0.502233504924
0.43052439984
14.1156450335

+1

//是整數除法,不是浮點數。我其實需要漂浮... – max 2011-04-25 22:47:34