# Registering an array of functions and using them in constraints and objectives

**URL:** https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [January 13, 2021, 5:39pm UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294 "2021-01-13T17:39:58Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![maajdl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maajdl/32/22838_2.png) [@maajdl](https://discourse.julialang.org/u/maajdl)
#### Post date: [January 13, 2021, 5:39pm UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294/1 "2021-01-13T17:39:59Z")

</div>

(Julia beginner)  
Still thinking about Nonlinear Programming with JuMP with some generality.  
([@NLconstraint with a sum, array and scalar variables](https://discourse.julialang.org/t/nlconstraint-with-a-sum-array-and-scalar-variables/52710))  
There are many NLP JuMP examples available but all more or less similar to the Rosenbrok problem in the sense that they involve a few explicit functions for objective and constraints.

My intuition for my own problem (pyro chemistry) is that I might need to create many nonlinear functions and that I would use as part of an array of functions or a dictionary of functions.  
Therefore when registering some new function(s) with some symbol(s) like here:

`JuMP.register(model, :hJuMP, 1, hjulia; autodiff=true)`

there is the problem that I will probably never be able to use literally the `hJuMP` symbol created in this statement. Instead, my likely use of `hJuMP` would be as one element from a list of such function:

```julia
funlist = [..., ..., hJuMP, ..., ...]

@NLconstraint(model, funlist[idx](T, xs...) == h0)

```

This kind of statement does not work and return for example this error:

```julia
LoadError: MethodError: no method matching _is_sum(::Expr)

```

I tried several variant of the idea without success.

Would there be a way to use JuMP/Julia as above?  
Or should I think otherwise?

Thanks for your suggestions,

Michel

---

<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: [January 18, 2021, 3:50am UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294/2 "2021-01-18T03:50:15Z")

</div>

This may help:

```nohighlight
using JuMP, Ipopt

function main(functions)
    model = Model(Ipopt.Optimizer)
    @variable(model, x)
    for (i, f) in enumerate(functions)
        f_sym = Symbol("f_$(i)")
        register(model, f_sym, 1, f; autodiff = true)
        add_NL_constraint(model, :($(f_sym)($x) <= 1.0))
    end
    return model
end

main([
    x -> x^2,
    x -> sin(x)^2,
])

```

I should add it as an example to the documentation. The current section on this is a little bare: [https://jump.dev/JuMP.jl/stable/nlp/#Raw-expression-input-1](https://jump.dev/JuMP.jl/stable/nlp/#Raw-expression-input-1)

---

<div class="post-metadata">

### Author: ![maajdl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maajdl/32/22838_2.png) [@maajdl](https://discourse.julialang.org/u/maajdl)
#### Post date: [January 18, 2021, 10:25am UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294/3 "2021-01-18T10:25:25Z")

</div>

Thanks odow, it could help indeed …

How would you modify the last line of this snippet to involve a sum() on these two functions ?

```julia

model = Model(Ipopt.Optimizer)
f_sym = [:f_1, :f_2]
f_fun = [x -> x^2, x -> sin(x)^2]
@variable(model, x)
for (s, f) in zip(f_sym,f_fun)
    register(model, s, 1, f; autodiff = true)
end
#@NLconstraint(model, f_1(x) + f_2(x) <= 1.0 )
add_NL_constraint(model, :($(f_sym[1])($x) + $(f_sym[2])($x) <= 1.0) )

```

As a beginner, I get already confused when trying to adjust this (very) naïve attempt:

```julia
add_NL_constraint(model, :( sum( $(f_sym[i])($x) for i in 1:2) <= 1.0) )

```

or this variant:

```julia
add_NL_constraint(model, :( sum( (($f)($x)) for f in f_sym) <= 1.0) )

```

Could you also suggest some readings on metaprogramming that deal with this kind of yoga with expressions? Explaining the mechanics of it a bit more in detail than what I found already.

Thanks!

---

<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: [January 29, 2021, 10:41pm UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294/4 "2021-01-29T22:41:41Z")

</div>

You need to build the expression manually:

```nohighlight
expr = Expr(:call, :+)
for f in f_sym
    push!(expr.args, :($(f)($x))
end
add_NL_constraint(model, :($(expr) <= 1.0) )

```

Here are the Julia docs: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/#Metaprogramming)

It’s often helpful to write the expression you want to achieve, then `dump` it to see the internal structure:

```nohighlight
julia> expr = :(f_1(x) + f_2(x) <= 1)
:(f_1(x) + f_2(x) <= 1)

julia> dump(expr)
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol <=
    2: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol +
        2: Expr
          head: Symbol call
          args: Array{Any}((2,))
            1: Symbol f_1
            2: Symbol x
        3: Expr
          head: Symbol call
          args: Array{Any}((2,))
            1: Symbol f_2
            2: Symbol x
    3: Int64 1

```

---

<div class="post-metadata">

### Author: ![maajdl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maajdl/32/22838_2.png) [@maajdl](https://discourse.julialang.org/u/maajdl)
#### Post date: [January 30, 2021, 8:40am UTC](https://discourse.julialang.org/t/registering-an-array-of-functions-and-using-them-in-constraints-and-objectives/53294/5 "2021-01-30T08:40:43Z")

</div>

Thanks odow!
