Sounds like you’re not trying to add a dimension at all, but instead convert a 1D array of 2D arrays into a 4D array, with the first dimension corresponding to the outer array, and the last dimension being 1. The following isn’t pretty and it isn’t general, but it will do exactly that:
function toconvkernel(A::AbstractArray{<:AbstractMatrix})
s = size(first(A))
@assert all(==(s), size.(A))
B = Array{eltype(eltype(A)), 4}(undef, length(A), s..., 1)
for (i, a) in enumerate(A)
B[i, :, :, 1] = a
end
B
end
hello, thank you but its not working
i tried with: LoadError: “can’t use index 25701 on LHS for a new array” @tullio B[25701, 100, 40, 1] := $x[25701][100, 40]
but it would be way better if it is a faster method compared to the other 2
the first returns: MethodError: no method matching toconvkernel(::Array{Any,1})
@contradict
even though it is slow and occupy a lot of memory it is working, thanks:
result: 25701×100×40×1 Array{Float64,4}:
The index letters in these einsum-like expressions are loop variables, not sizes. It should run literally as written (although without the dollar sign) if A is your vector of matrices:
Ordering things @tullio B[j, k, 1, i] := A[i][j, k] should be faster – the last index of Julia’s arrays is the biggest step in memory.
There are also many ways to make array-like views of all the slices, LazyStack.jl or JuliennedArrays.jl are two small packages for exactly this, and SplitApplyCombine.jl as mentioned seems to also include this.
I defined toconvkernel as taking in an array with element type <:AbstractMatrix and you seem to have Array{Any, 1} (the eltype is Any) instead. You can remove the type annotation from the function definition, but it would be better to have your array not be an array of Any in the first place. Wherever you create that, it would be better to make sure it is strictly typed.