No matching method error when adding 2d arrays

Viewed 62

I have the following method:

function Q(penalties::Array{Float64, 1}, Q::Array{Float64, 2})
    Q_ar = Array{Float64, 2}(undef, N+1, N+1)
    for r in 1:N+1
        Q_ar = Q_ar + penalties[r] * Q[r]
    end
    return Q_ar
end

That I'm calling, but I'm getting the following error:

(base.oneto(16), base.oneto(16))
error: loaderror: methoderror: no method matching +(::array{float64,2}, ::float64)
for element-wise addition, use broadcasting with dot syntax: array .+ scalar
closest candidates are:
  +(::any, ::any, !matched::any, !matched::any...) at operators.jl:538
  +(!matched::complex{bool}, ::real) at complex.jl:301
  +(!matched::missing, ::number) at missing.jl:115
  ...
stacktrace:
 [1] q(::array{float64,1}, ::array{float64,2}) at /users/prikshetsharma/documents/clotorch/src/clotorch/flight/trajectory.jl:42
 [2] top-level scope at /users/prikshetsharma/documents/clotorch/src/clotorch/flight/trajectory.jl:50
 [3] include(::function, ::module, ::string) at ./base.jl:380
 [4] include(::module, ::string) at ./base.jl:368
 [5] exec_options(::base.jloptions) at ./client.jl:296
 [6] _start() at ./client.jl:506
in expression starting at /users/prikshetsharma/documents/clotorch/src/clotorch/flight/trajectory.jl:50

How to fix this error? The error is occurring at the line:

Q_ar = Q_ar + penalties[r] * Q[r]

My intention is to add all the

penalties[r] * Q[r]

together, and return the result with the array Q_ar. What am I doing wrong?

1 Answers

First of all, you are preallocating memory without initialization. So instead of Q_ar = Array{Float64, 2}(undef, N+1, N+1) you need to write Q_ar = zeros(N+1, N+1) so that further addition to elements of Q_ar makes sense.

Then you are trying to add some number to the whole array. In Julia you can add number to number, array to array if their dimensions matches, but if you want to add a number to every element of an array you should use the broadcasting 1 .+ [1,2,3] instead of 1 + [1,2,3] which produces method error.

After that you're using strange global N which can cause some errors and type-instability. It is better to get size inside of a function n = length(penalties)

Finally your code will look like

function Q(penalties::Array{Float64, 1}, Q::Array{Float64, 2})
    n = length(penalties)
    Q_ar = zeros(n, n)
    for r in 1:n
        Q_ar .+= penalties[r] * Q[r]
    end
    Q_ar
end

But there are several questions to the sense of this code. You are making a matrix with similar elements, so why don't use fill(penalties ⋅ Q[:,1], (n, n)) because this part

    for r in 1:n
        Q_ar .+= penalties[r] * Q[r]
    end

is just computing inner product of penalties and Q[:,1]

Related