# Nonlinear Constraints with Splatting

**URL:** <https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [January 29, 2018, 6:49pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677 "2018-01-29T18:49:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![shoshievass](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoshievass/32/3260_2.png) [@shoshievass](https://discourse.julialang.org/u/shoshievass)\
**Post date:** [January 29, 2018, 6:49pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/1 "2018-01-29T18:49:40Z")

</div>

I’m trying to solve an optimization problem w/ (N+1) parameters subject to a set of N nonlinear constraints, each of which relies on the whole vector of the parameters.

A simplified version of my problem looks like this:

@variables m begin  
q\_b[i=1:N] \>= 0.  
0 \<= gamma \<= 0.001  
end

m = Model(solver=IpoptSolver(print\_level=0, tol=1e-5))

@NLobjective(m, Min, sum((q\_b[i])^2 for i in 1:N)))

function my\_constraint\_i(q\_b\_index, gamma, q\_b\_arr…)  
q\_b = [q\_b\_arr…]

```
exp_of_sum = exp(gamma * (dot(q_b, X))) ## X is an N-d vector of data

lhs = q_b[q_b_i] 
rhs = exp_of_sum * y ## y is another N-d vector data

constraint_i = lhs - rhs

return constraint_i

```

end

JuMP.register(m, :constraint\_i, (2+N), constraint\_i, autodiff=true)

When I try to use the constraint macros, I get a method error complaining that it can’t parse the inputs:

foc\_constraint = @NLexpression(m, [i=1:length(q\_a)], foc\_constraint\_i(index\_vector[i], gamma, q\_b…) )  
@NLconstraint(m, [i=1:length(q\_a)], foc\_constraint[i] == 0)

Note, however that if I listed the vars, q\_b[1], q\_b[2], etc. it does work.

