Proper parameter type for a scalar or array of numbers


#1

I’m using JuliaPro 0.6.2.

In numerical algorithms for engineering, I often write functions with input parameters that could be a scalar or an Array (1D Vector or 2D Matrix) of any kind of Number - it could be Int, Real, or Complex. However, the actual operations inside the function are identical for any one of these input types with the use of broadcast “dot” operators (for example .* instead of *).

I would like to specify the type of such input parameters for better execution speed and for catching a type mismatch bug a bit earlier.

I can force the use of Complex always, but it’s a waste of memory in most cases, and those who use my function would naturally assume an integer or a floating number will be accepted as the special cases of a complex number. While true in math, such assumption will lead to type mismatch errors in Julia.

I know I can create a Union of all the specific types I want, but I feel that a simpler way must exist.

For a scalar, things are easy. Just specifying the type Number would do, because Int, Real, and Complex are all subtypes of Number.

I then assumed Array{Number} would accept a 1D or 2D array of any kind of number. I only need to specify Union{Number, Array{Number}} and my problem is solved.

How wrong! I later found out that none of Array{Int}, Array{Real}, and Array{Complex} is a subtype of Array{Number} regardless of the fact that Int, Real, and Complex are all subtypes of Number.

Actually Array of any types T1 and T2, as long as T1 and T2 are not identical, seems to be unrelated. So even if I specify Array{Real}, an input of Array{Float64} will cause a mismatch, even though Float64 <: Real!

In fact, I tried typejoin(Array{Real}, Array{Float64}), and simply got Array as the return.

I don’t like the idea of defining a custom type Union of tons of Array types with elements in many various number types (especially considering Complex is also a composite type that can have various number types as its real and imaginary parts).

So the best I can do for now is to use Union{Number, Array} as my input parameter type. Even of someone pass in an Array{String} I have to accept it first and let it fail run-time in the function code, because I don’t know how to elegantly create an Array of any Number type. :confounded:

I must have missed something. Can anybody help? Thanks!!!


#2

Array{Real} does not mean what I think you think it means. See this section of the manual: https://docs.julialang.org/en/stable/manual/types/

You are most likely looking for something like Array{<:Real} or even better AbstractArray{<:Real}.


#3

Thanks a lot!!! I knew I must have missed something… Will read the document again more carefully.

Since we are on this topic, what’s the advantage of AbstractArray{<:Real} versus Array{<:Real}?


#4

There are more entities available to AbstractArray than to Array.
(AbstractArray is an abstraction of many sorts of array, including Array)


#5

OK, thanks Jeffrey!