Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Алгоритмы решения систем линейных уравнений с блочно-ленточными матрицами. Монография
.pdf
Алгоритмы решения СЛАУ с блочно-ленточными матрицами. Глава 5 101
Следовательно, вычисление рассматриваемой программы — это ре-
ализация итерационного процесса решения некоторой задачи линейной
алгебры.
XXk = (I – A)–1*B* XX
k – 1
+ (I – A)–1*E.
Таким образом, вычисление программы удалось свести к решению за-
дачи линейной алгебры.
В представленной моногорафии демонстрируется взаимная сводимость
задач решения СЛАУ с блочной двухдиагональной матрицей и вычисления
рекуррентного программного цикла. Кроме того, демонстрируется взаимная
сводимость вычисления гнезд циклов итерационного типа и итерационных
алгоритмов некоторых задач линейной алгебры. Этим самым обозначено
новое направление на стыке математики и информационных технологий:
анализ и преобразования программ, выполняющих аффинные вычисления
с данными. Суть этого раздела теории преобразования программ в том, что
множество данных, с которыми работает программа, конечно, а всякие линейные преобразования данных эквивалентны матричным преобразованиям;
соответственно, аффинные преобразования данных — это матричные преобразования с прибавлениями константных векторов (данных). Ранее встречались работы (авторов монографии), в которых, например, вычисление и
анализ сходимости рекуррентного цикла сводились к решению и анализу
СЛАУ с треугольной ленточной матрицей. В данной монографии этот прием обобщается до метода, позволяющего к анализу и преобразованиям программ применять методы линейной алгебры, а к методам линейной алгебры
применять соответствующие методы теории преобразования программ.
Будем рассматривать гнезда циклов программных итерационного типа,
подобные алгоритму Гаусса-Зейделя.
for (t = 0; t < Itera; t++)
for (i
= 0; i1 < N1; i1++)
1
for (i2 = 0; i2 < N2; i2++) (15)
...
for (in = 0; in < Nn; in++)
LoopBoby;
Здесь Itera — количество итераций внешнего цикла, LoopBoby — сим-
волическая запись тела гнезда циклов. В теле гнезда циклов могут быть
генераторы (левые части операторов присваивания) вида A[i
, i2–a2, …,
1–a1
in–an] (запись в память). Если есть в теле гнезда циклов в левой части операторов присваиваний вхождение, A[i1–a1, i2–a2, …, in–an ], то в правой ча-

102 Б. Я. Штейнберг, О. Б. Штейнберг
сти могут быть вхождения этой же переменной с другими константами в
индексных выражениях A[i1–b1, i2–b2, …, in–bn ] (чтение из памяти), В теле
гнезда циклов могут быть и другие переменные и с другими индексными
выражениями, но генераторами (вхождениями, которые соответствуют операциям записи в память) могут быть только эти переменные. Одна и та же
переменная может входить в тело цикла несколько раз.
Каждому гнезду циклов можно поставить в соответствие вектор счетчиков
циклов (t, I1, I2, …, In) где имена счетчиков расположены в порядке вложенности циклов. Множество значений этого вектора образует пространство итераций IS. Поскольку значения счетчиков циклов — целые числа, пространство
итераций можно рассматривать как подмножество пространства Zn.
В монографии предлагается комбинация нескольких методов.
Ускорение алгоритмов такого итерационного типа на примере алгоритма Гаусса-Зейделя для двумерной задачи Дирихле на основе скошенного
тайлинга и распараллеливания на общей памяти на 8-ядерном процессоре
достигает 30 раз [18].
Приведем пример обобщенного алгоритма Гаусса-Зейделя для случая
двумерной области.
Пример 39. Рекуррентно вычисляемое гнездо циклов, реализующее
абстрактный обобщенный алгоритм Гаусса-Зейделя решения (двумерной) задачи Дирихле в области, имеющей форму прямоугольного
параллелепипеда.
for (It = 0; It < maxIt; It++) {
for (i1 = 1; i1<N; i1++) {
for (i2 = 1; i2<N; i2++) {
x[i1,i2] = a1[i1,i2]*x[i1–1, i2] + b1[i1,i2]*x[i1+1, i2] +
c1[i1,i2]*x[i1,i2–1] + d1[i1,i2]*x[i1,i2+1] + e1[i1,i2];
y[i1,i2] = a2[i1,i2]*y[i1–1,i2] + b2[i1,i2]*y[i1+1,i2] +
c2[i1,i2]*y[i1,i2–1] + d2[i1,i2]*y[i1,i2+1]+ e2[i1,i2];
}}}
Здесь a1[i1, i2], b1[i1, i2], c1[i1, i2], d1[i1, i2], e1[i1, i2]; a2[i1, i2], b2[i1, i2],
c2[i1, i2], d2*[i1, i2], e2[i1, i2] — массивы, не меняющие своих значе-
ний при вычислении программы (входные не вычисляемые данные).
Конец примера.

