Open odow opened 2 months ago
@common_expression(model, y, f(x))
@variable(model, y)
@constraint(model, y :== f(x))
What is stopping @expression(model, y, f(x))
from adopting the common-subexpression behavior you're describing? Would this require breaking changes to MOI?
What is stopping @expression(model, y, f(x)) from adopting the common-subexpression behavior you're describing?
Yes, it's a breaking change. We discussed this on the monthly developer call. @mlubin is in favor of looking into a :subexpression
node. I need to just try out some options.
Some related discussion from https://github.com/jump-dev/MathOptInterface.jl/issues/2488:
Some possible options:
y = f(x)
for expressions. This makes things very explicit.:subexpression
operator to MOI. So: @expression(model, expr, subexpression(sin(x) + 1))
. Solvers would see this during parsing, and could choose to ignore, or store it in a common expression.I don't have a strong opinion yet. But our current approach requires us to smack the modeler on the hand and tell them they're holding it wrong and that they should do (2): https://github.com/jump-dev/JuMP.jl/issues/3729#issuecomment-2060586587
Background
@NLexpression
.MOI.Nonlinear
has support for representing expressions, and dealing with them efficientlyScalarNonlinearFunction
, we did not create an analogousScalarNonlinearExpression
object.@NLexpression
, or they made every possible expression a@NLexpression
The question is how to achieve this in JuMP.
I opened an issue in MOI: https://github.com/jump-dev/MathOptInterface.jl/issues/2488
Short of rewriting much of the
MOI.Nonlinear
module to use a single DAG of expressions (instead of the current tree), we could pass the expressions through to MOI, and then attempt to detect common subexpressions. This would rely on a heuristic of when it was beneficial to do so.A simpler approach would be to add a "nonlinear expression" set to MOI (and JuMP), just like we've done for Parameter.
A crude API would be:
with the fallback to a bridge
and maybe one for MCP:
We could come up with nicer syntax, for example: