I have two Matrix{Vector{}}
, say A
and B
, of the same sizes. I want to get a Matrix{Matrix{}}
, M
, such that each element is an outer sum of each element of A
and B
, i.e.
M[i, j][k, l] = A[i, j][k] + B[i, j][l]
.
How could I vectorize the above operation?
Example case:
A=[[[1, 2]] [[3, 4]] ; [[5, 6]] [[7, 8]]]
2×2 Matrix{Vector{Int64}}:
[1, 2] [3, 4]
[5, 6] [7, 8]
B=[[[11, 21]] [[13, 44]] ; [[25, 61]] [[27, 28]]]
2×2 Matrix{Vector{Int64}}:
[11, 21] [13, 44]
[25, 61] [27, 28]
size(A)==size(B)
true
M=[A[i, j] .+ B[i, j]' for i in 1:size(A)[1], j in 1:size(A)[2]]
2×2 Matrix{Matrix{Int64}}:
[12 22; 13 23] [16 47; 17 48]
[30 66; 31 67] [34 35; 35 36]
I would love to find a way for avoiding the for
loop, since in my use case, A
and B
are huge matrices! I also tried A .+ adjoint.(B)
but this throws an error message:
ERROR: DimensionMismatch: dimensions must match: a has dims (Base.OneTo(1), Base.OneTo(2)), b has dims (Base.OneTo(2),), mismatch at 1
.
I found a workaround using the TensorCast package which looks something like
@cast MCast[i, j][k, l] := A[i, j][k] + B[i, j][l];
julia> MCast = collect(MCast);
julia> MCast
2×2 Matrix{SubArray{Int64, 2, Array{Int64, 4}, Tuple{Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}, Int64, Int64}, true}}:
[12 22; 13 23] [16 47; 17 48]
[30 66; 31 67] [34 35; 35 36]
This does work, but I was wondering if there exists a more elegant way of doing this, preferably in native Julia.
julia> map(.+, A, adjoint.(B))
2×2 Matrix{Matrix{Int64}}:
[12 22; 13 23] [16 47; 17 48]
[30 66; 31 67] [34 35; 35 36]
is what I got so far.
Slight improvement:
using MappedArrays
map(.+, A, mappedarray(adjoint,B))
(does not materialize adjoint.(B)
)