Skip to content

Commit cc9558e

Browse files
committed
Черновик раздела про прикладные особенности линейной алгебры.
1 parent 1910bfa commit cc9558e

3 files changed

Lines changed: 116 additions & 8 deletions

File tree

book_structure.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@
3636
- ✅ Раздел "Полукольцо" — `05_Semiring.tex`
3737
- ✅ Раздел "Кольцо" — `06_Ring.tex`
3838
- ✅ Раздел "Матрицы и вектора" — `07_MatricesAndVectors.tex`
39-
- ❌ Раздел "Прикладные особенности" — `08_AppliedAspects.tex`
40-
- Планируемое содержание раздела: Взгляд программиста: типы данных, не совсем честные алгебраические структуры (<<просто лишь бы типизировалось>>), GraphBLAS, разреженность, параллельность. Операции типа маски, map2 и так далее.
41-
- Задачи
42-
- Наполнить раздел "Прикладные особенности" содержимым
39+
- ⚠️ Раздел "Прикладные особенности" — `08_AppliedAspects.tex`
40+
> Разреженные матрицы и представление значений: связь `\Opt{L}` с Option/Maybe.
41+
> Поэлементные операции и проблема нулей: тип AtLeastOne.
42+
> map2 — универсальная поэлементная операция (сложение, умножение, маска).
43+
> mxm — обобщённое матричное умножение, параметризованное op\_mult/op\_add/zero.
44+
> GraphBLAS: стандарт, моноиды/полукольца, SuiteSparse:GraphBLAS.
45+
- Интегрированы материалы из статьи `papers_src/GraphBLAS_in_functional_style_КИО`: типы для разреженных матриц, проблема явных/неявных нулей, map2 и mxm, обзор GraphBLAS.
4346

4447
### Глава 2. Некоторые понятия теории множеств — `tex/part_01_Prep/chapter_02_SetTheory/main.tex` — ✅
4548

tex/FormalLanguageConstrainedReachabilityLectureNotes.bib

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,15 @@ @misc{Cusp
14361436
note = {Version 0.5.0}
14371437
}
14381438

