Skip to content

Commit 05fae16

Browse files
committed
feat: implement user filtration
This patch brings user filtration logic: 1) Build filter via vector assign and kronecker product 2) Apply filter to matrix via assigning mask Signed-off-by: Rodion Suvorov <rodion.suvorov.94@mail.ru>
1 parent f741400 commit 05fae16

File tree

1 file changed

+162
-49
lines changed

1 file changed

+162
-49
lines changed

src/main.c

Lines changed: 162 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ typedef struct EdgeTX
4848
uint32_t count;
4949
} EdgeTX;
5050

51-
// operations TODO
51+
// operations TODO TODO TODO !!!
5252

5353
void tx_add(EdgeTX *z, EdgeTX *x, EdgeTX *y)
5454
{
@@ -62,6 +62,12 @@ void owns_add(EdgeOwns *z, EdgeOwns *x, EdgeOwns *y)
6262
void owns_mul(EdgeOwns *z, EdgeOwns *x, EdgeOwns *y)
6363
{
6464
}
65+
void check_user_age(bool *z, const User *x, GrB_Index _i, GrB_Index _j, const uint8_t *y) // EdgeOwns
66+
{
67+
{
68+
*z = (x->age > *y);
69+
}
70+
}
6571

6672
int main()
6773
{
@@ -75,8 +81,11 @@ int main()
7581
printf("GraphBLAS initialized.\n");
7682
LAGraph_Init(msg);
7783
printf("LAGraph initialized.\n\n");
84+
// GxB_Global_Option_set(GxB_BURBLE, true);
7885

86+
// ------------------------------------------------------------------------
7987
// init edge matrices
88+
// ------------------------------------------------------------------------
8089

8190
// custom types for edges
8291
GrB_Type tx_edge, owns_edge;
@@ -98,25 +107,25 @@ int main()
98107
GrB_Monoid tx_monoid;
99108
GrB_Semiring tx_semiring;
100109
EdgeTX tx_edge_id;
101-
info = GrB_BinaryOp_new(&tx_plus, (GxB_binary_function)&tx_add, tx_edge, tx_edge, tx_edge);
110+
info = GrB_BinaryOp_new(&tx_plus, (GxB_binary_function)&tx_add, tx_edge, tx_edge, tx_edge); // TODO
102111
if (info != GrB_SUCCESS)
103112
{
104113
fprintf(stderr, "failed to create \"tx_plus\" binop\n");
105114
return 1;
106115
}
107-
info = GrB_BinaryOp_new(&tx_mult, (GxB_binary_function)&tx_mul, tx_edge, tx_edge, tx_edge);
116+
info = GrB_BinaryOp_new(&tx_mult, (GxB_binary_function)&tx_mul, tx_edge, tx_edge, tx_edge); // TODO
108117
if (info != GrB_SUCCESS)
109118
{
110119
fprintf(stderr, "failed to create \"tx_mult\" binop\n");
111120
return 1;
112121
}
113-
info = GrB_Monoid_new(&tx_monoid, tx_plus, (void *)&tx_edge_id);
122+
info = GrB_Monoid_new(&tx_monoid, tx_plus, (void *)&tx_edge_id); // TODO
114123
if (info != GrB_SUCCESS)
115124
{
116125
fprintf(stderr, "failed to create \"tx\" monoud\n");
117126
return 1;
118127
}
119-
info = GrB_Semiring_new(&tx_semiring, tx_monoid, tx_mult);
128+
info = GrB_Semiring_new(&tx_semiring, tx_monoid, tx_mult); // TODO
120129
if (info != GrB_SUCCESS)
121130
{
122131
fprintf(stderr, "failed to create \"tx\" semiring\n");
@@ -127,25 +136,25 @@ int main()
127136
GrB_Monoid owns_monoid;
128137
GrB_Semiring owns_semiring;
129138
EdgeOwns owns_edge_id;
130-
info = GrB_BinaryOp_new(&owns_plus, (GxB_binary_function)&owns_add, owns_edge, owns_edge, owns_edge);
139+
info = GrB_BinaryOp_new(&owns_plus, (GxB_binary_function)&owns_add, owns_edge, owns_edge, owns_edge); // TODO
131140
if (info != GrB_SUCCESS)
132141
{
133142
fprintf(stderr, "failed to create \"owns_plus\" binop\n");
134143
return 1;
135144
}
136-
info = GrB_BinaryOp_new(&owns_mult, (GxB_binary_function)&owns_mul, owns_edge, owns_edge, owns_edge);
145+
info = GrB_BinaryOp_new(&owns_mult, (GxB_binary_function)&owns_mul, owns_edge, owns_edge, owns_edge); // TODO
137146
if (info != GrB_SUCCESS)
138147
{
139148
fprintf(stderr, "failed to create \"tx_mult\" binop\n");
140149
return 1;
141150
}
142-
info = GrB_Monoid_new(&owns_monoid, owns_plus, (void *)&owns_edge_id);
151+
info = GrB_Monoid_new(&owns_monoid, owns_plus, (void *)&owns_edge_id); // TODO
143152
if (info != GrB_SUCCESS)
144153
{
145154
fprintf(stderr, "failed to create \"owns\" monoid\n");
146155
return 1;
147156
}
148-
info = GrB_Semiring_new(&owns_semiring, owns_monoid, owns_mult);
157+
info = GrB_Semiring_new(&owns_semiring, owns_monoid, owns_mult); // TODO
149158
if (info != GrB_SUCCESS)
150159
{
151160
fprintf(stderr, "failed to create \"tx\" semiring\n");
@@ -235,9 +244,13 @@ int main()
235244
return 1;
236245
}
237246

247+
// ------------------------------------------------------------------------
238248
// init vetrices vectors
249+
// ------------------------------------------------------------------------
250+
239251
GrB_Type user, card;
240252
info = GrB_Type_new(&user, sizeof(User));
253+
241254
if (info != GrB_SUCCESS)
242255
{
243256
fprintf(stderr, "failed to create \"user\" type\n");
@@ -249,6 +262,7 @@ int main()
249262
fprintf(stderr, "failed to create \"card\" type\n");
250263
return 1;
251264
}
265+
252266
// 1 - 4 --- users
253267
GrB_Vector users;
254268
info = GrB_Vector_new(&users, user, VERTICES_NUMBER);
@@ -285,7 +299,8 @@ int main()
285299
fprintf(stderr, "failed to insert \"user4\" in vector\n");
286300
return 1;
287301
}
288-
// // 5 - 9 --- cards
302+
303+
// 5 - 9 --- cards
289304
GrB_Vector cards;
290305
info = GrB_Vector_new(&cards, card, VERTICES_NUMBER);
291306
if (info != GrB_SUCCESS)
@@ -329,72 +344,170 @@ int main()
329344
return 1;
330345
}
331346

332-
// build filters
333-
// GrB_Index width, height;
334-
// GrB_Matrix_nrows(&height, call_edges_mat);
335-
// GrB_Matrix_ncols(&width, call_edges_mat);
347+
// ------------------------------------------------------------------------
348+
// build user filters
349+
// ------------------------------------------------------------------------
336350

337-
// // all matrices are squared so let n be a dimension
338-
// GrB_Index n = width;
351+
// vertex filter: we will take only prersons over 30 and exclude cards with `mastercard` payment system
352+
GrB_Matrix ID;
353+
GrB_Vector v;
354+
info = GrB_Vector_new(&v, GrB_BOOL, VERTICES_NUMBER);
355+
if (info != GrB_SUCCESS)
356+
{
357+
fprintf(stderr, "failed to create \"ID\" vector\n");
358+
return 1;
359+
}
360+
info = GrB_Vector_assign_BOOL(v, NULL, NULL, false, GrB_ALL, VERTICES_NUMBER, NULL);
361+
if (info != GrB_SUCCESS)
362+
{
363+
fprintf(stderr, "failed to assign values to \"v\" vector\n");
364+
return 1;
365+
}
339366

340-
// // vertex filter: we will take only prersons over 30 and exclude cards with `mastercard` payment system
341-
// GrB_Matrix ID;
342-
// GrB_Vector v;
343-
// GrB_Vector_new(&v, GrB_BOOL, n);
344-
// GrB_Vector_assign_BOOL(v, NULL, NULL, true, GrB_ALL, n, NULL);
367+
// create selector
368+
GrB_IndexUnaryOp user_age;
369+
info = GrB_IndexUnaryOp_new(&user_age, (GxB_index_unary_function)&check_user_age, GrB_BOOL, user, GrB_UINT8); // TODO
370+
if (info != GrB_SUCCESS)
371+
{
372+
fprintf(stderr, "failed to create \"user_age\" unop\n");
373+
return 1;
374+
}
375+
uint8_t age = 30;
376+
info = GrB_Vector_apply_IndexOp_UDT(v, NULL, NULL, user_age, users, &age, NULL);
377+
if (info != GrB_SUCCESS)
378+
{
379+
fprintf(stderr, "failed to select elements from users vector: %d\n", info);
380+
return 1;
381+
}
382+
GxB_print(v, GxB_COMPLETE);
383+
GrB_Matrix v_mat, id_mat;
384+
GrB_Matrix_new(&v_mat, GrB_BOOL,VERTICES_NUMBER,1);
385+
GrB_Col_assign(v_mat,NULL,NULL,v,GrB_ALL,VERTICES_NUMBER,0,NULL);
345386

346-
// GrB_Index size = 0;
347-
// GrB_Index *zeros = malloc(n * sizeof(GrB_Index));
348-
// // GrB_select !!!
349-
// for (size_t i = 0; i < 4; i++)
350-
// {
351-
// if (users[i].age > 30)
352-
// {
353-
// GrB_Info e = GrB_Vector_setElement_BOOL(v, false, i);
354-
// }
355-
// }
387+
GrB_Vector id;
388+
info = GrB_Vector_new(&id, GrB_BOOL, VERTICES_NUMBER);
389+
info = GrB_Vector_assign_BOOL(id, NULL, NULL, true, GrB_ALL, VERTICES_NUMBER, NULL);
390+
GrB_Matrix_new(&id_mat, GrB_BOOL,1,VERTICES_NUMBER);
391+
GrB_Row_assign(id_mat,NULL,NULL,id,0,GrB_ALL,VERTICES_NUMBER,NULL);
356392

357-
// free(zeros);
358-
// GrB_Matrix_diag(&ID, v, 0);
393+
GrB_Matrix kron;
394+
GrB_Matrix_new(&kron,GrB_BOOL,VERTICES_NUMBER,VERTICES_NUMBER);
395+
GxB_print(v_mat, GxB_COMPLETE);
396+
GxB_print(id_mat, GxB_COMPLETE);
397+
info = GrB_kronecker(kron, NULL, NULL, GrB_LAND, v_mat, id_mat, NULL);
398+
// info = GrB_Matrix_diag(&ID, v, 0);
399+
if (info != GrB_SUCCESS)
400+
{
401+
fprintf(stderr, "failed to create filter matrix %d\n", info);
402+
return 1;
403+
}
359404

360-
// // DEBUG
361-
// printf("filter matrix content: \n");
362-
// for (GrB_Index i = 0; i < n; i++)
405+
// DEBUG
406+
printf("filter matrix content: \n");
407+
for (GrB_Index i = 0; i < VERTICES_NUMBER; i++)
408+
for (GrB_Index j = 0; j < VERTICES_NUMBER; j++)
409+
{
410+
bool val;
411+
GrB_Info info = GrB_Matrix_extractElement_BOOL(&val, kron, i, j);
412+
if (info == GrB_SUCCESS)
413+
{
414+
printf("[%lu,%lu] = %d\n", i, j, val);
415+
}
416+
else if (info == GrB_NO_VALUE)
417+
{
418+
printf("[%lu,%lu] no value\n", i, j);
419+
}
420+
else
421+
{
422+
printf("[%lu,%lu] error code: %d\n", i, j, info);
423+
}
424+
}
425+
// for (GrB_Index i = 0; i < VERTICES_NUMBER; i++)
363426
// {
364427
// bool val;
365-
// GrB_Info info = GrB_Matrix_extractElement_BOOL(&val, ID, i, i);
428+
// GrB_Info info = GrB_Matrix_extractElement_BOOL(&val, kron, i, i);
366429
// if (info == GrB_SUCCESS)
367430
// {
368431
// printf("[%lu,%lu] = %d\n", i, i, val);
369432
// }
433+
// else if (info == GrB_NO_VALUE)
434+
// {
435+
// printf("[%lu,%lu] no value\n", i, i);
436+
// }
370437
// else
371438
// {
372-
// printf("[%lu,%lu] error\n", i, i);
439+
// printf("[%lu,%lu] error code: %d\n", i, i, info);
373440
// }
374441
// }
375442

376-
// // apply filters
377-
378-
// // verices filter
379-
// // фильтр только owns фильтруем с одной стороны (исходящие ребра) (поправить рисунок)
380-
// GrB_Matrix owns_mat_filtered;
381-
// // M x ID
382-
// GrB_mxm(owns_mat_filtered,NULL,NULL,GxB_ANY_PAIR_BOOL,call_edges_mat,ID,NULL);
383-
// // ID x M
384-
// GrB_mxm(owns_mat_filtered,NULL,NULL,GxB_ANY_PAIR_BOOL,ID,call_edges_mat,NULL); // A*
385-
// // в итоге получаем ребра исходящие из отобранных пользователем
443+
// ------------------------------------------------------------------------
444+
// apply user filters
445+
// ------------------------------------------------------------------------
446+
447+
// verices filter
448+
// фильтр только owns фильтруем с одной стороны (исходящие ребра) (поправить рисунок)
449+
GrB_Matrix owns_mat_filtered;
450+
GrB_Matrix_new(&owns_mat_filtered,owns_edge,VERTICES_NUMBER,VERTICES_NUMBER);
451+
printf("\nowns edge mat before filter\n");
452+
for (GrB_Index i = 0; i < VERTICES_NUMBER; i++)
453+
for (GrB_Index j = 0; j < VERTICES_NUMBER; j++)
454+
{
455+
EdgeOwns val;
456+
GrB_Info info = GrB_Matrix_extractElement_UDT(&val, owns_edge_mat, i, j);
457+
if (info == GrB_SUCCESS)
458+
{
459+
printf("[%lu,%lu] = %d\n", i, j, val.days);
460+
}
461+
// else if (info == GrB_NO_VALUE)
462+
// {
463+
// printf("[%lu,%lu] no value\n", i, j);
464+
// }
465+
// else
466+
// {
467+
// printf("[%lu,%lu] error code: %d\n", i, j, info);
468+
// }
469+
}
470+
// apply filter
471+
info = GrB_Matrix_assign(owns_mat_filtered, kron, NULL, owns_edge_mat, GrB_ALL, VERTICES_NUMBER, GrB_ALL, VERTICES_NUMBER, NULL);
472+
if (info != GrB_SUCCESS)
473+
{
474+
fprintf(stderr, "failed to apply filter to owns matrix %d\n", info);
475+
return 1;
476+
}
477+
printf("\nowns edge mat after filter\n");
478+
for (GrB_Index i = 0; i < VERTICES_NUMBER; i++)
479+
for (GrB_Index j = 0; j < VERTICES_NUMBER; j++)
480+
{
481+
EdgeOwns val;
482+
GrB_Info info = GrB_Matrix_extractElement_UDT(&val, owns_mat_filtered, i, j);
483+
if (info == GrB_SUCCESS)
484+
{
485+
printf("[%lu,%lu] = %d\n", i, j, val.days);
486+
}
487+
// else if (info == GrB_NO_VALUE)
488+
// {
489+
// printf("[%lu,%lu] no value\n", i, j);
490+
// }
491+
// else
492+
// {
493+
// printf("[%lu,%lu] error code: %d\n", i, j, info);
494+
// }
495+
}
496+
// в итоге получаем ребра исходящие из отобранных пользователем
386497

387498
// /*--------------------------- PART 2 --------------------------*/
388499

389500
// теперь нужно взять карты (редукция по строчкам или по столбцам)
390501
// редуцируем карты (строим вектор карты, которые относятся к отфильтрованным пользователем )
502+
391503
// строим ID матрицу
504+
392505
// ID с двух сторон на матрицу транзакций
393506
// получили подграф на нужных транзакциях
507+
394508
// теперь строим матрицу для pagerank (пункт ниже). softmax. (посмотреть как можно сделать не по дебильному с помощью GB)
395509
/// снова редуцируем по строчкам , получаем знаменатель softmax
396510
/// 2
397-
// build matrix M'
398511

399512
// run pagerank
400513
}

0 commit comments

Comments
 (0)