Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Методы Монте-Карло для параллельных вычислений. Учебное пособие
.pdf
Пусть теперь e = 2 и каждый Xnзанимает два двоичных разряда.
Легко увидеть, что младший разряд по-прежнему описывается соотношением (2.5) с e = 1 и, следовательно, имеет максимальный период
2j− 1. В то же время, эволюция старшего разряда есть суперпозиция
двух процессов: а) сложение старших разрядов, порождающее последовательность вида (2.5) с e = 1 и максимальным периодом 2j− 1, и
б ) последовательность переносов, образующихся при сложении младших разрядов. Пусть X
0
= 1, X
0
0
= 0, n < j. Такая последовательность
n
моделирует появления 1 при переносе в результате сложения «в момент
времени 0». Тогда и при n > j единица будет снова появляться среди
значений X
0
и образовывать последовательность с периодом 2j−1. По-
n
этому при достаточно больших n значение старшего разряда Xnесть
сумма старших разрядов X
n−i
и X
и набегающих волн от ранее вы-
n−j
полненных переносов. Если за счет переносов добавляется четное число
единиц, то по модулю 2 фактически прибавляется 0. Поэтому при e = 2
слагаемые за счет переносов будут образовывать последовательность
периода 2 × (2j− 1). Другими словами, происходит удвоение периода.
Понятно, что и последовательность {Xn; n = 0, 1, . . .} будет иметь
период 2(2j− 1).
В общем случае максимальный период для рекуррентного соотношения (2.5) равен 2
e−1(2j
− 1). Известны несколько наборов чисел
(i, j), i < j, для которых последовательность, порождаемая соотношением (2.5), имеет максимальный период: (24, 55), (37, 100), (83, 258),
(273, 607), (9739, 23209) (см. [47]). Из предыдущего рассмотрения вид-
но, что важную роль в удвоении периода играют ненулевые младшие
биты. Поэтому условие на выбор начальных значений для генератора,
при которых достигается максимальная длина периода, состоит в наличии нечетных чисел среди них.
2.5. Векторный обобщенный генератор Фибоначчи с
запаздыванием
Рассмотрим два метода реализации обобщенного генератора Фибоначчи с запаздыванием с использованием векторных операций. В Алгоритме IV одновременно порождаются k обобщенных последовательностей Фибоначчи с запаздыванием. Реализация этого алгоритма не должна вызывать затруднений по аналогии с Алгоритмом I из раздела 2.3.
31

Первый векторный обобщенный генератор Фибоначчи с
Пусть заданы векторы
X0= (X
0
(2)
, X
0
. . . , X
, . . . , X
k−1
(k)
0
(1)
Последовательно определяем
Алгоритм IV
запаздыванием
), X1= (X
= (X
(1)
k−1
, X
(2)
k−1
(1)
, X
1
1
, . . . , X
(2)
, . . . , X
(k)
k−1
(k)
), . . .
1
).
Xn= X
n−i
◦ X
, n > max{i, j}.
n−j
Рассмотрим генератор, задаваемый соотношением
Xn= X
n−607
− X
n−273
mod 231, n > 607.
Пусть допускаются векторные операции над векторами длины k = 4.
Как было замечено выше, можно перейти к арифметике вещественных
чисел:
Un= {U
n−607
− U
}, n > 607, (2.6)
n−273
где {·} обозначает дробную долю числа, и Un∈ (0, 1) для всех n. То-
гда рекуррентное соотношение (2.6) может применяться параллельно и
поэлементно к векторам
U0= (U
U00= (U
с целью получения вектора U = (Un, U
n−607
n−273
, U
, U
n−606
n−272
, U
, U
n−605
n−271
n+1
, U
, U
, U
n+2
n−604
n−270
, U
),
).
). Заметим, что
n+3
152 · 4 = 608 > 607. Мы будем поддерживать массив из (152 + 1) ×
×4 = 612 чисел с плавающей точкой одинарной точности, который для
наглядности удобно представить в виде таблицы:
U1U5U9. . . U
U2U6U
U3U7U
U4U8U
10
11
12
. . . U
. . . U
. . . U
605U609
606U610
607U611
608U612
32

