Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Стохастический_мир.pdf
Скачиваний:
112
Добавлен:
16.03.2016
Размер:
2.96 Mб
Скачать

250

Глава 9.

9.4Моделирование стохастических процессов

Рассмотрим алгоритм моделирования одномерного стохастического процесса:

dx = a(x; t)dt + b(x; t) W:

Если задано начальное условие x0 = x(0), то последующие значения процесса xk = x(tk) получаются при помощи итерационной схемы (стр.

49): p

xk+1 = xk + a(xk; tk) t + b(xk; tk) t "k:

Чем меньше временной шаг t, тем ближе будут свойства получаемого выборочного процесса к точному результату:

# include " stat . cpp "

// ôàéë ñ RndG ( )

inline Float a( Float x , Float t ){ return 0; } // ñíîñ inline Float b( Float x , Float t ){ return x; } // волат .

void main ()

{

FILE * out = fopen (" ito . out " , "w" );

SRnd ( time (0));

// " встряхиваем " генератор

Float

step

=

0.1;

// шаг по времени для табуляции x

const

int

num

= 100; //

число точек табуляции

int lag =

1000;

//

количество дроблений шага s t e p

Float dt = step /lag ,

sqrt_dt = sqrt ( dt );

Float

x =1;

 

 

// начальное значение x

Float

t =0;

 

 

// в момент времени t

fprintf (out , "%g\t%g\n" , t , x );

for ( int k =1;

k <= num ; k ++){

for ( int

j =0; j < lag ;

j++ , t += dt )

x+= a(x ,t )* dt + b(x ,t )* RndG ()* sqrt_dt ;

fprintf (out , "%g\t%g\n" , t , x ); fflush ( out );

}

 

fclose ( out );

// закрываем файл

}

 

Разбер¼м этот код. Директивой include мы вставляем код из файлаstat.cpp , в котором содержится функция RndG, описанная в предыдущем разделе. Так как это наш файл и он находится в той же директории, где происходит компиляция основной программы, мы заключаем его имя в двойные кавычки.

Компьютерное моделирование

251

Далее идут описания функций сноса и волатильности. В примере выше выбран процесс логарифмического блуждания с нулевым сносом и единичной волатильностью (стр. 58).

Âглавной функции main открывается файл с именем ito.out . В него будут помещаться результаты работы программы. Для этого объявляется переменная (указатель) out типа FILE, значение которой зада¼тся функцией fopen. Последний е¼ аргумент w определяет способ открытия файла. В данном случае это будет вновь создаваемый файл, открывающийся для записи.

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

Âпрограмме вычисляется num = 100 значений случайного процес-

са x(t), с равным шагом по времени: t = 0; step; 2 step; :::; num step. Каждый интервал между вычисляемыми значениями x разбивается на большое число lag точек, время между которыми равно dt = step=lag.

x

 

x

x0

x0

t

t

 

step

 

step

Для вычислений используется два вложенных цикла. Внешний по k приводит к выводу x(step), x(2step),... тогда как внутренний по j, при помощи итерационной формулы, вычисляет промежуточные значения случай-

ного процесса. Для ускоренияpвычислений мы используем переменную sqrt_dt, в которой хранится dt. Начальное значение процесса x0 = 1

в момент времени t0 = 0 зада¼тся перед выполнением циклов.

Вывод в файл осуществляется функцией fprintf, которая аналогич- на printf, но первым аргументом указывается файловая переменная, в которую направляется вывод. Функция fflush(out) приводит к немедленному помещению данных в файл, поэтому, если прервать выполнение программы, часть посчитанных к этому моменту результатов будет находиться в файле. Последняя строка закрывает файл. Этот текстовый файл можно открыть, например, в Excel и построить график соответствущего случайного процесса.

Символ \t в функции fprintf обозначает табулирование и понимается Excel в качестве разделителя колонок. Можно его заменить на запятую , , и, придав файлу расширение .csv , получить формат, воспринимаемый большинством программ обработки данных.

252 Глава 9.

Аналогичным образом моделируется система стохастических уравнений. Рассмотрим в качестве примера двухмерный осциллятор с зату-

