I have a function that nominally accepts only 2-dimension arrays as input:
julia> function foo(x::Array{Float64, 2})
# Stuff
return nothing
end
foo (generic function with 1 method)
julia> y = rand(5, 6)
5×6 Array{Float64,2}:
0.818613 0.402175 0.141845 0.649995 0.622611 0.432664
0.368095 0.196203 0.235136 0.657062 0.281461 0.603284
0.962769 0.335103 0.875451 0.587475 0.620739 0.393967
0.957616 0.273278 0.740744 0.14692 0.792191 0.779481
0.95631 0.815702 0.961613 0.49849 0.188148 0.96158
julia> foo(y) # No error
But I sometimes want to call this function on the transpose of an array. This doesn’t work:
julia> foo(y')
ERROR: MethodError: no method matching foo(::LinearAlgebra.Adjoint{Float64,Array{Float64,2}})
Closest candidates are:
foo(::Array{Float64,2}) at none:1
Stacktrace:
[1] top-level scope at none:1
Instead, I have to do
julia> foo(permutedims(y)) # No error
Likewise, sometimes my array is just a column vector, and in such cases I would like it to be treated as a 2D array whose second dimension is 1
:
julia> z = rand(5)
5-element Array{Float64,1}:
0.373288007992006
0.971884387492479
0.8786393449999188
0.9435088229078494
0.570539122742798
julia> foo(z)
ERROR: MethodError: no method matching foo(::Array{Float64,1})
Closest candidates are:
foo(::Array{Float64,2}) at none:1
Stacktrace:
[1] top-level scope at none:1
julia> foo(reshape(z, 5, 1)) # No error
Now, I understand that I can explicitly allow adjoints and column vectors by modifying the function like so:
using LinearAlgebra
function foo(x::Union{Array{Float64,2},
Adjoint{Float64,Array{Float64,2}},
Array{Float64,1}})
if typeof(x) == Array{Float64,1}
x = reshape(x, :, 1)
end
return nothing
end
(In my real function, there are loops over both dimensions of x
, so the reshaping is necessary.)
But this is unsightly, and I am wondering if there is a better way to do this. Is there a type declaration that is equivalent to the following statement?
- “
x
should be an 2-dimensional array, or something that can be unambiguously interpreted as such”