You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Полный код разбираемого примера можно увидеть в [файле](./src/main.c).
5
25
6
26
Цель примера --- показать, как в рамках GraphBLAS можно работать со сложными атрибутами вершин и рёбер графа.
7
27
@@ -17,7 +37,7 @@ Stand for PageRank algorithm benchmark
17
37
18
38
Пусть будут следующие типы карт: МИР, VISA, MASTERCARD.
19
39
20
-
При этом рёбра типа "Перевод" в качестве атрибутов сожержат общую сумму и "количество транзакций".
40
+
При этом рёбра типа "Перевод" в качестве атрибутов содержат общую сумму и "количество транзакций".
21
41
Рёбра типа "Владеет" не имеют атрибутов.
22
42
23
43
Для примера возьмём следующий граф.
@@ -26,7 +46,6 @@ Stand for PageRank algorithm benchmark
26
46
27
47
Хотим выбрать по некоторому критерию пользователей и их карты, а затем для анализа переводов хотим посчитать PageRank на подграфе, заданном переводами между отобранными картами.
28
48
Выбрать хотим все карты системы "МИР", которыми владеют люди старше заданного возраста. Покажем, как это можно сделать, используя матрично-векторные операции, в частности [GraphBLAS](https://github.com/GraphBLAS).
29
-
Полный код разбираемого примера мрожно увидеть в файле [!!!!](!!!!).
30
49
31
50
GraphBLAS позволяет в качестве атрибутов использовать пользовательские типы (фиксированных размеров), потому объявим необходимый нам набор типов.
32
51
```c
@@ -68,9 +87,9 @@ typedef struct
68
87
```
69
88
70
89
Граф представлен как набор матриц и векторов: по одной матрице на каждый тип рёбер и по одному вектору на каждый тип вершин.
71
-
Матрицы и вектора в большинстве случаев будут разреженными и мы будем использовать символ '$.$' для обозначения отсутсвующего элемента.
90
+
Матрицы и вектора в большинстве случаев будут разреженными и мы будем использовать символ '$.$' для обозначения отсутствующего элемента.
72
91
Считаем при этом, что все вершины, вне зависимости от типа, занумерованы с 0 подряд (id вершин на рисунке).
73
-
Таким образом, нам понядобятся две матрицы:
92
+
Таким образом, нам понадобятся две матрицы:
74
93
75
94
$$
76
95
\texttt{TX-Edges}=
@@ -124,7 +143,7 @@ $$
124
143
Скажем, нас будут интересовать пользователи старше 30 лет.
125
144
Для этого в GraphBLAS есть функция ```Select```, которая фильтрует коллекции, используя функцию-предикат принимаемую в качестве аргумента.
126
145
127
-
Так как нам предстоит работать с пользовательскими типами, то предётся написать собственный предикат.
146
+
Так как нам предстоит работать с пользовательскими типами, то придётся написать собственный предикат.
Два дополнительных параметра типа ```GrB_Index``` позволяют, при необходимости, использовать в фильтре координаты рассматриваемого элемента.
137
156
138
157
Для того, чтобы выбрать карты, принадлежащие выбранным пользователям, нам необходимо получить "концы" рёбер типа Owns, исходящие из выбранных пользователей.
139
-
Чтобы сделать это, выполним один шаг обхода в ширину, который в терминах линейной алгебры выражается через умноженеи вектора текущих вершин на матрицу смежности.
158
+
Чтобы сделать это, выполним один шаг обхода в ширину, который в терминах линейной алгебры выражается через умножение вектора текущих вершин на матрицу смежности.
140
159
Текущие вершины в нашем случае --- выбранные пользователи.
141
160
То есть нам необходимо вычислить следующее произведение.
142
161
@@ -178,7 +197,7 @@ $$
178
197
179
198
Мы получили не совсем карты, но вектор, который указывает, какие карты нас интересуют.
180
199
Вспомним, что мы хотим взять только карты "МИР".
181
-
Для этого снова будем использовать Select, а полученный вектор $\texttt{Filtered-Cards}$ будем использовать как маску, чтобы дополнительно тфильтровать результат.
200
+
Для этого снова будем использовать Select, а полученный вектор $\texttt{Filtered-Cards}$ будем использовать как маску, чтобы дополнительно отфильтровать результат.
182
201
183
202
184
203
Чтобы получить переводы только между отобранными картами, воспользуемся тем фактом, что выбор исходящих рёбер, инцидентных заданному множеству вершин --- это умножение матрицы смежности на диагональную матрицу, в которой ненулевые элементы на местах интересующих нас вершин, слева.
@@ -261,14 +280,14 @@ $$
261
280
262
281
В качестве конкретных реализаций для $+$ можно взять логическое "И", а в качестве $*$ операцию $\textit{second}$ (вернуть второй элемент из пары).
263
282
264
-
Для $\otimes_2$ ситуация аналогияная,
265
-
Необходимо только проследить за тем, в какие моменты надо брать первый элемент из пары, а в какие вотрой, чтобы в результате получилась матрица с элементами типа $\texttt{EdgeTX}$
283
+
Для $\otimes_2$ ситуация аналогичная,
284
+
Необходимо только проследить за тем, в какие моменты надо брать первый элемент из пары, а в какие второй, чтобы в результате получилась матрица с элементами типа $\texttt{EdgeTX}$
266
285
267
286
Подграф готов.
268
-
Теперь неорбходимо сконструировать матрицу, по которой непосредственно будем считать PageRank.
287
+
Теперь необходимо сконструировать матрицу, по которой непосредственно будем считать PageRank.
269
288
Сейчас метки рёбер --- структуры, хранящие информацию о переводах, а мы хотим получить одно число.
270
289
При этом важно, чтобы сумма весов всех исходящих рёбер была равна единице.
271
-
Для примера действовать будем следующим образом: возьмём "средний размер транзакции" (вычислим как $\frac{\textit{Sum}}{\textit{Count}}$), поделим на 1000 (на всякий случай, чтобы избежать слишком больших знчений) и затем построчно примерним Softmax.
290
+
Для примера действовать будем следующим образом: возьмём "средний размер транзакции" (вычислим как $\frac{\textit{Sum}}{\textit{Count}}$), поделим на 1000 (на всякий случай, чтобы избежать слишком больших значений) и затем построчно применим Softmax.
272
291
Иными словами, будем использовать идею функции Softmax, которая задаётся следующим образом.
273
292
274
293
$$
@@ -283,10 +302,10 @@ $$
283
302
$$
284
303
285
304
Вычисления построим следующим образом. Сперва выполним редукцию по колонкам с использованием функции $f$: таким образом получим знаменатель дроби.
286
-
После этого сконструируем две квадратные матрицы: в одной нулевой столбец --- это получанный вектор, а остальные нули, в другой --- нулевая строка --- единицы, остальное --- нули.
305
+
После этого сконструируем две квадратные матрицы: в одной нулевой столбец --- это полученный вектор, а остальные нули, в другой --- нулевая строка --- единицы, остальное --- нули.
287
306
Перемножим эти две матрицы, использую исходную матрицу $\texttt{Filtered-Transactions}$ в качестве маски.
288
307
Таким образом получим матрицу, в которой знаменатель стоит на необходимых местах.
289
-
Также нам нужна будет матрица, содержащая числители дробей (получается поэлементным примерением соответствующей функции к $\texttt{Filtered-Transactions}$)
308
+
Также нам нужна будет матрица, содержащая числители дробей (получается поэлементным применением соответствующей функции к $\texttt{Filtered-Transactions}$)
290
309
После чего поэлементно поделим эти две матрицы.
291
310
292
-
Далее на полученной матрице запускаем [классический алгоритм PageRank](!!!) (правда, без "телепортации" в несвязанные вершины), который в терминах линейной алгебры реалищуется по определению: итеративное умножение исходной матрицы на вектор.
311
+
Далее на полученной матрице запускаем [классический алгоритм PageRank](./src/main.c#L190) (правда, без "телепортации" в несвязанные вершины), который в терминах линейной алгебры реализуется по определению: итеративное умножение исходной матрицы на вектор.
0 commit comments