You cannot write a JuMP model to file which contains a user-defined function. (Because we’d somehow have to write the Julia function to a text file.)
But atan2
quite a useful function. So it woutl be nice to have some solution for having it in our models.
Meanwhile I have to write
JuMP.register(model, :atan2, 2, atan; autodiff = true)
And also do some macro susbtitutions in expressione
ex = MacroTools.prewalk(u -> @capture(u, ($(atan)(a_, b_))) ? :(atan2($a, $b)) : u, ex)
Also I have to do much more macro substitutions in expressions because JuMP add_nonlinear_constraint does not undestands expressions like $(+)(a, b)
generated by Symbolics
module. It expects something like (a+b)
Thus I have a long list of such macros:
ex = Symbolics.toexpr(symexpr)
ex = MacroTools.prewalk(u -> @capture(u, ($(getindex)(u, n_))) ? :($(var[n])) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(+)(a_, b_))) ? :($a + $b) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(*)(a_, b_))) ? :($a * $b) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(^)(a_, b_))) ? :($a^$b) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(/)(a_, b_))) ? :($a / $b) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(atan)(a_, b_))) ? :(atan2($a, $b)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(max)(a_, b_))) ? :(max($a, $b)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(min)(a_, b_))) ? :(min($a, $b)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(sin)(a_))) ? :(sin($a)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(cos)(a_))) ? :(cos($a)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(sqrt)(a_))) ? :(sqrt($a)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(abs2)(a_))) ? :(abs2($a)) : u, ex)
ex = MacroTools.prewalk(u -> @capture(u, ($(atan)(a_))) ? :(atan($a)) : u, ex)
And these macros took most of the time. It not too much though. It might take a minute. But still quite annoying during developing.
It would be nice to get rid off Symbolics.jl
in first place if JuMP would accept nonlinear expressions on its variables directly. And thats still not the case. Hope this is in the next features list.