ханием (стр. 160), имеющий скоррелированный шум Wx Wy = dt:

dx = ( x ! y) dt + Wx dy = (+! x y) dt + Wy:

Программа на C++, выдающая реализацию траектории соответствущего случайного процесса x(t); y(t), имеет вид:

# include " stat . cpp "

// ôàéë ñ RndG ( )

void main ()

{

FILE * out = fopen (" ito . out " , "w" );

SRnd ( time (0));

// " встряхиваем " генератор

Float

step = 0.1;

// шаг по времени для табуляции x , y

const

int

num = 1000; //

число точек табуляцмм

int lag =

1000;

//

количество дроблений шага s t e p

Float w =0.5 , lm =0.01 , si =1 , rho =0.1;

Float x=1 , y=0 , t=0 , x1 , y1 , r1 , r2 ;

Float dt = step /lag , sqrt_dt = sqrt ( dt ),

rho1 = sqrt (1 - rho * rho );

fprintf (out , "%g\t%g\t%g\n" , t , x , y );

 

for ( int k =1;

k <= num ; k ++){

 

 

 

for ( int j =0;

 

j < lag ; j++ , t += dt ){

 

 

r1 = RndG (); r2 = rho * r1 + rho1 * RndG ();

 

x1

=

x

+

(- lm *x -w*y )* dt

+

si * r1

* sqrt_dt ;

y1

=

y

+

(- lm *y+w*x )* dt

+

si * r2

* sqrt_dt ;

x= x1 ; y= y1 ;

 

 

 

}

 

 

 

 

 

 

 

fprintf (out ,

 

"%g\t%g\t%g\n" ,

t ,

x , y );

}

 

 

 

 

 

 

 

fclose ( out );

 

 

//

закрываем файл

}

Принципиальное отличие от одномерного случая состоит в использовании промежуточных переменных x1 и y1. Мы должны сначала вычислить приращение каждой из переменных, и лишь затем их увеличить. Если бы это не было проделано, то во втором уравнении для y стояло

бы x не из предыдущей итерации, а уже измен¼нное. В качестве упраж-

нения стоит сравнить работу этого алгоритма и алгоритма, в котором стояло бы просто x+ = ::: и y+ = :::. Обратим также внимание на ге-

нерацию скоррелированных случайных чисел r1 и r2 с коэффициентом корреляции =rho.

Компьютерное моделирование

253

Пока системы уравнений имеют небольшую размерность, для каж-

дой степени свободы вводится отдельная переменная. Однако, рано или поздно необходимо переходить к массивам, особенно, если уравнение имеет компактную векторную форму.

Рассмотрим, например, систему следующего вида:

dxi = xi r dt + Wi;

p

ãäå r = x21 + ::: + x2n расстояние до начала координат в n-мерном декартовом пространстве. Так как снос вектора x = fx1; :::; xng всегда направлен к началу координат, блуждание будет вс¼ время оставаться в его окрестности. Со временем установится стационарное распределение вероятностей.

Для моделирования подобных уравнений необходимо определить массивы значений на предыдущей и текущей итерациях, а также задать начальные значения:

const int n = 10; Float x[n], x1 [n ];

for ( int i =0; i <n; i ++) x[i ]=0;

Для объявления размера статических массивов необходимо использовать константы (const). В качестве начального значения выбрано начало координат.

Основной цикл итерационных расч¼тов имеет следующий вид:

for ( int k =1; k <= num ; k ++){ for ( int j =0; j < lag ; j ++){

Float r =0;

 

for ( int

i =0; i <n;

i ++) r += x[i ]* x[i ];

r= sqrt (r );

 

for ( int i =0; i <n; i ++)

x1 [i]

= x[i] -

x[i ]* r* dt + RndG ()* sqrt_dt ;

for ( int

i =0; i <n; i ++)

x[i]

= x1 [i ];

 

}

}

При помощи значений x[i], полученных на предыдущей итерации, вычисляется радиус-вектор r. Затем в цикле происходит определение новых значений координат, которые присваиваются в массив x1. Только после того, как все новые значения вычислены, они снова помещаются в массив решений x.