Julia 中的布尔矩阵乘法

Boolean matrix multiplication in Julia

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

只做 A*AA^2 returns Int64 矩阵。

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

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

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

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

根据 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 中的 [] 以不在那里分配。

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

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)