Как улучшить скорость моделирования броуновского движения Монте-Карло? - PullRequest
5 голосов
/ 16 марта 2019

Я хочу, чтобы мой код работал быстрее для большего количества итераций и запусков. Сейчас мой код слишком медленный, но я не знаю, что изменить, чтобы ускорить его. Я начал с кодирования кинетической симуляции Монте-Карло, а затем отредактировал ее, чтобы она стала броуновской симуляцией движения. Мой текущий код не может обработать 10 000 прогонов с 10 000 итераций в каждой, что необходимо.

import numpy as np
import matplotlib.pyplot as plt
import time
%matplotlib inline

runs = int(input("Enter number of runs: "))
N = int(input("Enter number of iterations per simulation: "))

y = 0
R = 10*1  # R is the rate value
t0 = time.time()
for y in range(runs):  # Run the simulation 'runs' times
    T = np.array([0])
    dt = 0
    x = 0.5  # sets values 
    X = np.array([x])
    t = 0
    i = 0

    while t < N:  # N is the number of iterations per run
        i = i + 1  # i is number of iterations so far
        z = np.random.uniform(-1, 1, 1)  # sets z to be a random number between -1 to 1 size 1

        if z > (1/3):  # if conditions for z for alpha and gamma, beta 
            x = x + 1  # z[]=alpha state then + 1
        elif z < (-1/3):
            x = x-1  # z[]=gamma state then - 1
        elif z < (1/3) and z > (-1/3):
            x = x  # z=beta state then + 0

        X = np.append(X, x)  # adds new X value to original X array
        X[i] += X[i-1] * 0.01 * np.random.normal(0, 1, 1) * np.sqrt(dt)  # for Brownian motion with sigma as 0.01
        Z = np.random.uniform(0, 1)  # sets Z to be a random number between 0 and 1
        dt = 1/R * np.log(1/Z)  # formula for dt; R is the rate value
        t = t + dt  # ITERATED TIME
        T = np.append(T, t)
        plt.plot(T, X, lw='0.5', alpha=0.5)

t1 = time.time()
print("final %.10f seconds " % (t1-t0))

1 Ответ

1 голос
/ 16 марта 2019

Вот превосходный пример быстродействующего броуновского движения Монте-Карло, менее затратного в вычислительном отношении.

В прошлом я делал то же самое, что и вы, изаставил каждый шаг каждой итерации иметь место во вложенных циклах.Возможно, это стоимость переключения контекста, запуска через разные библиотеки или просто нехватки памяти, но выполнение каждого шага кода в каждой итерации определенно приводило к снижению производительности и увеличению использования памяти.

В приведенном выше примере автор сначала создает массивы и , а затем перебирает их соответственно с помощью одного цикла for.Все случайные числа генерируются и помещаются в массив одновременно.Затем все возвраты броуновского движения рассчитываются одновременно.и т. д. (Подумайте о сборочной линии - очень хорошо используя ресурсы на каждом этапе и достигая экономии за счет масштаба.) Также важно отметить, что функция plt запускается только один раз (не внутри цикла) и только после того, как все итерацииполный.

Этот метод должен предусматривать гораздо большее количество итераций на гораздо меньшем оборудовании.

...