# Creating a macro for defining differential equation constraints in NLOptControl.jl

**URL:** <https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [May 31, 2017, 10:17pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023 "2017-05-31T22:17:25Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [May 31, 2017, 10:17pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/1 "2017-05-31T22:17:25Z")

</div>

@miles.lubin please correct me if I am wrong, but from what I understand from the [docs](http://www.juliaopt.org/JuMP.jl/0.15/nlp.html#raw-expression-input) and our previous discussions, JuMP.jl does not allow the user to programmatically create variables and use [ReverseDiffSparse.jl](https://github.com/mlubin/ReverseDiffSparse.jl).

To improve the readability and reduce boiler-plate code, I have been working on a [macro](https://github.com/JuliaMPC/NLOptControl.jl/blob/master/src/macros.jl) to allow the user to define the Differential Equation constraints easily. Without this macro, the code looks like [this](https://juliampc.github.io/MPCDocs.jl/latest/tutorials/Brachistochrone/main.html#Brachistochrone-1). Where the only thing that the user needs to modify are the expressions inside the `@NLexpression()` .

I can use the macro for simple linear problems like in [this example](https://juliampc.github.io/MPCDocs.jl/latest/tutorials/BrysonDenham/main.html), but if I try to use it with the macro, then I cannot solve nonlinear problems like [the first example](https://juliampc.github.io/MPCDocs.jl/latest/tutorials/Brachistochrone/macro.html).

It fails because I need to create the nonlinear expression inside of the `@NLexpression` macro. I have tried many things but I cannot seem to get it to work. Am I missing something? Any suggestions?

Thanks!

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [June 1, 2017, 11:54am UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/2 "2017-06-01T11:54:36Z")

</div>

It’s hard to follow the links to understand what you’re trying to do. Could you give a self-contained example?

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 6, 2017, 7:13pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/3 "2017-06-06T19:13:00Z")

</div>

@miles.lubin sorry for the delay, I was on a camping trip.

Basically, what I am trying to do is create a macro that can create a function for the user. Currently, the user would have to write the function as:

```julia
function Brachistochrone{T<:Any}(n::NLOpt,x::Array{T,2},u::Array{T,2})
  if n.s.integrationMethod==:tm; L=size(x)[1]; else L=size(x)[1]-1; end
  dx = Array(Any,L,n.numStates)
  dx[:,1]=@NLexpression(n.mdl, [j=1:L], x[j,3]*sin(u[j,1]) );
  dx[:,2]=@NLexpression(n.mdl, [j=1:L], x[j,3]*cos(u[j,1]) );
  dx[:,3]=@NLexpression(n.mdl, [j=1:L], 9.81*cos(u[j,1]) );
  return dx
end

```

where most of the above is boiler-plate code and the only thing that changes is the third argument that is in the `@NLexpression()` macro. For instance, if the user was to use my macro, the above function could be defined as:

```julia
@DiffEq(Brachistochrone,[x[j,3]*sin(u[j,1]);x[j,3]*cos(u[j,1]);9.81*cos(u[j,1])])

```

Do, you understand what I am trying to do now? If not, I will try to come up with a more contained example.

Thanks!

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [June 6, 2017, 8:06pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/4 "2017-06-06T20:06:42Z")

</div>

In principle you could “just” define

```julia
@DiffEq(Brachistochrone,[x[j,3]*sin(u[j,1]);x[j,3]*cos(u[j,1]);9.81*cos(u[j,1])])

```

to generate the code

```julia
function Brachistochrone{T<:Any}(n::NLOpt,x::Array{T,2},u::Array{T,2})
  if n.s.integrationMethod==:tm; L=size(x)[1]; else L=size(x)[1]-1; end
  dx = Array(Any,L,n.numStates)
  dx[:,1]=@NLexpression(n.mdl, [j=1:L], x[j,3]*sin(u[j,1]) );
  dx[:,2]=@NLexpression(n.mdl, [j=1:L], x[j,3]*cos(u[j,1]) );
  dx[:,3]=@NLexpression(n.mdl, [j=1:L], 9.81*cos(u[j,1]) );
  return dx
end

```

JuMP doesn’t currently have any ability to make multidimensional output easy to generate.

---

<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:** [June 6, 2017, 10:41pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/5 "2017-06-06T22:41:17Z")

</div>

Is the `@DiffEq` macro capable of defining differential equation constraints, that get automatically discretized to algaebric constraints? Does it work for linear and nonlinear programs/ODEs? What about PDEs? If so, is there a similar macro for functionals that automatically approximates the integral to an algaebric expression?

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 6, 2017, 10:42pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/6 "2017-06-06T22:42:48Z")

</div>

@mohamed82008 the `@DiffEq` macro is currently under development. Eventually it will automatically approximate the integral to nonlinear ODEs. There is no plan to do PDEs yet.

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 7, 2017, 6:45pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/7 "2017-06-07T18:45:48Z")

</div>

@miles.lubin I am still struggling to figure this out. The issues is not generating the function above, it happens when I try to actually use it. I get the error:

```julia
ERROR: sin is not defined for type Variable. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.
 in macro expansion at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:226 [inlined]
 in macro expansion at /home/febbo/.julia/v0.5/JuMP/src/macros.jl:1193 [inlined]
 in Brachistochrone(::NLOptControl.NLOpt, ::Array{JuMP.Variable,2}, ::Array{JuMP.Variable,2}) at /home/febbo/.julia/v0.5/NLOptControl/src/macros.jl:20
 in OCPdef!(::NLOptControl.NLOpt) at /home/febbo/.julia/v0.5/NLOptControl/src/setup.jl:256
 in #configure!#51(::Array{Any,1}, ::Function, ::NLOptControl.NLOpt) at /home/febbo/.julia/v0.5/NLOptControl/src/setup.jl:379
 in (::NLOptControl.#kw##configure!)(::Array{Any,1}, ::NLOptControl.#configure!, ::NLOptControl.NLOpt) at ./<missing>:0
 in anonymous at ./<missing>:?

```

I think that this is happening because I am evaluating the expression (`eq`) that I pass the macro inside the function that I am creating. So, then when I run it it is like I am trying to run:

```julia
julia> n.r.x[1,3]*sin(n.r.u[1,1])
ERROR: sin is not defined for type Variable. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.
in sin(::JuMP.Variable) at /home/febbo/.julia/v0.5/JuMP/src/operators.jl:630

```

So, I am trying to define a nonlinear expression outside of the `@NLexpression` macro, which does not work. Do you have any ideas how I can do this? I have several other ways, but since nothing is working, I won’t go into it.

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [June 8, 2017, 1:54am UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/8 "2017-06-08T01:54:31Z")

</div>

Don’t try to evaluate the nonlinear expression. You’ll have to generate a call to the macro `@NLexpression` and put the expression in the body of that call.

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 10, 2017, 1:18am UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/9 "2017-06-10T01:18:22Z")

