В исчислении Ито метод Эйлера –Маруямы (также называемый просто методом Эйлера ) — это метод приближенного численного решения стохастического дифференциального уравнения (СДУ). Он является расширением метода Эйлера для обыкновенных дифференциальных уравнений до стохастических дифференциальных уравнений, названных в честь Леонарда Эйлера и Гисиро Маруямы . Такое же обобщение невозможно сделать для любого произвольного детерминированного метода. [1]
Рассмотрим стохастическое дифференциальное уравнение (см. исчисление Ито )
с начальным условием X 0 = x 0 , где W t обозначает винеровский процесс , и предположим, что мы хотим решить это СДУ на некотором интервале времени [0, T ]. Тогда приближение Эйлера–Маруямы к истинному решению X представляет собой цепь Маркова Y , определяемую следующим образом:
Случайные величины Δ W n являются независимыми и одинаково распределенными нормальными случайными величинами с ожидаемым значением нулевым и дисперсией Δ t .
Область, которая значительно выиграла от SDE, — это математическая биология . Поскольку многие биологические процессы являются как стохастическими, так и непрерывными по своей природе, численные методы решения SDE весьма ценны в этой области.
На графике изображено стохастическое дифференциальное уравнение, решенное с использованием метода Эйлера-Маруямы. Детерминированный аналог показан синим цветом.
Следующий код Python реализует метод Эйлера–Маруямы и использует его для решения процесса Орнштейна–Уленбека, определяемого формулой
Случайные числа генерируются с помощью математического пакета NumPy .
# -*- кодировка: utf-8 -*-импортировать numpy как npимпортировать matplotlib.pyplot как plt Модель класса : """Константы стохастической модели.""" ТЕТА = 0,7 МЕ = 1,5 СИГМА = 0,06def mu ( y : float , _t : float ) -> float : """Реализовать мю Орнштейна-Уленбека.""" Модель возврата . THETA * ( Модель . MU - y )def sigma ( _y : float , _t : float ) -> float : """Внедрить сигму Орнштейна-Уленбека.""" Модель возврата . SIGMAdef dW ( delta_t : float ) -> float : """Выбор случайного числа при каждом вызове.""" вернуть np.random.normal ( loc = 0.0 , scale = np.sqrt ( delta_t ) ) определение run_simulation (): """ Верните результат одной полной симуляции.""" Т_ИНИТ = 3 Т_КОНЕЦ = 7 N = 1000 # Вычислить в 1000 точках сетки DT = float ( T_END - T_INIT ) / N TS = np.arange ( T_INIT , T_END + DT , DT ) утверждение TS . размер == N + 1 Y_INIT = 0 ys = np . нули ( TS . размер ) ys [ 0 ] = Y_INIT для i в диапазоне ( 1 , TS . size ): t = T_INIT + ( i - 1 ) * DT у = ys [ i - 1 ] ys [ i ] = y + mu ( y , t ) * DT + sigma ( y , t ) * dW ( DT ) возврат TS , ггdef plot_simulations ( num_sims : int ): """ Построить несколько симуляций на одном изображении.""" для _ в диапазоне ( num_sims ): plt . plot ( * run_simulation ()) plt.xlabel ( " время " ) plt.ylabel ( " y " ) plt . показать ()если __name__ == "__main__" : NUM_SIMS = 5 plot_simulations ( NUM_SIMS )
Ниже приведен простой перевод приведенного выше кода на язык программирования MATLAB (R2019b) :
%% Инициализация и утилитазакрыть все ; очистить все ; numSims = 5 ; % отобразить пять запусков tBounds = [ 3 7 ]; % Границы t N = 1000 ; % Вычислить в 1000 точках сетки dt = ( tГраницы ( 2 ) - tГраницы ( 1 )) / N ; y_init = 0 ; % Начальное состояние y % Инициализируем распределение вероятностей для нашего% случайная величина со средним значением 0 и стандартным отклонением sqrt(dt)pd = makedist ( 'Нормальный' , 0 , sqrt ( dt )); c = [ 0,7 , 1,5 , 0,06 ]; % Тета, Мю и Сигма соответственно ts = linspace ( tBounds ( 1 ), tBounds ( 2 ), N ); % От t0-->t1 с N точками ys = нули ( 1 , N ); % 1xN Матрица нулей ys ( 1 ) = y_init ; %% Вычисление процессадля j = 1 : numSims для i = 2 : число ( ts ) t = tГраницы ( 1 ) + ( i - 1 ) .* dt ; у = ys ( i - 1 ); мю = с ( 1 ) .* ( с ( 2 ) - у ); сигма = с ( 3 ); dW = случайный ( pd ); ys ( i ) = y + mu .* dt + сигма .* dW ; конец фигура ; подожди ; участок ( ts , ys , 'o' ) конец