# Using structures with JuMP

**URL:** <https://discourse.julialang.org/t/using-structures-with-jump/110663>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [February 23, 2024, 6:24pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663 "2024-02-23T18:24:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![joaomcostab](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@joaomcostab](https://discourse.julialang.org/u/joaomcostab)\
**Post date:** [February 23, 2024, 6:24pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/1 "2024-02-23T18:24:57Z")

</div>

I am trying to solve a non-linear system re-writing it in a way that I can use optimization (basically the objective function is 1.0 and the constraints are the equations of the system).

However, these equations use user-defined function that have objects of type mutable structure as arguments. When I try to run the model I get the error “Unexpected stuct\_params of type struct\_params in non-linear expression”, where “struct\_params” is the structure that I am talking about. A snippet of the code is provided below

```julia
function v_zeros_UI_exogeno!(pars,Psi,UI)
    pars::struct_params
    Psi::struct_smm
    UI::Float64
    
    b = (UI^(1-pars.sigma))/(1-pars.sigma)
    n = 0.5*b
    
    model = Model(Ipopt.Optimizer)
    
    @variable(model, v_ni >= 0)
    @variable(model, v_nf >= 0)
    @variable(model, v_bi >= 0)
    @variable(model, v_bf >= 0) 
    
    register(model, :gauss_cheby_integral_f, 4, gauss_cheby_integral_f, autodiff=true)
    register(model, :gauss_cheby_integral_i, 6, gauss_cheby_integral_i, autodiff=true)
    register(model, :complementar_cdf_f, 3, complementar_cdf_f, autodiff=true)
    register(model, :complementar_cdf_i, 5, complementar_cdf_i, autodiff=true)

    @objective(model, Min, 1.0)
    
    @NLconstraint(model, c1, v_ni == n + (Psi.alpha_f/(pars.r+pars.lambda_f))*gauss_cheby_integral_f(v_nf,v_max,pars,Psi) + 
    (Psi.alpha_i/(pars.r+pars.lambda_i))*gauss_cheby_integral_i(v_ni,v_max,pars,Psi,false,UI) + 
    (Psi.alpha_f/(pars.r+pars.lambda_f))*(v_nf - v_ni + (pars.lambda_f/pars.r)*(v_bf-v_ni))*complementar_cdf_f(pars,Psi,v_nf))
    
    @NLconstraint(model, c2, v_nf == ((pars.r+pars.lambda_f)/pars.r)*v_ni - (pars.lambda_f/pars.r)*v_bf)
    
    @NLconstraint(model, c3, v_bi == ((pars.r+pars.theta)/pars.r)*v_bf - (pars.theta/pars.r)*v_ni)
    
    @NLconstraint(model, c4, v_bf == b - (pars.theta/pars.r)*(v_bf - v_ni) + (Psi.alpha_f/(pars.r+pars.lambda_f))*gauss_cheby_integral_f(v_bf,v_max,pars,Psi) + 
    (Psi.alpha_i/(pars.r+pars.lambda_i+pars.theta))*gauss_cheby_integral_i(v_bi,v_max,pars,Psi,true,UI) + 
    (complementar_cdf_i(pars,Psi,true,v_bi,UI))*(((pars.theta*pars.lambda_i)/(pars.r+pars.lambda_i))*(v_ni/pars.r) - pars.theta*(v_bf/pars.r)) + 
    ((Psi.alpha_i*pars.theta)/((pars.r+pars.lambda_i+pars.theta)*(pars.r+pars.lambda_i)))*(gauss_cheby_integral_i(v_ni,v_max,pars,Psi,false,UI) + ((complementar_cdf_i(pars,Psi,true,v_ni,UI))-(complementar_cdf_i(pars,Psi,true,v_bi,UI)))*v_ni))
    
    optimize!(model)

    return [value(v_ni),value(v_nf),value(v_bi),value(v_bf)]
end

```

---

<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 23, 2024, 7:22pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/2 "2024-02-23T19:22:37Z")

</div>

Hi @joaomcostab, welcome to the forum!

Last year we rewrote JuMP’s nonlinear interface, precisely to support structures like this.

See:

- [ANN: JuMP v1.15 is released](https://discourse.julialang.org/t/ann-jump-v1-15-is-released/103875)
- [Nonlinear Modeling · JuMP](https://jump.dev/JuMP.jl/stable/manual/nonlinear/)

To update, change

```Julia
register(model, :gauss_cheby_integral_f, 4, gauss_cheby_integral_f, autodiff=true)

```

to

```Julia
@operator(model, op_gauss_cheby_integral_f, 4, gauss_cheby_integral_f)

```

Use `op_gauss_cheby_integral_f` instead of `gauss_cheby_integral_f` in the constraint macros, and change `@NLconstraint` to `@constraint`.

If you get stuck, post a reproducible example that we can copy and paste, and we can help fix any issues.

---

<div class="post-metadata">

**Author:** ![joaomcostab](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@joaomcostab](https://discourse.julialang.org/u/joaomcostab)\
**Post date:** [February 23, 2024, 8:51pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/3 "2024-02-23T20:51:07Z")

</div>

Thanks for the quick reply!

This almost got my problem solved. However, now I am having an issue with the moi\_function. I have two mutable structures, struct\_params and struct\_smm. After making the changes suggested, it gives the error “MethodError: no method matching moi\_function(::struct\_smm)”.

---

<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 23, 2024, 9:58pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/4 "2024-02-23T21:58:29Z")

</div>

Can you make a reproducible example? What is the full error message and stacktrace?

Note that your user defined function must take only JuMP variables and expressions as input. They must not take additonal arguments like your structs.

---

<div class="post-metadata">

**Author:** ![joaomcostab](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@joaomcostab](https://discourse.julialang.org/u/joaomcostab)\
**Post date:** [February 23, 2024, 10:18pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/5 "2024-02-23T22:18:34Z")

</div>

Thanks again for the reply.

I do not feel free to make a reproducible example because I am not full responsible for the code. To make a reproducible example, I would have to give parts of the code that my supervisor may not like.

However, I guess that your comment may solve the issue. I will change the functions to only take JuMP variables.

Again, thanks for the reply!

---

<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 24, 2024, 9:07pm UTC](https://discourse.julialang.org/t/using-structures-with-jump/110663/6 "2024-02-24T21:07:30Z")

</div>

> [@joaomcostab](#):
>
> I do not feel free to make a reproducible example because I am not full responsible for the code

Try simplifying the code as much as possible. Delete unnecessary variables and constraints. Replace data with constants like `1.0`. Rename sensitive variables and constraints. The goal is to have a piece of code that reproduces the error. We don’t need exactly the code you are running.

The change will be something like this. Instead of:

```Julia
gauss_cheby_integral_f(v_nf,v_max,pars,Psi)

```

do

```Julia
function jump_gauss_cheby_integral_f(v_nf, v_max)
    return gauss_cheby_integral_f(v_nf,v_max,pars,Psi)
end
@operator(model, op_gauss_cheby_integral_f, 2, jump_gauss_cheby_integral_f)

```

and `* op_gauss_cheby_integral_f(v_nf, v_max) +`.
