Implement "parametric" Expressions#69
Open
sstroemer wants to merge 25 commits intoait-energy:mainfrom
Open
Conversation
…erything except Units)
…ile misconfiguration
Member
Author
|
Just leaving a small ping @hkoller: this could be really useful for re-solving when running a lot of LPs. |
…eterized expressions
Collaborator
|
Sorry for my very late response. I could not really think of anything better than |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a pretty complete (but rather basic) implementation of parametric
Expressions. It currently uses theJuMP.ParameterRefapproach. Tests are passing, a new example has been added. I probably missed something somewhere, but it should not break too many non-parametric things.I would consider this highly experimental for now, so I'd like to "just get that in" and see if we can get some actual application feedback from the MGA topic or from some rolling window optimization (or MPC) to improve on it. Felt like there will be some learnings that we probably can't easily "think through" without just playing around with it.
@daschw What are your thoughts on the naming for the public functions
modify!(expression, new_value)andquery(expression)?Motivation
This is based on example 07, with 8760 snapshots. Comparing "generate and solve each time" versus "pre-generate once" with "modify and re-solve each time".
Non-parametric:
Parametric:
Rough idea
Doing this
allows us to prepare a proper objective function (
QuadExpr) assuming that someParameters might be added to it.The following then allows to parameterize some scalar settings, while providing default values:
One can use
cost: $()to "not" provide a default (since we still need one internally "no" always means0).Similarly for temporal expression the following works:
Again,
value: $(t)acts as the "no" default syntax for a temporal expression.(Re-)optimizing
The approach then looks like this:
The "nice" thing behind that is, that we can directly work with the actual
Expressionobjects, which can be accessed from Python in exactly the same way. No need to "register" parameters in the model, look them up in any way, etc.The model also prints pretty nicely now (shortened the output to show some lines as example):
Note that the
.par.is just cosmetic, to be in line with the other things. There is no actualbuild.par.lbentry in the "opt container dict", because it's justsome_component.lb(the actual field) that already contains this. For stuff like Profiles that might be mistaken for the actual "value" (the variable) in the print, which is calledfoo.var.value. I felt thatfoo.par.valueis better than justfoo.value.What's missing?
Updates to the documentation and the Python wrapper to expose the functions.
Quick notes on issues to keep in mind
set = JuMP.Parameter(0)is not properly supported byHiGHS(and others?) if using a direct model. Using fixed variables should in theory still be possible, so we should investigate further.HiGHSdoes not detect that it's actually an LP, but maybe we can report that?).JuMP(orMOI?) PR from roughly two years ago; that could help with the currently still existing problem of quadratic constraints (which occur for variousUnitrelated configurations).Expression, but I've only tested it with the "common" configurations and only partially forUnits. It can be expected that unit commitment or similar more complex formulations may be bricked by that (note: I've testedcapacityandavailability_factoras the most common ones and they work).Auto-generated summary
This pull request introduces significant changes to support parametric expressions and optimization in the
IESoptpackage. The most important changes include the addition of parametric capabilities, modifications to the objective function handling, and updates to various components to support the new features.Parametric Capabilities:
assets/examples/51_parametric_expressions.iesopt.yaml._is_parametricfunction to check if a model is parametric._optimize_hook_parametricfunction to handle quadratic objectives for parametric models.Objective Function Handling:
_build_model!function to include a hook for parametric models and handle the current objective accordingly._optimize!function to include a TODO for substituting quadratic objectives with affine expressions in parametric models.Component Updates:
Decisioncomponent to use expressions forlb,ub, andcostfields._decision_con_value_bounds!to handle value bounds constraints for decisions.Profilecomponent to handle parametric costs and values. [1] [2]Expression Handling:
_convert_to_expressionfunction to handle parametric cases. [1] [2]_prepareandaccessfunctions to support parametric expressions. [1] [2]Miscellaneous:
string_names_on_creationconfiguration check from the_build_model!function._connection_obj_cost!and_decision_obj_fixed!. [1] [2]