Алгоритмы решения СЛАУ с блочно-ленточными матрицами. Глава 5 103
Формирование вычислительной задачи по тексту программного
цикла, не содержащего зависимости
Пример 40.
for (j = 1; j < N; j++) {
x[j] = expr1(a1[j],b1[j],...)
y[j] = expr2(a2[j],b2[j],...)
}
Здесь выражения правой части expr1(a1[j], b1[j], …), expr2(a2[j], b2[j], …)
зависят только от входных данных программы и не зависят от вычисляемых переменных. Такой код не содержит информационных зависимостей. Все операторы присваивания могут вычисляться независимо друг от друга (параллельно).
Неинтересный вырожденный случай. Задача соответствует решению СЛАУ с единичной матрицей, правая часть которой вычисляется.
Конец примера.
Формирование вычислительной задачи по тексту программного
цикла, содержащего антизависимости
Пример 41.
for (j = 1; j < N; j++) {
x[j] = expr1(a1[j],b1[j],..., x[j+k1],y[j+k1])
y[j] = expr2(a2[j],b2[j],... , x[j+k3],y[j+k4])
...
}
Здесь k1, k2, k3, k4 — неотрицательные целые числа, выражения
правой части expr1(a1[j], b1[j], …, x[j+k1], y[j+k2]), expr2(a2[j], b2[j], … ,
x[j+k3], y[j+k4]) зависят не только от входных данных программы,
но и от вычисляемых переменных. Такой код содержит антизависимости. Это означает, что при вычислении выходных переменных
используются значения этих переменных, вычисленные ранее, или
они являются еще и входными данными и получены при вводе исходных данных.
Конец примера.

104 Б. Я. Штейнберг, О. Б. Штейнберг
Теорема 3. Если выражения правых частей цикла вида (из примера 40)
линейно зависят от вычисляемых переменных, входящих в программу с
антизависимостями, то вычисление цикла можно представить как задачу
умножения верхнетреугольной матрицы на вектор.
Доказательство. Достаточно рассмотреть случай, в котором в правой части есть только одно вхождение вычисляемой переменной, создающее антизависимость с генератором этой переменной. Если же таких вхождений несколько, с помощью преобразований «вынесение вычисления подвыражений» и
«разбиение цикла» рассматриваемый цикл можно представить в виде последовательности цик лов, каждый из которых имеет только одну антизависимость.
Если в теле программного цикла только одна антизависимость, то
утверждение теоремы доказывается методом математической индукции по
количеству итераций цикла.
Пример 42. Программный цикл с несколькими антизависимостями
for (j = 1; j < N; j++) {
x[j] = a[j]*x[j+k1] + b[j]*x[j+k2]) + ...
}
можно представить как последовательность двух циклов, каждый из
которых содержит меньше зависимостей:
for (j = 1; j < N; j++) {
x[j] = a[j]*x[j+k1]
}
for (j = 1; j < N; j++) {
x[j] = x[j] + b[j]*x[j+k2]) + ...
}
Процесс можно продолжать по индукции, пока не будет получен код,
представляющий последовательность циклов, каждый из которых
содержит одну антизависимость.
Конец примера.
Пример 43. Вычисление следующего программного цикла
с антизависимостями
for (j = 1; j < N; j++) {
x[j] = a[j]*x[j+1] + b[j]*x[j+2]) + … + h[j];
}
равносильно умножению ленточной матрицы U на вектор x со старыми значениями (известными до вычисления цикла) и прибавлению вектора h:

