-
-
Notifications
You must be signed in to change notification settings - Fork 401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nonlinear Modeling: user-defined functions with vector inputs *and* output #1914
Comments
The short answer is that there isn't (currently) a good way to do this. JuMP's automatic differentiation library was written before much of Julia's AD tooling, and so is very specific to how JuMP likes things. We have a Google Summer of Code project on integrating other AD-backends that may enable things like this. |
I'm going to close this issue given that we have no plans to implement this feature. It would require a complete rewrite of the AD system that JuMP uses. IMO the best bet is support the effort to get CasADi running in Julia: casadi/casadi#1105. |
I think we are actually pretty far along with that through SparsityDetection.jl and SparseDiffTools.jl. Doing sparse AD and coloring directly from descriptions of a Julia function is now a thing. How to make JuMP utilize this is a different story, but I think a lot of what JuMP does doesn't necessarily need the DSL anymore with the newest iteration of Cassette-based tooling. |
@ChrisRackauckas Agreed, I'm totally supportive of seeing how far Cassette-based optimization modeling can go. Maybe you need the DSL aspect only for expressing constraints (i.e., changing the meaning of relation operators). |
I would like to know if user-defined function with vector output is still restricted due to AD? regards |
With ModelingToolkit you can automatically generate symbolic code from numeric code, so this kind of this is supported: rosenbrock(x,p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
x0 = zeros(2)
p = [1.0,100.0]
prob = OptimizationProblem(rosenbrock,x0,p)
sys = modelingtoolkitize(prob) # symbolicitize me captain!
prob = OptimizationProblem(sys,x0,p,grad=true,hess=true)
sol = solve(prob,NelderMead())
@test sol.minimum < 1e-8
sol = solve(prob,BFGS())
@test sol.minimum < 1e-8
sol = solve(prob,Newton())
@test sol.minimum < 1e-8 And for the OP, ModelingToolkit's
using ModelingToolkit
@variables t x(t) v(t) u(t)
@parameters p
@derivatives D'~t
loss = (4-x)^2 + 2v^2 + u^2
eqs = [
D(x) ~ v
D(v) ~ p*u^3
]
sys = ControlSystem(loss,eqs,t,[x,v],[u],[p])
dt = 0.1
tspan = (0.0,1.0)
sys = runge_kutta_discretize(sys,dt,tspan)
u0 = rand(112) # guess for the state values
prob = OptimizationProblem(sys,u0,[0.1],grad=true) I think the way forward here is to use this kind of tool for nonlinear things, but YMMV. We could link this to JuMP, i.e. generate JuMP symbolic code from this symbolic code, but I think directly connecting with MOI through GalacticOptim might have some advantages here, so it's what we're trying first (though outputting to JuMP in the future might be nice: automatically detect whether a numerical code is quadratic and then use quadratic optimization for example). |
Oh, this feature is brand new and I had forgot to tag it. It'll be released in ModelingToolkit v3.21 later today. |
@odow's talk at JuliaCon2021 included some remarks about revamping the Automatic-Differentiation engine and Nonlinear Interface. Would that mean vector inputs/outputs can be on the agenda as well? When I had tried using splatting workaround before, it ended up being easier to move the entire problem to Matlab just to use fmincon... |
Yes. This is on our radar. |
@ferrolho Check out this elegant work-around by @tkoolen : https://github.com/tkoolen/RigidBodyDynamicsSandbox/blob/master/src/jump_utils.jl With this macro, you can add nonlinear constraints with vector inputs and outputs as follows: @VectorNLconstraint(model, my_dynamics(x) == qnext) |
Thank you for sharing that, @adubredu. Twan's workaround seems along the lines of what is described in Tips and tricks > User-defined functions with vector outputs. I'm a bit sad I didn't find that a few years ago! |
Consider the following user-defined functions with vector inputs:
This function does not return a single scalar; in fact, it returns a tuple comprised of two arrays.
Ideally, I'd like to be able to define some set of constraints with the following (non-working) syntax:
Now, I am aware of the current NL interface limitations and know this is not currently possible. Moreover, I have been trying to find an example of such a situation and some workaround with the methods currently available in the NL interface but without success...
For that matter, my current workaround has ended up resembling a horrible, horrible abomination:
Surely, there must be a better way...
As such, I am opening this issue here, with the hope that someone, somewhere, has been through this and can perhaps give me some pointers to some minimum working examples, or some suggestions on how to tackle this and improve the snippet above...
Thanks in advance, and apologies for this terrible code.
P.s. I was unsure whether I should have opened this issue as a "Bug report" or as a "Feature request". I hope it isn't a big deal in the case I chose wrongly.
The text was updated successfully, but these errors were encountered: