# Programmaticly build expression for JuMP NLconstraint

**URL:** <https://discourse.julialang.org/t/programmaticly-build-expression-for-jump-nlconstraint/34950>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, optimization\
**Created:** [February 21, 2020, 12:45am UTC](https://discourse.julialang.org/t/programmaticly-build-expression-for-jump-nlconstraint/34950 "2020-02-21T00:45:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacob-roth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacob-roth/32/1862_2.png) [@jacob-roth](https://discourse.julialang.org/u/jacob-roth)\
**Post date:** [February 21, 2020, 12:45am UTC](https://discourse.julialang.org/t/programmaticly-build-expression-for-jump-nlconstraint/34950/1 "2020-02-21T00:45:12Z")

</div>

I’m trying to define a nonlinear constraint programmatically via expressions. Specifically, I have a function `f` that takes in arguments `x` (a JuMP Variable), `i` (the index of the variable), and `p` (some parameters). The real function `f` is somewhat involved, so I’d like to be able to pass it indices/parameters and return an expression that I can use in JuMP constraints. So far, the below attempts haven’t worked for me. What I’m hung up on is splicing the JuMP Variable into the expression.

```julia
using JuMP

##
## parameter and function
##
p = Dict()
p[:a] = 10.0

function f(x, i, p)
    return :( $(x[i])^2 + $(p[:a]) )
end

```

The final constraint expression I’m trying to build must look something like

```julia
:( $(x[i])^2 + 10.0 == 0)

```

I first tried using the `@NLconstraint` macro

```julia
##
## attempt
##

M = Model()
@variable(M, x[1:3])

for i in 1:3
    @NLconstraint(M, :(0 == $(Expr(:call, f, x, $(i), p))))
end

```

but got the error

```julia
ERROR: LoadError: in @NLconstraint ($(Expr(:quote, :(0 == $(Expr(:$, :(Expr(:call, f, x, $(Expr(:$, :i)), p)))))))): constraints must be in one of the following forms:
       expr1 <= expr2
       expr1 >= expr2
       expr1 == expr2
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] @NLconstraint(::LineNumberNode, ::Module, ::Any, ::Any, ::Vararg{Any,N} where N) at /Users/jakeroth/.julia/packages/JuMP/PbnIJ/src/macros.jl:1375
in expression starting at REPL[18]:2

```

The issue with how I’ve written the constraint is that the JuMP Variable `x` isn’t spliced in, that is, I need the final expression to contain `:( $(x[i]) ... )` but I only have `:( x[i] ... )`.

It seems that my function `f` is to blame – is there a way to rewrite it to get `$` to stop interpolating in `f`? Alternatively, is there a better way to define programmatic constraints still using expressions?

---

<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:** [February 21, 2020, 12:50am UTC](https://discourse.julialang.org/t/programmaticly-build-expression-for-jump-nlconstraint/34950/2 "2020-02-21T00:50:13Z")

</div>

See [Procedural Nonlinear Constaint Generation - String to NLconstraint - #4 by odow](https://discourse.julialang.org/t/procedural-nonlinear-constaint-generation-string-to-nlconstraint/34799/4) There have been a few similar questions asked over the previous few days. Pull requests to improve the documentation appreciated.

Why not declare `f` as a user-defined function? [Nonlinear Modeling · JuMP](https://www.juliaopt.org/JuMP.jl/stable/nlp/#User-defined-Functions-1)

---

<div class="post-metadata">

**Author:** ![jacob-roth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacob-roth/32/1862_2.png) [@jacob-roth](https://discourse.julialang.org/u/jacob-roth)\
**Post date:** [February 21, 2020, 1:28am UTC](https://discourse.julialang.org/t/programmaticly-build-expression-for-jump-nlconstraint/34950/3 "2020-02-21T01:28:06Z")

</div>

> [@jacob-roth](#):
>

@odow:

Thanks for the link, I didn’t see that before!

In my actual case, `f` is a vector valued function and `x` is 2D, and I want something like `f(x[:,i]) + x[:,i] == 0`. Registering `f` will be fine, but it I think it will mean that I have to define many subfunctions `f_i` that are scalar functions. I think this will become cumbersome since I’ll need many separate `@NLconstraints` for each `i` since I can’t create single flexible expression that both include `f_i` and the appropriate indices of `x`. Also, I just tested a case registering the different `f_i` and using `autodiff=true` and it was about 10x slower than when I coded the expressions directly in JuMP, so I was hoping to use JuMP’s AD.

Even if I’ve registered `f_i`s, the issue I seem to be encountering is building an expression which mixes calls to `f_i` and the actual variables, e.g., like `@NLconstraint(M, 0 == :( x[k,i] + $(Expr(:call, f1, x[:,i]...,p)) ))`
