Skip to content

Matrix multiplication and triangle counting#7

Merged
gsvgit merged 15 commits intoLamagraph:mainfrom
Danil-Zaripov:mxm
Feb 6, 2026
Merged

Matrix multiplication and triangle counting#7
gsvgit merged 15 commits intoLamagraph:mainfrom
Danil-Zaripov:mxm

Conversation

@Danil-Zaripov
Copy link
Contributor

No description provided.

@Danil-Zaripov Danil-Zaripov requested a review from gsvgit February 4, 2026 15:53
(Matrix.mkNode tree (Matrix.qtree.Leaf Dummy) (Matrix.qtree.Leaf Dummy) (Matrix.qtree.Leaf Dummy))
(expandRatio / 2UL)

let mxm op_add op_mult (m1: Matrix.SparseMatrix<'a>) (m2: Matrix.SparseMatrix<'a>) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Типы матриц могут быть разными.

else
(Error.InconsistentSizeOfArguments(vector, matrix)) |> Result.Failure

let rec shrink tree (size: uint64<storageSize>) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Правда ли эти функции должны быть на верхнем уровне?

// DDDD
let tree =
qtree.Node(
qtree.Leaf << UserValue <| Some 2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А может сделать для таких вещей вспомогательные функции?
Типа

leaf_v v = qtree.Leaf << UserValue <| Some v
leaf_n = qtree.Leaf << UserValue <| None

и т.д.

let halfSize = size / 2UL

// Double check this code
let nw1xnw2, ne1xsw2, nw1xne2, ne1xse2, sw1xnw2, se1xsw2, sw1xne2, se1xse2 =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может nw1_x_nw2?

(multiply halfSize se1 se2)

match nw1xnw2, ne1xsw2, nw1xne2, ne1xse2, sw1xnw2, se1xsw2, sw1xne2, se1xse2 with
| Result.Success(tnw1xnw2, nvals_nw1xnw2),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И тут тоже t_nw1_x_nw2


match m1, m2 with
| Matrix.qtree.Leaf(UserValue v1), Matrix.qtree.Leaf(UserValue v2) ->
let res = multScalar op_add (uint64 size) (op_mult v1 v2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чот меня тип size смущает. Если я правильно понимаю, то тут он уже uint64. Тогда каст не нужен. Хотя я и не уверен, что это хорошая затея. Я бы предпочёл до последнего тянуть типизированный uint, и только в самом конце конвертировать к другим единицам. Больше кода, но и больше контроля со стороны компилятора.

let m1_tree, m2_tree =
if m1.storage.size < m2.storage.size then
expand (m1.storage.data) (m2.storage.size / (uint64 m1.storage.size)), m2.storage.data
else if m1.storage.size > m2.storage.size then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elif?

@Danil-Zaripov Danil-Zaripov requested a review from gsvgit February 5, 2026 08:06
@Danil-Zaripov Danil-Zaripov changed the title Matrix multiplication Matrix multiplication and triangle counting Feb 5, 2026
)
Matrix.qtree.Node(leaf_n (), leaf_v 1, leaf_v 3, leaf_v 2),
Matrix.qtree.Node(leaf_v 1, leaf_n (), leaf_v 2, leaf_v 3),
Matrix.qtree.Node(leaf_n (), leaf_n (), Matrix.qtree.Leaf(Dummy), Matrix.qtree.Leaf(Dummy)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dummy тоже вынести через хелпер?


[<Fact>]
let ``7V Triangle count`` () =
// Lower triangle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То есть Вы считаете, что в функцию подсчёта треугольиков сразу подаётся треугольная матрица?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В коде самой функции, вроде, есть получение треугольника. Может тогда тут всё же полноценная матрица смежности графа пусть будет?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Писать долго руками, и не понятно что это дает

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Даёт отсутствие ложных ожиданий от функции. Тесты - тоже документация. Можно, например, граф попроще взять.

Leaf (s, op v1)
| Node (s,x1,x2,x3,x4) ->
mkNode s (map op x1) (map op x2) (map op x3) (map op x4)
for _ in 1UL .. area do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не очень нравится такой код. В сети хорошо транслируется и параллелится код в духе рекурсивного "разделяй и властвуй". А с такимим циклами не понятно, что делать.

else
(Error.InconsistentSizeOfArguments(matrix1, matrix2)) |> Result.Failure

let fold (folder: 'State option -> 'T option -> 'State option) (state: 'State option) (matrix: SparseMatrix<'T>) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Надо не забыть потом написать что-то в духе fold_values, чтобы пустые куски не обходить. Вообще, надо потом подумать, как такое глобально дизайнить. Может и для map должна быть пара, которая только значеня обходит.

Assert.Equal(expected, actual)

[<Fact>]
let ``4x4 lower triangle`` () =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А для нечётного размера? А для каких-нибудь "пустых" блоков со странной структурой?


Assert.Equal(expected.storage.data, actual.storage.data)

[<Fact>]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На транспонирование ещё надо бы.

// Assume non-oriented graph adjacency matrix
// Some () -> edge, None -> no edge
// Computes triangle count
let triangle_count (graph: Matrix.SparseMatrix<unit>) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему unit? Вам же всё равно, что там на рёбрах.


let op_mult o1 o2 =
match o1, o2 with
| Some(), Some() -> Some 1UL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Во. Вам точно всё равно, что на рёбрах.

@Danil-Zaripov Danil-Zaripov requested a review from gsvgit February 5, 2026 15:06
else
(Error.InconsistentSizeOfArguments(matrix1, matrix2)) |> Result.Failure

let foldAssociative (folder: 'T option -> 'T option -> 'T option) (state: 'T option) (matrix: SparseMatrix<'T>) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Получился в тоге reduce. Давайте так и назовём. А над тем, как fold нормальный делать, я ещё подумаю.

@gsvgit gsvgit merged commit ecd5ba0 into Lamagraph:main Feb 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants