2
votes

I am new to Julia and the REPL answers seems strange to me:

When I run this uncorrect code :

mat = [1 2 3; 4 5 6]

function minus(mat::Array{Int64,2}, min)::Array{UInt8,2}
    out = mat-min;
    # out = UInt8.(out);
    return out;
end

minmat = minus(mat);

I get this correct error message :

ERROR: LoadError: MethodError: no method matching minus(::Array{Int64,2})
Closest candidates are:
  minus(::Array{Int64,2}, ::Any) at /home/hugo/dev/julia/test.jl:5

But when I run this correct (I guess) code :

mat = [1 2 3; 4 5 6]

function minus(mat::Array{Int64,2}, min)::Array{UInt8,2}
    out = mat-min;
    # out = UInt8.(out);
    return out;
end

minmat = minus(mat, 1);

Julia gives me this incorrect error message :

ERROR: LoadError: MethodError: no method matching -(::Array{Int64,2}, ::Int64)
Closest candidates are:
  -(::Complex{Bool}, ::Real) at complex.jl:298
  -(::Missing, ::Number) at missing.jl:93
  -(::Base.CoreLogging.LogLevel, ::Integer) at logging.jl:107
  ...

(notice the '-' in the function signature)

I see nothing related to this in the doc, so I am a bit confused, that's why I'm asking here.

2

2 Answers

4
votes

You try to subtract a scalar from an array. You need to vectorize this operation with the dot operator.

function minus(mat::Array{Int64,2}, min)::Array{UInt8,2}
    out = mat .- min;
    # out = UInt8.(out);
    return out;
end

Now running this function yields:

julia> minmat = minus(mat, 1)
2×3 Array{UInt8,2}:
 0x00  0x01  0x02
 0x03  0x04  0x05

Note that your argument is an Array of Int64 while you want the result to be UInt8. Your function call can easily end with an InexactError when the values will be out of bounds.

4
votes

The method error is not for your minus function, but is actually being generated by the line out = mat-min. Given x::Matrix{Int} and y::Int, Julia does not have a method for x - y. To see this, just paste the following in your REPL:

[1 2 ; 3 4] - 5

If the behaviour you desire is to subtract min from every element of mat, then what you really want to do is broadcast the min argument. That is, use:

out = mat .- min

Given this change, your function will now work as I suspect you intended.