jump-dev / JuMP.jl

Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
http://jump.dev/JuMP.jl/
Other
2.17k stars 390 forks source link

Improve support for relational algebra #3438

Open odow opened 11 months ago

odow commented 11 months ago

Motivated by https://jump.dev/2023/07/20/gams-blog/

To make this syntax a bit nicer

image
odow commented 10 months ago

The alternative is to parse SparseAxisArray into a data frame: https://github.com/jump-dev/JuMP.jl/pull/3441#issuecomment-1674393697

Ideally, we should parse the condition of the JuMP.Containers.NestedIterator then it would be an expression tree of conditions with && and ||. Then we put it into conjunctive normal form c1 && c2 && ... && cm. Then for each condition, we should check: which indices does it involve ? is this an equality lhs == rhs If it involves a subset of the indices then we should filter with this condition earlier and not in the most nested level of the for loops. If it is an equality, we could do the indexing ourself (as in https://discourse.julialang.org/t/is-it-possible-to-incorporate-the-relational-algebra-technique-into-jump-in-the-future-to-expedite-model-generation/101343/4?u=blegat) or use DataFrames but that's kind of an heavy dependency for just this. Now what's a bit tricky is that you could have [i = I, j = J, k = K, l = L; f(i, j, k) == g(j, k, l)]. Then, it means you need to build the set of (i, j, k) and the set of (j, k, l) and then index them with the Dict to take the intersection. One could wonder if it wouldn't be better to just to the 4-nested for loops instead of having to do twice a 3-nested for loops. I think however than unless K has only 2 elements, it is always better to do two 3-nested for-loops than a 4-nested for loops so doing this intersection with dictionaries is always better.

In some cases, it might be better to do the nested for loops in an order that is different from the order of the indices used by the user but that can be left as future work since I don't think this is easy to find that. But detecting the two things I mentioned above and improving the iteration shouldn't be too complicated and it would solve the issue in the GAMS example without the user to do anything. The SparseAxisArray would automatically build itself efficiently.

odow commented 9 months ago

This tutorial is relevant for any changes in the future looking at this:

https://jump.dev/JuMP.jl/stable/tutorials/linear/multi_commodity_network/

odow commented 9 months ago

See also https://github.com/jump-dev/JuMP.jl/issues/3212