【问题标题】:Boolean matrix multiplication in JuliaJulia中的布尔矩阵乘法
【发布时间】:2020-11-21 02:15:24
【问题描述】:

我需要在 Julia 中将两个布尔矩阵相乘。

简单地执行A*AA^2 会返回一个Int64 矩阵。

有没有办法有效地乘法布尔矩阵?

【问题讨论】:

  • 你想要元素明智的乘法吗?布尔矩阵的矩阵乘法应该返回Int的矩阵。
  • 我需要布尔矩阵乘法,如此处所述en.wikipedia.org/wiki/Boolean_matrix。 IE。 AB[i,j] = any([A[i,k] & B[k,j] for k in 1:N]) 其中 N 是被相乘的索引的大小。
  • Julia 没有内置函数(这不是标准)。也就是说,您基本上可以在您刚刚编写的内容周围放置 2 个 for 循环,您将获得一个有效的方法。 (特别是如果您使用 LoopVectorization 进行循环)。

标签: boolean julia matrix-multiplication


【解决方案1】:

按照 Oscar 的评论,在代码周围添加两个 for 循环,但没有改进 LoopVectorization,尽管没有在 any 调用内分配完整数组(因此 any 在第一次出现时停止),这相当快(编辑:用短路 && 替换标准 AND &):

function bool_mul2(A, B)
    mA, nA = size(A)
    mB, nB = size(B)
    nA ≠ mB && error()
    AB = BitArray(undef, mA, nB)
    for i in 1:mA, j in 1:nB
        AB[i,j] = any(A[i,k] && B[k,j] for k in 1:nA)
    end
    AB
end

(请注意,我删除了 any 中的 [] 以不在那里分配。

例如,AB 大小为 1000×1000,我得到

julia> @btime bool_mul2($A, $B) ;
  16.128 ms (3 allocations: 122.25 KiB)

相比

julia> @btime bool_mul($A, $B) ;
  346.374 ms (12 allocations: 7.75 MiB)

编辑:对于矩阵求平方,也许可以尝试

function bool_square(A)
    m, n = size(A)
    m ≠ n && error()
    A² = BitArray(undef, n, n)
    for i in 1:n, j in 1:n
        A²[i,j] = any(A[i,k] && A[k,j] for k in 1:n)
    end
    A²
end

我得到的

julia> A = rand(Bool, 500, 500) ;

julia> @btime $A * $A .!= 0 ;
  42.483 ms (12 allocations: 1.94 MiB)

julia> @btime bool_square($A) ;
  4.653 ms (3 allocations: 30.69 KiB)

【讨论】:

  • 假设矩阵是rand(Bool, 1000, 1000),我认为你必须等待比宇宙年龄更长的时间才能得到不是trues(1000, 1000)的答案。虽然即使大小为 10x10,但使用 any 提前停止(我相信平均经过 3 步之后)似乎比使用 @avx 的完整循环更快。
  • 我需要有效地乘以稀疏矩阵,因为我想实现 Seidel's algorithm 来计算未加权无向稀疏图的 APSP,以改进现有的 LightGraphs.jl 算法。对大小为 500x500 的稀疏邻接矩阵求平方实际上需要大约 700 毫秒,这比整数乘法 (50 毫秒) 慢得多。
  • 好吧,如果它是稀疏的,我认为A * A .≠ 0 会更快。
【解决方案2】:

一个非常简单的解决方案是

function bool_mul(A,B)
    return A*B .!= 0
end

这不是最有效的,因为它会为A*B 分配一个矩阵,但最终可能会成为可用的最快解决方案之一。

【讨论】:

  • 我想这可能确实是关于稀疏矩阵时间的最佳解决方案。对于空间问题,使用any 使用嵌套循环可能更方便,这对于密集矩阵来说更方便。
猜你喜欢
  • 2013-11-29
  • 2015-06-17
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
相关资源
最近更新 更多