Алгоритмы решения СЛАУ с блочно-ленточными матрицами. Глава 5 105
x = U*x + h.
Здесь у ленточной матрицы U с единицами по главной диагонали
по другим ненулевым диагоналям расположены элементы массивов программы
1 a[1] b[1]
1 a[2] b[2]
1 a[3] b[3]
1 a[4] b[4]
1 a[5] b[5]
1 a[6] b[6]
…
а вектор h состоит из элементов массива h
h[1]
h[2]
h[3]
h[4]
h[5]
h[6]
…
Конец примера.
Пример 44. Вычисление следующего программного цикла с истин-
ными зависимостями
for (j = 3; j < N; j++) {
x[j] = a[j]*x[j – 1] + b[j]*x[j – 2]) + … + h[j];
}
равносильно решению СЛАУ с нижнетреугольной ленточной
матрицей.
1 h[1]
0 1 h[2]
–a[1] –b[1] 1 h[3]
–a[2] –b[2] 1 h[3+1]
–a[3] –b[3] 1 h[3+2]
– a[4] –b[4] 1 h[3+3]
–a[5] –b[5] 1 h[3+4]
–a[6] –b[6] 1 h[3+5]
…
Конец примера.

106 Б. Я. Штейнберг, О. Б. Штейнберг
Пример 45. Случай выходной зависимости
for (j = L; j < N; j++) {
x[j] = expr1(a1[j],b1[j],…)
x[j+k] = expr2(a2[j],b2[j],…)
}
Здесь k — целое число, выражения правой части expr1(a1[j ], b1[j], …),
expr2(a2[j], b2[j], …) зависят только от входных данных программы и
не зависят от вычисляемых переменных. Такой код содержит выходную зависимость. Это означает, что при вычислении выходных переменных иногда некоторые выходные значения вычисляются 2 раза:
приобретают одно значение, которое затем перевычисляется. Конечно, интерес представляет только последний раз присвоенное переменной значение. Рассматриваемый цикл равносилен двум последовательно выполняемым циклам. В итоге, N +|k| элементов массива
получают новые значения.
Если k > 0, то исходный цикл равносилен следующим двум:
for (j = L; j < L+k; j++) {
x[j] = expr1(a1[j],b1[j],…)
}
for (j = L; j < N; j++) {
x[j+k] = expr2(a2[j],b2[j],…
}
Если k < 0, то исходный цикл равносилен следующим двум
for (j = L+k; j < L; j++) {
x[j] = expr1(a1[j],b1[j],…)
}
for (j = L; j < N; j++) {
x[j+k] = expr2(a2[j],b2[j],…)
}
Конец примера.
Пример 46. Одновременное наличие истинной зависимости и антизависимости. Примером может служить код алгоритма Гаусса-Зейделя решения задачи Дирихле. В этом случае вычисление программы
равносильно решению матричного уравнения
A*x = B*x + h.

Алгоритмы решения СЛАУ с блочно-ленточными матрицами. Глава 5 107
Здесь h — вектор входных данных, x — вектор неизвестных,
B — верхнетреугольная матрица коэффициентов при вхождени-
ях неизвестных, от которых идут дуги антизависимости, A нижнетреугольная матрица коэффициентов при вхождениях неизвестных,
к которым идут дуги истинной зависимости.
Конец примера.
5.4. Операторы сдвига, операторы умножения
на функцию и соответствующие им матрицы
Будем рассматривать множество векторов с целыми координатами Zm.
На этом множестве функций C(Zm ) будем рассматривать оператор сдвига Sk
и оператор умножения на функцию Mf, которые определяются, как обычно,
следующим образом:
Sk(φ)(t) = φ(t–k) t, k ϵ Z
Mf (φ)(t) = f(t)*φ(t) t, k ϵ Zm.
Обозначим прямоугольный параллелепипед в m-мерном целочисленном
пространстве Z
m
D = {1, 2, ..., n1}x{1, 2, ..., n2}x … x{1, 2, ..., nm};
n1, n2, …, nm — положительные целые числа.
Как обычно, характеристическая функция множества D — это функция,
которая равна 1 в точках множества D и равна нулю в точках, не принадлежащих D. Пусть проектор P
тор умножения на характеристическую функцию множества D. Тогда PD (φ)
равна нулю за пределами прямоугольной двумерной области D. Произведение сдвига и проектора удовлетворяют равенству
— это функция, равная нулю за пределами сдвинутого (целочисленного)
прямоугольного параллелепипеда, а функция PD Sk PD (φ)(t) равна нулю за
пределами пересечения прямоугольников (для случая m = 2).
m
в пространстве функций C(Zm) — это опера-
D
S
(φ)(t) = (PD φ)(t–k), t, k ϵ Z
k PD
m

108 Б. Я. Штейнберг, О. Б. Штейнберг
Пример 47.
for (i = 0; i < n1; i++) {
for {j = 0; j++, j<n2) { (16)
U[i,j] = X[i+1,j+3];
}}
Массив X будем рассматривать как функцию на множестве индексов D = {1, 2, ..., n
сдвига S
P
D Sk PD
на величину (вектор) k = (1, 3). Тогда функция
k
(X)(t)
определена на области индексов {2, 3, ..., (n
Ленточная матрица с одной диагональю соответствует оператору
P
D*Sk*Mf
*PD (φ)(t) (17)
Конец примера.
} x {1, 2, ..., n2}, и будем рассматривать оператор
1
+1)} x {4, 5, ..., (n2 +3)}.
1
Нумерация узлов параллелепипеда
Разным нумерациям узлов прямоугольного параллелепипеда (области
определения функций C(D))
D = {1, 2, …, n
соответствуют разные матрицы операторов на конечномерном простран-
стве функций C(D).
Опишем каноническую нумерацию узлов параллелепипеда.
Занумеруем точки области
D = {1, 2, …, n
следующим образом. Точке
a = (a
, a
1
поставим в соответствие номер
k = a1*n1 + a2*n2 +… + a
} x {1, 2, ..., n2 } x … x {1, 2, ..., nm}
1
} x {1, 2, …, n2} x … x {1, 2, …, nm}
1
…, am )
2 ,
m – 1*nm – 1
+ am.

Алгоритмы решения СЛАУ с блочно-ленточными матрицами. Глава 5 109
0000000000
0000000000
1111111110
1111111110
1111111110
1111111110
1111111110
1111111110
1111111110
0000000000
0000000000
0000000000
При такой нумерации операторам (17) соответствуют ленточные матрицы. Размерность матриц равна произведению n1*n2*…*n
m – 1*nm
.
«Ненулевая диагональ» отстоит от главной на n1 позиций. Каждая строка, номер которой делится на одно из чисел n2, … n
, nm, является ну-
m – 1
левой. Аналогично, каждый столбец, номер которого делится на одно из
чисел n2, … n
, nm, является нулевым.
m – 1
При m > 1 матрица имеет иерархию блоков.
Всякая ленточная матрица может быть представлена в виде конечной
суммы произведений операторов умножения на функцию и операторов
сдвига (и проекторов):
P
*(Mf1*Sk1 + Mf2*Sk2 + … )*PD. (18)
D
Операторы сдвига являются образующими алгебры операторов свертки,
а операторы вида (18) называют операторами обобщенной свертки или операторами типа свертки.
5.5. Операторы сдвига
Рассмотрим матрицу A размером M x N с элементами a[i, j] в которой
первые L и последние R столбцов полностью состоят из нулей. Помимо
этого, U первых и D последних строк также состоят из нулей.
Пример 48. В примере показана матрица A размерности 10x12, в которой все ненулевые элементы равны 1. При этом L = 0, R = 1, U = 2,
D = 3.
A
=
Конец примера.
.

110 Б. Я. Штейнберг, О. Б. Штейнберг
01111
01111
00000
00000
( )
' 01111011110000000000
Задача 1. Имея двумерный массив, определить значения L, R, U, D.
Решение: рассмотрим функцию, способную определить значение L.
functionL (A, N, M, L) {
L = N;
for (int i = 0; i < M; i++) {
for (int j = 0; j < L; j++) {
if (a[i][j]! = 0) {
L = j;
}}}}
Конец решения.
Подобным образом можно определить значения R, U, D.
Рассмотрим ситуацию, когда матрица A представлена одномерным мас-
сивом (т. е. последовательности строк).
Пример 49. В примере показана матрица A размерности 4x5, в которой
все ненулевые элементы равны 1. При этом L = 1, R = 0, U = 0, D = 2.
A
=
Ее представление одномерным массивом будет иметь вид:
.
A =
Конец примера.
Задача 2. Имея одномерный массив, определить значения L, R, U, D.
Решение: рассмотрим функцию, способную определить значение L.
functionL (A, N, M, L) {
L = N;
for (int i = 0; i < M; i++) {
for (int j = 0; j < L; j++) {
if (a[i*N + j]! = 0) {
L = j;
}}}}
Конец решения.
Подобным образом можно определить значения R, U, D.
.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
