# ComponentArrays.jl with NLopt.jl

**URL:** https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482
**Category:** Optimization (Mathematical)
**Tags:** nlp, componentarrays
**Created:** [March 18, 2021, 3:44pm UTC](https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482 "2021-03-18T15:44:35Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![avonmoll](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avonmoll/32/17599_2.png) [@avonmoll](https://discourse.julialang.org/u/avonmoll)
#### Post date: [March 18, 2021, 3:44pm UTC](https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482/1 "2021-03-18T15:44:35Z")

</div>

These two packages seem to be incompatible. Without fully understanding the internals of NLopt.jl it seems that the vector of optimization variables ends up getting cast as an `Array{Float64,1}`. This basic snippet works:

```julia
using NLopt
function rosenbrock(x)
    (1 - x[1])^2 + 100*(x[2] - x[1]^2)^2
end

function rosenbrock(x, grad)
    if length(grad) > 0
        grad[1] = -400 * x[1] * (x[2] - x[1]^2) - 2 * (1 - x[1])
        grad[2] = 200 * (x[2] - x[1]^2)
    end
    rosenbrock(x)
end

opt = NLopt.Opt(:LD_SLSQP, 2);
opt.lower_bounds = [0., -0.5];
opt.upper_bounds = [1., 2.];
opt.min_objective = rosenbrock;

guess = [0.5, 0.];
(minf,minx,ret) = NLopt.optimize(opt, guess);
println("evals = $(opt.numevals)");
println("got $minf at $minx with constraints (returned $ret)");

```

But when I specify the `rosenbrock` function to work on ComponentArrays, it does not work (I get `:FORCED_STOP`):

```julia
using ComponentArrays
function rosenbrock(x)
    (1 - x.arg1)^2 + 100*(x.arg2 - x.arg1^2)^2
end
...
...
guess = ComponentArray(arg1=.5, arg2=0.)

```

Even when I pass this ComponentArray in as the initial vector, the `NLopt.optimize` function always returns `Array{Float64,1}`.

It would be great if it were possible to utilize ComponentArrays.jl within NLopt.jl. I’m solving optimization problems with 10’s or 100’s of optimization variables. Each specific problem I work on thus requires slicing the `x` vector with carefully constructed ranges in order to make sense of anything. With ComponentArrays.jl, I can store everything in a `ComponentArray` which appears as a flat array but can also be accessed via problem-specific field names.

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [March 18, 2021, 4:20pm UTC](https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482/2 "2021-03-18T16:20:10Z")

</div>

You can write a function that changes the vector to a component vector and call this function first thing in your objective before proceeding with the rest of your objective definition.

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [March 18, 2021, 6:30pm UTC](https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482/3 "2021-03-18T18:30:40Z")

</div>

I believe NLopt is a C/C++ library, hence they have no idea about fancy array types and only work with `Array{Float64}` and perhaps `Float32`. If you call C-code, you will probably have to do the conversion yourself like Mohamed suggests.

---

<div class="post-metadata">

### Author: ![jonniedie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonniedie/32/12842_2.png) [@jonniedie](https://discourse.julialang.org/u/jonniedie)
#### Post date: [March 24, 2021, 2:08pm UTC](https://discourse.julialang.org/t/componentarrays-jl-with-nlopt-jl/57482/4 "2021-03-24T14:08:38Z")

</div>

Doing it the way Mohamed suggests is a good way to go. The `getaxes` function from ComponentArrays will help here. This is what I usually do in situations like that:

```julia
guess = ComponentArray(arg1=.5, arg2=0.)
ax = getaxes(guess)

rosenbrock(x) = rosenbrock(ComponentArray(x, ax))
rosenbrock(x::ComponentArray) = (1 - x.arg1)^2 + 100*(x.arg2 - x.arg1^2)^2

```

Another option is to use a native Julia solver from Optim.jl, which will let ComponentArrays pass through just fine. I like using GalacticOptim.jl for a standard interface to all solvers, so here’s how I’d do it in GalacticOptim with an Optim solver:

```julia
using ComponentArrays, GalacticOptim

function rosenbrock(x, p)
    (p.a - x.arg1)^2 + p.b*(x.arg2 - x.arg1^2)^2
end

guess = ComponentArray(arg1=0.5, arg2=0)
lb = ComponentArray(arg1=0, arg2=-0.5)
ub = ComponentArray(arg1=1.0, arg2=2)

params = (a=1, b=100)

opt_fun = OptimizationFunction(rosenbrock, GalacticOptim.AutoForwardDiff())
prob = OptimizationProblem(opt_fun, guess, params; lb=lb, ub=ub)

sol = solve(prob, Fminbox(BFGS()))

```
