# Abstract Type Number does´t recognize Int64 as suitable type

I have to question to the following code:

1. I get an MethodError message if I run the code below:
“LoadError: MethodError: no method matching ox1(::Array{Int64,2}, ::Array{Int64,2})”
But actually I don´t understand why, because Int64 is a subtype of Number. What I´m doing wrong?

2. Is there a way that randperm returns an array of size Array{Int64,2} instead of reshaping it? Or how can I code my methods that they work on both Array{Number,1} and Array{Number,2} without overloading the method and without performance loss?

``````using Random
using Crossover

# Order crossover
v1 = reshape(randperm(2000), 2000, 1)
v2 = reshape(randperm(2000), 2000, 1)

@time c1, c2 = Crossover.ox1(v1, v2)

module Crossover

# Order crossover
function ox1(v1::Array{Number,2}, v2::Array{Number,2})
s = length(v1)
from, to = rand(1:s, 2)
# while from == to
#     from, to = rand(1:s, 2)
# end
from, to = from > to ? (to, from)  : (from, to)

c1 = zeros(Int64, size(v1))
c2 = zeros(Int64, size(v2))
# Swap
c1[from:to] = v2[from:to]
c2[from:to] = v1[from:to]
# Fill in from parents
k = to+1 > s ? 1 : to+1 #child1 index
j = to+1 > s ? 1 : to+1 #child2 index
for i in vcat(to+1:s,1:from-1)
while in(v1[k],c1)
k = k+1 > s ? 1 : k+1
end
c1[i] = v1[k]
while in(v2[j],c2)
j = j+1 > s ? 1 : j+1
end
c2[i] = v2[j]
end
return c1, c2
end

end``````

Try `ox1(v1::Array{<:Number,2}, v2::Array{<:Number,2})`. Then the concrete type can match the prescribed argument type.

3 Likes

Are you sure that you even need those type signatures? Now, you are disallowing most types of matrices, only the standard `Array{..., 2}` matrix type will work. No symmetric or sparse matrices, no transposed matrices, etc. etc.

Maybe you should use `AbstractMatrix` instead? Or maybe even drop the whole signature?

1 Like

I´m not sure. I´m a beginner in julia. I just know, that the method will only and should only works on permutations. So one dimensional vectors. But I don´t know when a method return arrays as Array{…,2} or Array{…,1}. Furthermore i.e. the permutation array is just one array of multiple arrays, which are gathered in another array (see the code eyample below). This is the reason why choose Number and not Int64. I read the performance of the code should be better if not so many types have to be supported. So Any or AbstractMatrix would be slower than Array{Number,2}?

Example:

``````parms::Array{Array{Number,2},1}

parms = [FloatArray, IntegerArray, PermutationArray, ...]``````

The function type signature makes no difference for performance, it just limits what sort of inputs that will be accepted. `AbstractMatrix` will be exactly as fast as just `Matrix`, because the compiled codes are identical. You can just drop the signature completely and get precisely the same performance.

This is a bit confusing, your code seems to work on matrices, not vectors.

2 Likes

This is really good to know I´m looping over it. Parms is more a list of arrays. I.e. with `parms` you will get the FloatArray, which for example a vector of random float numbers and with `parms` you will get the PermutationArray, which contains a permutation of a vector. They are separate parameters, which will be optimized by an evolutionary algorithm

Ah, ok. If you know and require that each element should be a matrix, then perhaps a good function signature would be

``````function ox1(v1::AbstractMatrix, v2::AbstractMatrix)
``````

I wouldn’t bother with specifying number types, unless you have several different versions of `ox1` with different behaviours for different types of numbers.

I see something odd in your code, though:

``````c1 = zeros(Int64, size(v1))
c2 = zeros(Int64, size(v2))
# Swap
c1[from:to] = v2[from:to]
c2[from:to] = v1[from:to]
``````

This will only work if `v1` and `v2` contain numbers that can be converted to `Int`, such as `2.0`, `6//2`, `3+0im` etc. Is this really what you want? It will fail in most cases, apparently.

ox1 is the order crossover 1. It creates with two parent permutations two child permutations, which have genes of their parents. So the method is just suited for permutations, which are in integer.

In that case, I would consider limiting the types of the matrix elements.

If the algorithm makes no sense except for integers it can be nice to make that clear by only defining the function for the right kind of types. It’s not necessary, but it can make it clearer to the user what’s going on. If you allow `Number`, you sort of signal to the user that the algorithm makes sense for all kinds of numbers.

For example:

``````function ox1(v1::AbstractMatrix{<:Integer}, v2::AbstractMatrix{<:Integer})
``````

and then

``````c1 = zero(v1)
c2 = zero(v2)
``````

I recommend `Matrix` over `Array{..., 2}` because it’s more readable, but means the same thing.

1 Like

Thanks for your help. I allowed number, because parms is `Array{Array{Number, 2}, 1}`. I will try your advises, thanks.