No matching method error after using range

Hello,

The last line of my code returns the following error, but both appear to be matrixes. I cannot seem to figure out what is wrong?

MethodError: no method matching +(::Float64, ::Matrix{Float64})
For element-wise addition, use broadcasting with dot syntax: scalar .+ array
Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/operators.jl:655
  +(::Union{Float16, Float32, Float64}, ::BigFloat) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/mpfr.jl:413
  +(::AbstractFloat, ::Bool) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/bool.jl:172
  ...
zstar=mew/(1-ρ); #expected value of z

#stddev of z
σz=σ/sqrt(1-ρ^2); 
  
#fill in along real line: 
lnzg = zstar.*ones(nz,1) + range(start = -q.*σz,stop=q.*σz,length=nz);

The RHS of + sign looks like:

2-element LinRange{Matrix{Float64}, Int64}:
 [-0.00367698 -302.609; -0.00370377 -302.609; … ; -360.943 -750.157; -387.051 -780.339],…,[0.00367698 302.609; 0.00370377 302.609; … ; 360.943 750.157; 387.051 780.339]

And the LHS of + sign looks like:

2×1 Matrix{Float64}:
 0.0
 0.0

Hi @ejlongman , welcome to the community.

Did you try to add the .+ as suggested in the error message?

Your RHS is not a matrix, but a Vector of Matrices, see this example:

julia> rhs = range( start=[1.0 1.0],stop=[2.0 2.0],length=2)
2-element LinRange{Matrix{Float64}, Int64}:
 [1.0 1.0],[2.0 2.0]

julia> collect(rhs)
2-element Vector{Matrix{Float64}}:
 [1.0 1.0]
 [2.0 2.0]

Each element of this vector/list is a:

julia> collect(rhs)[1]
1×2 Matrix{Float64}:
 1.0  1.0

With that, the +operator is not well defined, even .+ will not work I guess.

The range you are constructing, do you want this to be a row by row range, like in

julia> [1.0 1.0; 2.0 2.0]
2×2 Matrix{Float64}:
 1.0  1.0
 2.0  2.0

or do you want this to be a column to column range like in:

julia> [1.0 2.0; 1.0 2.0]
2×2 Matrix{Float64}:
 1.0  2.0
 1.0  2.0

From my example above:

julia> rhs = range( start=[1.0 1.0],stop=[2.0 2.0],length=2)
2-element LinRange{Matrix{Float64}, Int64}:
 [1.0 1.0],[2.0 2.0]

you can create the column to column matrix with:

julia> reshape(collect(Iterators.flatten(rhs)),(2,2))
2×2 Matrix{Float64}:
 1.0  2.0
 1.0  2.0

To make it a row to row matrix, you can use:

julia> collect(reshape(collect(Iterators.flatten(rhs)),(2,2))')
2×2 Matrix{Float64}:
 1.0  1.0
 2.0  2.0

Both transformations are perhaps not best practice, but for now I can’t find something shorter.

Combining row-wise can also be done via

julia> rhs = range( start=[1.0 1.0],stop=[2.0 2.0],length=2)
2-element LinRange{Matrix{Float64}, Int64}:
 [1.0 1.0],[2.0 2.0]

julia> reduce(vcat, rhs)
2×2 Matrix{Float64}:
 1.0  1.0
 2.0  2.0

For your original problem, you can use double broadcasting

julia> lhs = reshape([2, 3], 2, 1)
2×1 Matrix{Int64}:
 2
 3

julia> (.+).(lhs, rhs)
2×1 Matrix{Matrix{Float64}}:
 [3.0 3.0]
 [5.0 5.0]

or

julia> (.+).(Ref(lhs), rhs)
2-element Vector{Matrix{Float64}}:
 [3.0 3.0; 4.0 4.0]
 [4.0 4.0; 5.0 5.0]

depending on what exactly you want to do.

1 Like

Thank you so much everyone! The issue was the dimensions of my vector.