</div>

@miles.lubin thank you for your help with this, unfortunately I still cannot seem to get it running, but I have created a self-contained example that should be easier to work with:

```julia
using JuMP
type R
  eq
  mdl::JuMP.Model
end
function R()
  R(Any,JuMP.Model())
end

macro defODE(r,eq)
  r=esc(r);
  quote
      r.eq=$(Meta.quot(eq))
      function $(esc(:DE))(r,x)
         @NLexpression($r.mdl,$r.eq)
      end
  end
end

r=R();
@defODE(r,2+sin(x));
@variable(r.mdl,x);
expr=DE(r,x)

```

Where the output from the above code is:

```julia
ERROR: MethodError: no method matching parseNLExpr_runtime(::JuMP.Model, ::Expr, ::Array{ReverseDiffSparse.NodeData,1}, ::Int64, ::Array{Float64,1})
Closest candidates are:
  parseNLExpr_runtime(::JuMP.Model, ::Number, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:196
  parseNLExpr_runtime(::JuMP.Model, ::JuMP.Variable, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:202
  parseNLExpr_runtime(::JuMP.Model, ::JuMP.NonlinearExpression, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:208
  ...
 in macro expansion at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:226 [inlined]
 in macro expansion at /home/febbo/.julia/v0.5/JuMP/src/macros.jl:1193 [inlined]
 in DE(::R, ::JuMP.Variable) at ./REPL[166]:6

```

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 14, 2017, 7:26am UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/10 "2017-06-14T07:26:06Z")

