I recently came across extending some of the numerical arrays that I work with along different axes and in different orders, and the repeat
function of Base using inner
and outer
came quite handy. However, it seems like the kron
function is extremely faster and more memory efficient. Is there any way that a more general function like repeat
use this functionality. I understand that the repeat is not limited to numerical arrays, but wouldn't it make sense to use this functionality?
function inner_repeat(
X::AbstractArray{T, 2},
K::Int64,
) where {T <: AbstractFloat}
return repeat(X, inner = (K, 1))
end
function inner_kron_repeat(
X::AbstractArray{T, 2},
K::Int64,
) where {T <: AbstractFloat}
return kron(X, ones(T, K, 1))
end
Xs = [rand(10^i, 10^i) for i in 2:4]
Ks = [i for i in 2:4]
for X in Xs
for K in Ks
println("matrix of size $(size(X)) with $(K) repeats")
println("using repeat:")
@btime inner_repeat($X, $K)
println("using kron:")
@btime inner_kron_repeat($X, $K)
println()
end
end
And the output results are as follows:
matrix of size (100, 100) with 2 repeats
using repeat:
933.659 μs (50003 allocations: 1.68 MiB)
using kron:
18.834 μs (3 allocations: 156.42 KiB)
matrix of size (100, 100) with 3 repeats
using repeat:
966.348 μs (50003 allocations: 1.75 MiB)
using kron:
21.505 μs (3 allocations: 234.56 KiB)
matrix of size (100, 100) with 4 repeats
using repeat:
996.305 μs (50003 allocations: 1.83 MiB)
using kron:
25.571 μs (3 allocations: 312.69 KiB)
matrix of size (1000, 1000) with 2 repeats
using repeat:
111.865 ms (5000003 allocations: 167.85 MiB)
using kron:
1.907 ms (3 allocations: 15.26 MiB)
matrix of size (1000, 1000) with 3 repeats
using repeat:
117.833 ms (5000003 allocations: 175.48 MiB)
using kron:
2.322 ms (3 allocations: 22.89 MiB)
matrix of size (1000, 1000) with 4 repeats
using repeat:
125.939 ms (5000003 allocations: 183.11 MiB)
using kron:
2.770 ms (3 allocations: 30.52 MiB)
matrix of size (10000, 10000) with 2 repeats
using repeat:
12.320 s (500000003 allocations: 16.39 GiB)
using kron:
631.530 ms (3 allocations: 1.49 GiB)
matrix of size (10000, 10000) with 3 repeats
using repeat:
12.887 s (500000003 allocations: 17.14 GiB)
using kron:
862.406 ms (3 allocations: 2.24 GiB)
matrix of size (10000, 10000) with 4 repeats
using repeat:
13.406 s (500000003 allocations: 17.88 GiB)
using kron:
1.098 s (3 allocations: 2.98 GiB)
kron
is not equivalent torepeat
, but is only equivalent to a few very special cases of repeat. It might be worth doing a performance PR for the specific case of repeat with inner specified, outer not specified, and inner with two parameters, the second one == 1. – Bill Apr 02 '20 at 18:55