newbie here

I'm trying to minimize a function in Julia with optim.jl. The function works, but when I try to optimize it it gives me this error message:

MethodError: no method matching -(::Float64, ::Array{Float64,1}) For element-wise subtraction, use broadcasting with dot syntax: scalar .- array Closest candidates are: -(::Float64, !Matched::Float64) at float.jl:403 -(::Float64) at float.jl:393 -(::Real, !Matched::Complex{Bool}) at complex.jl:302 ... Stacktrace: [1] _broadcast_getindex_evalf at ./broadcast.jl:648 [inlined] [2] _broadcast_getindex at ./broadcast.jl:621 [inlined] [3] getindex at ./broadcast.jl:575 [inlined] [4] copy at ./broadcast.jl:876 [inlined] [5] materialize at ./broadcast.jl:837 [inlined] [6] broadcast_preserving_zero_d at ./broadcast.jl:826 [inlined] [7] -(::Array{Float64,1}, ::Array{Array{Float64,1},1}) at ./arraymath.jl:39 [8] objective(::Array{Float64,1}) at ./In[147]:4 [9] value!!(::NonDifferentiable{Float64,Array{Float64,1}}, ::Array{Float64,1}) at /ext/julia/depot/packages/NLSolversBase/NsXIC/src/interface.jl:9 [10] initial_state(::NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Nothing}, ::NonDifferentiable{Float64,Array{Float64,1}}, ::Array{Float64,1}) at /ext/julia/depot/packages/Optim/TNmSw/src/multivariate/solvers/zeroth_order/nelder_mead.jl:158 [11] optimize(::NonDifferentiable{Float64,Array{Float64,1}}, ::Array{Float64,1}, ::NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Nothing}) at /ext/julia/depot/packages/Optim/TNmSw/src/multivariate/optimize/optimize.jl:33 [12] optimize(::Function, ::Array{Float64,1}; inplace::Bool, autodiff::Symbol, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /ext/julia/depot/packages/Optim/TNmSw/src/multivariate/optimize/interface.jl:64 [13] optimize(::Function, ::Array{Float64,1}) at /ext/julia/depot/packages/Optim/TNmSw/src/multivariate/optimize/interface.jl:58 [14] top-level scope at In[148]:3 [15] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091 

This is my code:

function objective(b) x = x1[:,2] b = fill(b,T) u = y - x.*b obj = sum(u.^2) return obj end using Optim Sol = optimize(objective,[0.0;0.0]) b_optim = Optim.minimizer(Sol) 

, where x and y are Array{Float64,1}

I don't understand this error message. If I understand it correctly, it tells me that I'm trying to subtract an array from a number, which I'm not doing?! Broadcasting also doesn't work.

15

2 Answers

You should add arguments to your function, so that you can be sure you're passing the right variables. Then you should not use fill(b,T) as it allocates a new array uselessly. Furthermore, if you have an univariate problem you should give to the solver only one variable and as written in the documentation () you should use another solver, like LBFGS().

Summing up this would look like:

using Optim function objective(b, x1, y) x = x1[:,2] u = y - x.*b obj = sum(u.^2) return obj end x1 = rand(10,10) y = rand(10) Sol = optimize(b -> objective(b,x1,y),[0.0], LBFGS()) b_optim = Optim.minimizer(Sol) 
7

You can replicate your error via:

julia> 4 - [2,5] ERROR: MethodError: no method matching -(::Int64, ::Array{Int64,1}) 

That it means is that your y is not a vector as expected but a scalar.

One possible way to address the issue is to broadcast -:

julia> 4 .- [2,5] 2-element Array{Int64,1}: 2 -1 

Another problem with your code already mentioned in comments are global variables. You should never do that due to type stability and performance. For sure now it is the time to read:

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.