# JuMP optimization with vector input and analytical gradient

**URL:** <https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664>\
**Category:** Optimization (Mathematical)\
**Tags:** question, package, jump\
**Created:** [June 27, 2021, 9:14pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664 "2021-06-27T21:14:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [June 27, 2021, 9:14pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/1 "2021-06-27T21:14:29Z")

</div>

In JuMP’s manual, there are simple instructions to either optimize by providing an analytical gradient function or by providing a vector input with splatting: [Nonlinear Modeling · JuMP](https://jump.dev/JuMP.jl/dev/manual/nlp/#User-defined-functions-with-vector-inputs). I have been trying to combine the two but my efforts have been in vain thus far. Is it possible to do it? I am specifically trying to minimize a sum of Rosenbrock functions and specifically using JuMP for benchmarking. But just a small toy example to get me started would be appreciated. Thanks in advance.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 27, 2021, 9:20pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/2 "2021-06-27T21:20:17Z")

</div>

Docs:  
[https://jump.dev/JuMP.jl/stable/manual/nlp/#Multivariate-functions](https://jump.dev/JuMP.jl/stable/manual/nlp/#Multivariate-functions)

I guess you want something like the following (I have not run, there may be typos, etc.):

```julia
f(x...) = (x[1] - 1)^2 + (x[2] - 2)^2
function ∇f(g::Vector{T}, x::T...) where {T}
    g[1] = 2 * (x[1] - 1)
    g[2] = 2 * (x[2] - 2)
    return
end
model = Model()
register(model, :my_square, 2, f, ∇f)
@variable(model, x[1:2] >= 0)
@NLobjective(model, Min, my_square(x...))

```

You should also read:  
[https://jump.dev/JuMP.jl/stable/background/should\_i\_use/#Black-box,-derivative-free,-or-unconstrained-optimization](https://jump.dev/JuMP.jl/stable/background/should_i_use/#Black-box,-derivative-free,-or-unconstrained-optimization)  
There are other tools in Julia that may be more suited if you have an unconstrained problem.

---

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [June 27, 2021, 10:20pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/3 "2021-06-27T22:20:25Z")

</div>

Thanks a lot for the quick answer. Yes I’ve been trying variations around your suggestion, but I ran into the same error message:

```julia
ERROR: MethodError: no method matching ∇f(::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}, ::Float64, ::Float64)
Closest candidates are:
  ∇f(::Vector{T}, ::T...) where T at REPL[5]:1
Stacktrace:
  [1] (::JuMP.var"#148#151"{typeof(∇f)})(g::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}, x::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true})
...

```

But actually, you solved my problem in another way, because I’ve realized that indeed, NLopt is much better suited for my needs so that’s what I’ll be using. So no need to persist trying to do it with JuMP.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 27, 2021, 10:36pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/4 "2021-06-27T22:36:08Z")

</div>

Ah. That’s a bug in the documentation. The example should read (note the `AbstractVector`):

```nohighlight
using JuMP, Ipopt
f(x...) = (x[1] - 1)^2 + (x[2] - 2)^2
function ∇f(g::AbstractVector{T}, x::T...) where {T}
    g[1] = 2 * (x[1] - 1)
    g[2] = 2 * (x[2] - 2)
    return
end
model = Model(Ipopt.Optimizer)
register(model, :my_square, 2, f, ∇f)
@variable(model, x[1:2] >= 0)
@NLobjective(model, Min, my_square(x...))
optimize!(model)

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 27, 2021, 10:39pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/5 "2021-06-27T22:39:22Z")

</div>

I opened an issue: [User-defined gradients need to accept AbstractVector · Issue #2638 · jump-dev/JuMP.jl · GitHub](https://github.com/jump-dev/JuMP.jl/issues/2638). Apologies for the confusion!

---

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [June 27, 2021, 10:58pm UTC](https://discourse.julialang.org/t/jump-optimization-with-vector-input-and-analytical-gradient/63664/6 "2021-06-27T22:58:11Z")

</div>

It worked! thanks a lot for the help.