Столбцы таблицы будут интерпретироваться как четырехкомпонентные
векторы. Сам массив будет использоваться как кольцевой буфер.
Алгоритм V
Второй векторный обобщенный генератор Фибоначчи с запаздыванием
Шаг 1. Заполнить массив чисел U1, U2, . . . , U
, произвольным
608
образом. Например, первые 607 чисел заполняются с помощью линейного конгруэнтного генератора. Величины с U
608
по U
— по скалярной
612
версии генератора Фибоначчи с запаздыванием.
Шаг 2. Скопировать последнюю колонку чисел на место первой
колонки.
Шаг 3. Выбрать в качестве U0отрезок массива с U5по U8, а в
качестве U00— отрезок массива с U
339
по U
. Вычислить U и запи-
342
сать результат во второй столбец. Выбрать в качестве векторов U0и U
новые отрезки на 4 позиции правее. Если какой-то из отрезков, используемый для выбора значений U0или U00должен начаться в последнем,
153-м столбце, то участок для выбора сдвигается на 608 позиций влево, на первый столбец. Затем продолжается движение этого участка
вправо. Так заполняются все столбцы со второго по 153-й. После этого
возвращаемся к шагу 2.
Реализация алгоритма V приведена в следующей программе.
Программа 2.2. Генератор Фибоначчи с запаздыванием для соотношения Un=
= {U
1 t ypede f fl o a t v4sf _ _at t r i but e _ _
2 (( v ect o r _ siz e (1 6))) ;
3 c l a ss l f r n g {
4 float s e e d [612] ;
5 in t lo c ;
6 lfrng ();
7 void g e nera t e ( ) ;
8 p u blic :
9 lfrng ( i nt _s e e d );
10 float n e x t ( ) ;
11 };
12
13 i n line v 4sf s u b m od ( v4 s f x , v4sf y ) {
14 v4sf z ;
n−607
− U
n−273
}
00
33

15 z = x - y ;
16 z + = __ bui l t in _ i a 32 _ a n dp s (
17 _ _ b u il t i n_i a 3 2_ c m p lt p s ( z ,( v4sf ){0 . , 0 . , 0 . , 0 .}) ,
18 (v4sf ) { 1 . , 1 . , 1 . , 1 . } ) ;
19 retur n z ;
20 }
21
22 f l o at l f r n g : : n e x t ( ){
23 float a n s ;
24 an s = s e e d [ l o c ] ;
25 lo c + + ;
26 if ( loc > 6 0 7 ) gen e r a t e ();
27 retur n an s ;
28 };
29
30 l f r ng : : l f r n g ( int _ s e e d ) {
31 float i n t p ;
32 fo r ( in t i=0; i < 6 0 7; i ++){
33 _ s e e d = _ s e e d *165 3 5 & 0 x 7 f f ffff f ;
34 se e d [i ] = ( _ s e e d + 1.0) / ( ( f l oat )0 x 8 000 0 0 0 0 ) ;
35 };
36 fo r ( in t i=607; i <6 1 2 ; i + + ) {
37 f l o a t t= seed [i - 6 0 7 ] - s e e d [i -273 ] ;
38 if (t <0) se ed [ i ] = 1 . 0 + t ; else s e e d [ i ]= t ;
39 };
40 lo c = 6 0 7;
41 };
42
43 v o i d lfrng :: g ener a t e ( ) {
44 short i , j , k ;
45 *( v 4 s f *) seed = *( v4sf *)( seed +608) ;
46 i=5;
47 j=339 ;
48 fo r ( k =1; k <153; k ++){
49 *( v4sf *) ( s e e d + 4 * k ) = su b m o d (
50 __ b u i lt i n _ ia 3 2 _lo a d up s ( s e ed + i ),
51 __ b u i lt i n _ ia 3 2 _lo a d up s ( s e ed + j ));
52 i + = 4 ; if (i > 607) i -=60 8 ;
53 j + = 4 ; if (j > 607) j -=60 8 ;
54 }
55 lo c = 0 ;
56 };
34

По заданному начальному значению U0= X0/m вычисляются
первые 607 значений по методу мультипликативного конгруэнтного генератора (строки 32–34). Затем следующие четыре значения вычисляются по рекуррентной формуле (2.6) (строки 36–38). Строки 45–54
реализуют основной ход алгоритма. Отметим некоторые особенности:
1) действие функции submod эквивалентно следующему последовательному циклу (см. объяснения в разделе 8.11)
1 f o r ( i =0; i < 4 ; i ++){
2 t = x [ i ]- y [ i ] ;
3 if (t <0 ) z[ i ]= t + 1 . 0 ; el s e z[ i ] = t;
4 };
2) осторожное обращение с памятью требуется при выборке векторов
в строках 49–51, а именно — размещение необходимых элементов четырехмерных векторов в памяти не обязано быть выровнено, и более
простая запись submod(*(v4sf*)(seed+i), *(v4sf*)(seed+i)) порождает ошибку обращения к памяти.
На рис. 2.3 приведен график точек (Un, U
), n = 1, 2, . . . ,
n+1
100. Для данных точек максимальная абсолютная величина D разно-
сти между функцией распределения равномерного закона и выборочной
функцией распределения
ˆ
F (x) = 0,01 · N({n: Un< x, n = 1, 2, . . . , 100})
оказалась равной 0,0804. Очевидно, против гипотезы согласия значений U1, U2, .. . , U
с равномерным законом распределения должны
100
свидетельствовать большие значения меры расхождения D. Можно вычислить [11, 22], что для выборки объема 100 из равномерного закона
распределения на интервале (0, 1) вероятность встретить D > 0,0804
приближенно равна 0,5377. Поскольку мы пронаблюдали событие с высокой вероятностью, гипотезу о согласии с равномерным распределением следует принять.
2.6. Методы перетасовывания и комбинации
Пусть псевдослучайные последовательности U = {U0, U1, . . . }
и V = {V0, V1, . . . } со значениями в [0, 1) порождаются различны-
ми алгоритмами. Приводимый ниже алгоритм VI использует одну из
них, чтобы перетасовать члены другой последовательности, разрывая
35

