2011-04-25 469 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