</div>

@miles.lubin I know that you are probably very busy with the meetup, but I would greatly appreciate any help that you can spare with this, I finally got it working for for the scalar case:

```julia
  function test(n,exp,x)
    @eval begin
      x1=$x[1,1]
      x1=eval(x1);
      eq=@NLexpression($n,$exp)
    end
    return eq
  end

```

the above can be tested with this made-up example:

```julia
  using JuMP, Ipopt
  n = Model(solver=IpoptSolver(print_level=0))
  @variable(n,x[1:4,1:4])
  exp=test(n,:(sin(x1)),x)

```

The issue that I am having is that I am dealing with arrays of expressions, so I tried to extend the above to an `N-d` case:

```julia
  function test(n,exp_arr,x)
    code=quote
      x1=$x[1,1]
      x1=eval(x1);
      @NLexpression($n,$exp_arr[1])
      end
    return eval(code)
  end

```

which can be tested with:

```julia
  using JuMP, Ipopt
  n = Model(solver=IpoptSolver(print_level=0))
  @variable(n,x[1:4,1:4])
  exp_arr=[:(sin(x1)),:(sin(x1))]
  exp=test(n,exp_arr,x)

```

which fails with:

```julia
julia> exp=test(n,exp_arr,x)
ERROR: MethodError: no method matching parseNLExpr_runtime(::JuMP.Model, ::Expr, ::Array{ReverseDiffSparse.NodeData,1}, ::Int64, ::Array{Float64,1})
Closest candidates are:
  parseNLExpr_runtime(::JuMP.Model, ::Number, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:196
  parseNLExpr_runtime(::JuMP.Model, ::JuMP.Variable, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:202
  parseNLExpr_runtime(::JuMP.Model, ::JuMP.NonlinearExpression, ::Any, ::Any, ::Any) at /home/febbo/.julia/v0.5/JuMP/src/parsenlp.jl:208
  ...
 in eval(::Module, ::Any) at ./boot.jl:234
 in test(::JuMP.Model, ::Array{Expr,1}, ::Array{JuMP.Variable,2}) at ./REPL[9]:7

```

The difference is that between an array indexed at a spot and a the item at that spot in a quoted expression can be seen with this simple example:

```julia
julia> A=[:(2+3),:(4),:(9-8)];
julia> t=A[1];
julia> eval(quote 
       @show isequal($A[1],$t)
       @show $A[1]
       @show $t
       end)
isequal((Any[:(2 + 3),4,:(9 - 8)])[1],2 + 3) = false
(Any[:(2 + 3),4,:(9 - 8)])[1] = :(2 + 3)
2 + 3 = 5
5

```

I have tried all kinds of things (which I will not go into), and I cannot get things working. Again, any help would be very nice. Thanks

---

<div class="post-metadata">

**Author:** ![huckl3b3rry87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huckl3b3rry87/32/3163_2.png) [@huckl3b3rry87](https://discourse.julialang.org/u/huckl3b3rry87)\
**Post date:** [June 14, 2017, 10:59am UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/11 "2017-06-14T10:59:13Z")

</div>

@miles.lubin I ended up just calling the function for each expression that I have, and it works. But it would be more efficient if I could just call the function once

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [June 14, 2017, 5:34pm UTC](https://discourse.julialang.org/t/creating-a-macro-for-defining-differential-equation-constraints-in-nloptcontrol-jl/4023/12 "2017-06-14T17:34:02Z")

</div>

This is not a JuMP-specific issue, it’s a question about code generation and macro hygiene.