0.0 0.2 0.4 0.6 0.8 1.0
0.0 0.2 0.4 0.6 0.8 1.0
Рис. 2.3. Совместное распределение точек (Un, U
= {U
n−607
− U
n−273
}
) для генератора Un=
n+1
таким образом возможные зависимости между членами этого ряда. Алгоритм VII предназначен для перестановки членов одной последовательности U = {U0, U1, . . . }.
Другим популярным способом получения псевдослучайных последовательностей является комбинация нескольких последовательностей в одну. Рассмотрим две целочисленные псевдослучайные последовательности {X0, X1, . . . } и {Y0, Y1, . . . } со значениями в {0, 1, . . .
. . . , m − 1}. Определим комбинацию этих последовательностей посред-
ством соотношения
Zn= Xn◦ Ynmod m, n = 0, 1, . . .
Например, для псевдослучайных последовательностей U = {U0, U1, . . . }
и V = {V0, V1, . . . } чисел из интервала (0, 1) можно положить
Wn= {Un+ Vn}, n = 0, 1, . . . .
Комбинация двух псевдослучайных последовательностей может
быть реализована на векторном компьютере с использованием функции
36

submod из Программы 2.2. Дополнительная вычислительная эффективность может быть достигнута путем включения кода, генерирующего
последовательности U и V .
Алгоритм VI
Алгоритм перетасовывания для двух псевдослучайных
последовательностей
Шаг 0. Выберем натуральное K и введем вспомогательные переменные
A0, A1, . . . , A
Шаг 1. Положим A0= U0, A1= U1, . . . , A
K−1
.
K−1
= U
K−1
.
Шаг 2. Пусть u и v — следующие числа в последовательностях U и V .
Положим j = [Kv] — целая часть от произведения Kv.
Шаг 3. Выдаем следующее число последовательности, Aj; присваиваем
Aj= u. Возвращаемся к шагу 2.
Алгоритм VII
Алгоритм перетасовывания для одной последовательности
Выберем натуральное K и введем вспомогательные переменные A0, A1,
. . . , A
Шаг 1. Положим A0= U0, A1= U1, . . . , A
K−1
.
K−1
= U
K−1
.
Шаг 2. Выберем следующий член u последовательности U. Положим
j = [Ku].
Шаг 3. Возвращаем Aj; присваиваем Aj= u. Переходим к шагу 2.
2.7. «Вихрь Мерсенна»
Следующий генератор псевдослучайных чисел обладает некоторыми важными статистическими свойствами. Пусть w — число двоичных разрядов в машинном слове. Рассмотрим двоичное представление целого бизонового числа 0 6 X < 2wкак массив из w бит:
X = (X
(w−1)X(w−2)
. . . X
(0)
)2. Обозначим X
[k:l]
подвектор (X
(l)
. . . X
(k)
37
)

вектора U . В основе генератора лежит рекуррентное соотношение
X
k+n
= X
k+m
⊕ (X
(r:w−1)
k
|X
(0:r−1)
) ⊗A, k = 0, 1, . . . ,
k+1
где 1 6 m 6 n и 0 6 r 6 w − 1 — целочисленные параметры, ⊕ обозначает сложение векторов по модулю 2, вертикальная черта означает
конкатенацию двух векторов, A — матрица размера w ×w с элементами
0 и 1, ⊗ — умножение матриц по модулю два. Начальные значения X0,
X1, . . . , X
выбираются произвольно. В рассматриваемом алгоритме
n−1
матрица A имеет вид
A =
0 1 0 . . . 0
0 0 1 . . . 0
.
.
.
0 0 0 . . . 1
a
w−1aw−2aw−3
.
.
.
.
.
.
.
. . . a
.
.
. . .
,
0
так что вычисление произведения X ⊗ A может быть выполнено только с использованием побитовых операций сдвига вправо (shiftright) и
сложения по модулю два: при X
(0)
= 0 имеем
X ⊗ A = shiftright(X),
(0)
при X
= 1 имеем
X ⊗ A = shiftright(X) ⊕(a
w−1aw−2
. . . a0)2.
Операции вычисления подвектора и конкатенации векторов легко реализуются с помощью операций «логическое И» (and) и «логическое
ИЛИ» (or). Далее операции ⊕ соответствует «логическое исключающее
ИЛИ». Таким образом, расчет по рекуррентной формуле производится
только с использованием основных логических и побитовых операций.
Кроме того, оказывается полезным вместо X
вычислять X
n+k
0
n+k
по
формулам:
Y0= X
n+k
⊕ (X
n+k
u),
Y00= Y0⊕ ((Y0 s) B),
000
Y
= Y00⊕ ((Y00 t) and C),
X
0
n+k
= Y
000
⊕ (Y
000
l),
38