1439+
@inproceedings{7761646,
1440+
author = {Kepner, Jeremy and Aaltonen, Peter and Bader, David A. and Bulu{\c{c}}, Ayd{\i}n and Franchetti, Franz and Gilbert, John R. and Hutchison, Dylan and Kumar, Manoj and Lumsdaine, Andrew and Meyerhenke, Henning and McMillan, Scott and Yang, Carl and Owens, John D. and Zalewski, Marcin and Mattson, Timothy G. and Moreira, Jos{\'e} E.},
1441+
title = {Mathematical Foundations of the GraphBLAS},
1442+
booktitle = {2016 IEEE High Performance Extreme Computing Conference (HPEC)},
1443+
year = {2016},
1444+
pages = {1--9},
1445+
doi = {10.1109/HPEC.2016.7761646}
1446+
}
1447+
14391448
@inproceedings{Davis2018Algorithm9S,
14401449
title = {Algorithm 9xx: SuiteSparse:GraphBLAS: graph algorithms in the language of sparse linear algebra},
14411450
author = {Timothy A. Davis},
Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,102 @@
11
\section{Прикладные особенности}
2-
\tikzsetfigurename{LinearAlgebra_Applied_}
2+
\tikzsetfigurename{LinearAlgebra_Applied_}
33

4-
\mytodo{Написать раздел}
5-
Планируемое содержание раздела: Взгляд программиста: типы данных, не совсем честные алгебраические структуры (<<просто лишь бы типизировалось>>), GraphBLAS, разреженность, параллельность. Операции типа маски, map2 и так далее.
6-
\mytodo{Перенести из GraphBLAS_in_functional_style_КИО. Про map2, Option, GraphBLAS и его проблемы. Связать с определением обобщённой матрицы смежности, с поэлементными операциями. }
4+
В предыдущих разделах мы определили полугруппы, моноиды, группы, полукольца и кольца как <<честные>> алгебраические структуры: сформулировали аксиомы, которым они должны удовлетворять, и привели примеры.
5+
На практике же при реализации алгоритмов анализа графов эти аксиомы часто соблюдаются лишь частично, а на первый план выходят вопросы представления данных, эффективности операций и удобства программного интерфейса.
6+
Данный раздел посвящён именно таким прикладным аспектам~\sidecite{7761646}.
7+
8+
Начнём с фундаментального вопроса~--- представления данных.
9+
При определении матрицы смежности (раздел~\ref{chpt:GraphTheoryIntro}) мы ввели множество $\Opt{L} = \{\Bbbzero\} \cup L$, где $\Bbbzero$ означает <<ребро отсутствует>>.
10+
В языках программирования такой конструкции естественно соответствует тип \texttt{Option} (OCaml, F\#) или \texttt{Maybe} (Haskell): значение \texttt{Some x} означает <<есть ребро с меткой \texttt{x}>>, а \texttt{None}~--- <<ребра нет>>.
11+
Таким образом, матрица смежности графа с метками типа \texttt{Lbl} имеет тип $\texttt{Matrix}\langle\texttt{Option}\langle\texttt{Lbl}\rangle\rangle$.
12+
13+
В реальных графах число рёбер, как правило, существенно меньше $|V|^2$, поэтому матрицы смежности разрежены: подавляющее большинство ячеек содержат \texttt{None}.
14+
Хранить их все нет смысла~--- достаточно хранить лишь те ячейки, которые соответствуют реально существующим рёбрам, то есть имеют значение \texttt{Some x}.
15+
Для этого существует множество форматов разреженных матриц: CSR (Compressed Sparse Row), координатный, Quad Tree и другие.
16+
Выбор формата определяется конкретной задачей и используемой библиотекой, но все они основаны на одной и той же идее: хранить только <<непустые>> ячейки.
17+
18+
Определившись со способом хранения, перейдём к операциям над разреженными матрицами.
19+
Поэлементная операция над двумя матрицами~--- это операция, которая применяется независимо к каждой паре ячеек с одинаковыми индексами.
20+
Наивная типизация такой операции имеет вид
21+
\[
22+
\texttt{Option}\langle T_1\rangle \to \texttt{Option}\langle T_2\rangle \to \texttt{Option}\langle T_3\rangle.
23+
\]
24+
Однако эта сигнатура недостаточно ограничительна: она позволяет определить операцию, возвращающую \texttt{Some x} даже тогда, когда оба аргумента равны \texttt{None}.
25+
Иными словами, можно <<создать значение из двух пустот>>.
26+
Эта проблема известна в сообществе GraphBLAS как \emph{проблема явных и неявных нулей}~\sidecite{7761646}: разреженная матрица хранит только явные (ненулевые) значения, но комбинация двух не-хранимых нулей не должна порождать новое хранимое значение.
27+
28+
Решение~--- ввести тип $\texttt{AtLeastOne}\langle T_1, T_2\rangle$, который гарантирует, что хотя бы один из аргументов непуст:
29+
\begin{align*}
30+
\texttt{AtLeastOne}\langle T_1, T_2\rangle =\ &\texttt{Both}\ \texttt{of}\ T_1 * T_2 \\
31+
\mid\ &\texttt{Left}\ \texttt{of}\ T_1 \\
32+
\mid\ &\texttt{Right}\ \texttt{of}\ T_2.
33+
\end{align*}
34+
Теперь поэлементная операция получает сигнатуру
35+
\[
36+
\texttt{op}: \texttt{AtLeastOne}\langle T_1, T_2\rangle \to \texttt{Option}\langle T_3\rangle,
37+
\]
38+
которая на уровне типов гарантирует, что операция никогда не будет вызвана с двумя \texttt{None}.
39+
При этом тип результата остаётся $\texttt{Option}\langle T_3\rangle$: операция всё ещё может вернуть \texttt{None}, и это просто означает, что в данной позиции результирующая ячейка не должна храниться.
40+
41+
Использование $\texttt{AtLeastOne}$ позволяет унифицировать поэлементные операции, заменив несколько специализированных функций одной обобщённой высокопорядковой функцией $\texttt{map2}$~\sidecite{7761646}:
42+
\begin{align*}
43+
\texttt{map2}\ & : \\
44+
& \quad \texttt{op}: \texttt{AtLeastOne}\langle T_1, T_2\rangle \to \texttt{Option}\langle T_3\rangle \\
45+
& \to \texttt{m}_1: \texttt{Matrix}\langle\texttt{Option}\langle T_1\rangle\rangle \\
46+
& \to \texttt{m}_2: \texttt{Matrix}\langle\texttt{Option}\langle T_2\rangle\rangle \\
47+
& \to \texttt{result}: \texttt{Matrix}\langle\texttt{Option}\langle T_3\rangle\rangle.
48+
\end{align*}
49+
Одна и та же функция $\texttt{map2}$, параметризованная разными операциями $\texttt{op}$, реализует и поэлементное сложение, и поэлементное умножение, и маскирование.
50+
Рассмотрим конкретные примеры.
51+
52+
Операция поэлементного сложения для целых чисел определяется следующим образом:
53+
\begin{align*}
54+
\texttt{op\_int\_add}\ (\texttt{Both}\ (x, y)) &= \texttt{Some}\ (x + y), \\
55+
\texttt{op\_int\_add}\ (\texttt{Left}\ x \mid \texttt{Right}\ y) &= \texttt{Some}\ x.
56+
\end{align*}
57+
(Если в результате сложения получился <<честный>> ноль, можно дополнительно вернуть \texttt{None}, чтобы не сохранять его.)
58+
59+
Операция поэлементного умножения, напротив, возвращает непустое значение только тогда, когда оба аргумента непусты:
60+
\begin{align*}
61+
\texttt{op\_int\_mult}\ (\texttt{Both}\ (x, y)) &= \texttt{Some}\ (x * y), \\
62+
\texttt{op\_int\_mult}\ (\texttt{Left}\ x \mid \texttt{Right}\ y) &= \texttt{None}.
63+
\end{align*}
64+
65+
Наконец, маска (оставить значения первой матрицы только там, где во второй матрице есть ненулевые значения) также является частным случаем $\texttt{map2}$:
66+
\begin{align*}
67+
\texttt{op\_mask}\ (\texttt{Both}\ (x, y)) &= \texttt{Some}\ x, \\
68+
\texttt{op\_mask}\ (\texttt{Left}\ x \mid \texttt{Right}\ y) &= \texttt{None}.
69+
\end{align*}
70+
71+
Идея параметризации операции может быть распространена и на матричное умножение.
72+
Напомним, что в разделе~\ref{chpt:LinearAlgebraIntro} мы определили матричное умножение над полукольцом $(S, \oplus, \otimes)$ как
73+
\[
74+
P[i,j] = \bigoplus_{l} M[i,l] \otimes N[l,j],
75+
\]
76+
где $\oplus$~--- операция <<сложения>> (агрегации) частичных результатов, а $\otimes$~--- операция <<умножения>> ячеек.
77+
78+
В терминах типов этому соответствует функция $\texttt{mxm}$:
79+
\begin{align*}
80+
\texttt{mxm}\ & : \\
81+
& \quad \texttt{m}_1: \texttt{Matrix}\langle\texttt{Option}\langle T_1\rangle\rangle \\
82+
& \to \texttt{m}_2: \texttt{Matrix}\langle\texttt{Option}\langle T_2\rangle\rangle \\
83+
& \to \texttt{op\_mult}: \texttt{Option}\langle T_1\rangle \to \texttt{Option}\langle T_2\rangle \to \texttt{Option}\langle T_3\rangle \\
84+
& \to \texttt{op\_add}: \texttt{Option}\langle T_3\rangle \to \texttt{Option}\langle T_3\rangle \to \texttt{Option}\langle T_3\rangle \\
85+
& \to \texttt{zero}: \texttt{Option}\langle T_3\rangle \\
86+
& \to \texttt{result}: \texttt{Matrix}\langle\texttt{Option}\langle T_3\rangle\rangle.
87+
\end{align*}
88+
89+
Здесь $\texttt{op\_mult}$ задаёт, как перемножить ячейку первой матрицы с ячейкой второй, $\texttt{op\_add}$~--- как сложить несколько частичных произведений для одной позиции результата, а $\texttt{zero}$~--- нейтральный элемент $\texttt{op\_add}$.
90+
Преимущество такого подхода перед классическим определением через полукольцо в том, что $\texttt{op\_mult}$ и $\texttt{op\_add}$ не обязаны удовлетворять аксиомам ассоциативности, коммутативности или дистрибутивности.
91+
На практике при решении задач анализа графов используемые операции часто не образуют полукольцо в математическом смысле, но это не мешает им быть полезными: достаточно, чтобы они были согласованы с конкретной решаемой задачей.
92+
Так, полукольцом может называться структура с доменами разных типов для аргументов умножения, что формально не является полукольцом в алгебраическом смысле, однако такая <<вольность>> оправдана практическими потребностями.
93+
94+
Именно такой подход реализован в стандарте GraphBLAS~\sidecite{7761646}~--- открытом стандарте, описывающем набор примитивов и операций разреженной линейной алгебры, предназначенных для построения алгоритмов анализа графов.
95+
Он вводит абстракции моноидов и полуколец, объекты (скаляры, векторы, матрицы) и операции над ними (поэлементные, матричное умножение, маскирование, редукция).
96+
Стандарт позволяет параметризовать операции пользовательскими полукольцами и тем самым единообразно выражать широкий класс графовых алгоритмов~--- от поиска кратчайших путей (тропическое полукольцо) до вычисления достижимости (булево полукольцо).
97+
98+
На практике этот стандарт реализуется в нескольких библиотеках: наиболее известная из них~--- SuiteSparse:GraphBLAS~\sidecite{Davis2018Algorithm9S}, широко используемая в высокопроизводительных графовых вычислениях.
99+
Активно развиваются и GPGPU-реализации, такие как GraphBLAST.
100+
101+
Независимо от конкретной реализации, главное преимущество GraphBLAS-подхода для программиста~--- возможность выражать графовые алгоритмы через композицию матричных операций, делегируя заботу о разреженности, параллелизме и низкоуровневых оптимизациях библиотеке.
102+
Операции $\texttt{map2}$ и $\texttt{mxm}$, параметризованные пользовательскими функциями, являются естественным обобщением этого подхода: они позволяют отказаться от жёсткого требования задавать полукольцо и вместо этого указывать ровно те операции, которые нужны для конкретной задачи, с явными гарантиями корректности на уровне типов~\sidecite{7761646}.

0 commit comments

Comments
 (0)