随机游走 - 并行处理

时间:2014-06-18 17:03:45

标签: python parallel-processing montecarlo

我目前正在实施monte-carlo方法来解决扩散方程。该解可以表示为phi(W)的数学期望,其中phi是函数(相应于扩散方程而变化),W是在域的边界处停止的对称随机游动。为了评估x点的函数,我需要从x的期望开始每次行走。

我想在很多方面评估这个功能。所以这就是我的工作:

  1. 我从每个点开始同步一步
  2. 我对每个点使用相同的步骤
  3. 一旦每次行走到达边界,我就停止
  4. 我重复这些操作N次,以便通过N次模拟的频率来估计数学期望值。
  5. 我的代码(Python)如下所示:

    for k in range(N): #For each "walk"
        step = 0
        while not(every walk has reach the boundary):
            map(update_walk,points) #update the walk starting from each x in points
            incr(step)
    

    问题是:由于N可能很大而且点数也很长。我正在寻找可以帮助我优化此代码的任何解决方案。

    我已经考虑过使用IPython进行并行处理(每个步行是独立的)但是我没有成功,因为它在函数内部(它返回了一个错误,如

      

    "无法启动功能' f'因为没有找到' file.f' "但是' f'是在file.big_f中定义的

2 个答案:

答案 0 :(得分:1)

这是我可能不会使用并行计算的少数情况之一。我认为使用numpy会更快。

>>> import numpy as np
>>> def walk(x, n=100, box=.5, delta=.2):
...   np.random.seed()
...   w = np.cumsum(x + np.random.uniform(-delta,delta,n))
...   w = np.where(abs(w) > box)[0]
...   return w[0] if len(w) else n
... 
>>> pwalk = np.vectorize(walk)
>>> pwalk(np.zeros(10))
array([10,  25, 4,   5, 100,  6,  28,   6,  25,  23])

我认为你应该知道如何从那里获得期望值。

您也可以将元组传递给np.random.uniform的最后一个参数,然后不需要使用np.vectorize

当然,如果你想使用并行计算,那么你可以选择一个好的map函数,并从walk调用map而不是使用vectorize我上面做了。

>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> p = Pool(4)
>>> p.map(walk, [0]*10)
[8, 7, 39, 7, 36, 7, 22, 27, 18, 31]

使用pathos,因此可以从解释器轻松调用地图。 https://github.com/uqfoundation/pathos

答案 1 :(得分:0)

在单独的进程中启动计算(这是你想要的,以避免GIL)可能会使用多处理模块。可以使用以下代码启动X并行进程:

from multiprocessing import Process
from Queue import Queue
queue = Queue(maxsize=MAX_NODES) # this is the number of processes you will spawn
procs = [Process(target=f, args=(node, queue) for node in nodes] # node will be the node for each process , the queue is common to all of the processes
[p.start() for p in procs] # start them
results = []
for i in range(len(nodes):
    results.append(queue.get())

您需要做的就是修改func(目标函数)以获取相关数量的args和队列,并在计算结束时调用queue.put(result)

希望这是有道理的