где l, s, t и u — целые числа, B, C — двоичные массивы длины w,
операция X u означает сдвиг массива X вправо на u мест, операция
X u — влево на u мест.
В теории генератора «Вихрь Мерсенна» доказывается, что максимальный период генератора равен 2nr−1. Широко применяется вариант
вихря Мерсенна MT19937 при значении параметров w = 32, n = 624,
m = 397, r = 31, u = 11, s = 7, t = 15, l = 18,
(a31a30. . . a0) = (10011001000010001011000011011111)2,
B = (10011101001011000101011010000000)2,
C = (11101111110001100000000000000000)2.
Период этого генератора весьма велик: 2
19968
− 1 ≈ 9,267 × 10
6010
.
2.8. Методы получения псевдослучайных
последовательностей с равномерным распределением для
параллельных вычислений
Для решения многих задач приходится находить оценку математического ожидания M X случайной величины X на основании достаточно большой выборки ее значений x1, x2, . . . , xN. Предполагается, что
выборочные значения являются независимыми в вероятностном смысле. Часто для получения одного значения xiвеличины X используется
несколько псевдослучайных чисел из последовательности U1, U2, . . . .
Если мы желаем распределить получение выборочных значений x1, x2,
. . . , xNмежду несколькими вычислительными процессами, мы должны
по-прежнему обеспечить независимость величин x1, x2, . . . , xN. Необходимым условием для этого является использование различных частей
последовательности U1, U2, .. . или даже различных последовательностей U
1
, U
0
, .. . , U
2
00
00
, U
, .. . разными вычислительными процессами.
1
2
0
В этом случае говорят, что необходимо получить достаточное число
независимых потоков псевдослучайных чисел. Предположим, что для
получения выборки значений x1, x2, . . . , xNиспользуются перекрываю-
щиеся участки последовательности U1, U2, . . . . Тогда можно указать по
меньшей мере два отрицательных следствия. Во-первых, работа разных
вычислительных процессов над одним потоком данных даст идентичные результаты, и поэтому использование более одного вычислительного процесса для воспроизведения известного результата является непро-
39

изводительной растратой вычислительных ресурсов. Во-вторых, наличие одинаковых выборочных значений может быть ложно интерпретировано как наличие малой дисперсии величины X и, как следствие,
точность полученного результата окажется завышенной.
Рассмотрим некоторые приемы получения независимых потоков
псевдослучайных чисел.
Метод непересекающихся отрезков. Предположим, что заранее
известно количество N псевдослучайных чисел, необходимое для работы одного вычислительного процесса. Пусть далее предполагаемое число процессов L и период генератора d удовлетворяют условию L·N 6 d.
Тогда можно разбить период U1, U2, .. . , Udна непересекающиеся от-
резки
(U1, U2, . . . , UN), (U
N+1
, U
, . . . , U2N), . . .
N+2
или
(U1, U2, . . . , UN), (U
[d/L+1]
, U
[d/LN+2]
, . . . , U
[d/L]+N
), . . .
Основная трудность в реализации этого приема заключается в быстром
переходе к значениям U
N+1
, U
, . . . без вычисления промежуточных
2N+1
значений. Для некоторых генераторов существуют более-менее эффективные приемы. Например, пусть исходным является мультипликативный конгруэнтный генератор из раздела 2.2. Тогда
U
= aNU1mod m, U
N+1
2N+1
= aNU
mod m, . . . .
N+1
Известно, что возведение в целую степень N можно выполнить за число
операций порядка O(log N ). Например, функция intpow, представленная в Программе 2.3, реализует бинарный метод возведения в степень.
Этот метод основан на тождестве
(
N/2)2
aN=
(a
(N−1)/2)2
a(a
при четном N,
при нечетном N.
Существуют и другие методы быстрого возведения в целую степень.
Программа 2.3. Функция быстрого возведения в степень
1 i n t in t pow ( int a , un s i gned n , u n s i g ned m ){
2 in t an s ;
3 if (0 != n % 2) ans = a % m; e l s e an s = 1 ;
4 fo r ( ; ; ){
40
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
