Search code examples
functionoptimizationjuliaminimizeminimization

Optimization in Julia with Optim.jl - How do I get rid of this error?


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.


Solution

  • 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 (Optim.jl/stable/#user/minimization/) 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)