I saw the thread on using splatting w/ user defined functions [here](https://discourse.julialang.org/t/passing-an-array-of-variables-to-a-user-defined-non-linear-function/4132) and [here](https://stackoverflow.com/questions/44710900/juliajump-variable-number-of-arguments-to-function/44711305#44711305) but I’m a novice and haven’t been able to adapt the solutions to my problem. Any help would be tremendously appreciated.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 29, 2018, 8:08pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/2 "2018-01-29T20:08:14Z")

</div>

I’m having a little trouble parsing what you’re doing here, and I’m not sure where your error is coming from, but one suggestion is that you can easily consolidate this code somewhat (I’m pretty sure you don’t need splatting at all, though I feel like I’m missing something about what you’re doing…). For example, you can simply specify your objective as

```julia
@NLobjective(m, Min, sum(q_b.^2))

```

and your constraint as

```julia
@NLconstraint(m,
             exp(γ*q_b⋅X)*y .== q_b
             )

```

(I think I’m reading that right, is that the correct constraint?). The unicode is me being fanciful, but I wanted to advertise how beautifully these types of problems can be written in Julia. You might try the above using the `@constraint` macro and see if this fixes your problem.

(By the way, if I am getting this wrong it might be helpful if you write your problem down in latex, which you can do in discourse using $.)

---

<div class="post-metadata">

**Author:** ![shoshievass](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoshievass/32/3260_2.png) [@shoshievass](https://discourse.julialang.org/u/shoshievass)\
**Post date:** [January 29, 2018, 8:20pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/3 "2018-01-29T20:20:59Z")

</div>

Thanks for the response! The trouble is that I need to have N constraints (one for each element of q\_b). The reason I’m using splatting is so that I write the constraint function as a function of scalars that I can register (i.e. `JuMP.register(m, :constraint_i, (2+N), constraint_i, autodiff=true)`).

In my understanding, registered functions can only be scalar functions, but I need the entirety of the q\_b vector for each constraint, so I need to use splatting to input each element of the vector as a separate variable. 😕

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 29, 2018, 8:24pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/4 "2018-01-29T20:24:16Z")

</div>

What I have written above _is_ N constraints (that’s the glory of JuMP and Julia, see [here](https://docs.julialang.org/en/stable/manual/mathematical-operations/#man-dot-operators-1)).

Let me continue to give the caveats that 1. I’m still not sure I’m understanding your problem correctly and 2. there may be some subtlety or trick for `@NLconstraint` beyond what you’d need to do for `@constraint` that I’m not aware of at this very moment.

---

<div class="post-metadata">

**Author:** ![shoshievass](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoshievass/32/3260_2.png) [@shoshievass](https://discourse.julialang.org/u/shoshievass)\
**Post date:** [January 29, 2018, 8:29pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/5 "2018-01-29T20:29:01Z")

</div>

Ah right, sorry - the constraint in my problem is a bit more complicated than that but I can try to vectorize it…

Assuming I do need to use splatting (say, because I need to do several transformations of `q_b` inside the function), my error seems to be from JuMP not parsing `q_b...` as `q_b[1], q_b[2], ...`. It seems like a similar problem has been dealt with in the threads I linked to wrt nonlinear functions in the objective, but not in the constraints…

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 29, 2018, 8:34pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/6 "2018-01-29T20:34:48Z")

</div>

It seems highly unlikely to me that you would need to resort to splatting, but it’s hard to say for sure. I could take another stab at what I think your problem is, but if we have to go that route it’s probably just best for you to write it out algebraically. My best advice at the moment is to formulate your problem in such a way that it doesn’t require splatting (which is inefficient anyway). It must be possible to write it succinctly and put into one or more `@NLconstraint`s like I’ve shown above.

---

<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:** [January 29, 2018, 8:58pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/7 "2018-01-29T20:58:53Z")

</div>

Please:

1. Quote your code using triple backticks as described in [PSA: how to quote code with backticks](https://discourse.julialang.org/t/psa-how-to-quote-code-with-backticks/7530) to make it more readable, and
2. Provide enough data in your code to run it by just copying and pasting it to help people to help you.

Adapting the solution from the link you posted, in particular, the comment below, you can try:

```julia
foc_constraint = @eval @NLexpression(m, [i=1:length(q_a)], foc_constraint_i(index_vector[i], gamma, $(q_b...)))

```

It seems that the `@NLconstraint` macro cannot parse the splatting because it works when you manually splat, so you can intercept the expression by the `@eval` macro to “pseudo-manually” splat `q_b` for you before passing the expression to the `@NLconstraint` macro to do its magic on the splatted version. I didn’t test this solution because of point 2 above, so I may very well be wrong.

> [@Passing an array of variables to a user-defined non-linear function](https://discourse.julialang.org/t/passing-an-array-of-variables-to-a-user-defined-non-linear-function/4132/6):
>
> Perhaps what you are looking for can be achieved with @eval. For example, taking n = 3, the code looks like: m = Model(solver=IpoptSolver(print\_level=0)) n=3 @variable(m, 0 \<= x[1:n] \<= 1) f(x...) = rand() df(g,x...) = g[:] = rand(n) JuMP.register(m, :obj, n, f, df) The problematic @NLobjective could be specialized for n=3 as: @NLobjective(m, Max, obj(x[1],x[2],x[3])) and this would work. To make it work for other n defined at runtime, we could build-up this expression and @eval it, as foll…

Also consider doing away with this pattern completely if you can as @ExpandingMan mentioned because it simply looks ugly in my opinion and Julia gives you plenty of tools to make your code look elegant and often even be simultaneously more efficient.

---

<div class="post-metadata">

**Author:** ![shoshievass](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoshievass/32/3260_2.png) [@shoshievass](https://discourse.julialang.org/u/shoshievass)\
**Post date:** [January 29, 2018, 9:47pm UTC](https://discourse.julialang.org/t/nonlinear-constraints-with-splatting/8677/8 "2018-01-29T21:47:05Z")

</div>

Thank you very much, @ExpandingMan and @mohamed82008. That was really helpful. I think the `@eval` trick solves my current problem but I’m going to see if I can refactor the way I’m approaching it.
