# Multiple Variable Types in JuMP Extensions

**URL:** https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948
**Category:** Optimization (Mathematical)
**Created:** [February 21, 2020, 12:03am UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948 "2020-02-21T00:03:00Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)
#### Post date: [February 21, 2020, 12:03am UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/1 "2020-02-21T00:03:00Z")

</div>

With JuMP 0.21 I was wondering what the might be the recommended way to extend it to allow for mixed variable types? In other words, I am trying to figure out which functions I should extend to permit this behavior. For example, let’s suppose I have the variable reference types `MyVariableRef1 <: MyAbstractVariableRef` and `MyVariableRef2 <: MyAbstractVariableRef`, where `MyAbstractVariableRef <: JuMP.AbstractVariableRef`. Natively, JuMP will support building expressions that only contain one of these 2 reference types, thus some sort of extension is necessary to permit expressions containing both. These extensions would invoke some sort of conversion rule that would ensure the expression struct uses `MyAbstractVariableRef` (e.g., `GenericAffExpr{Float64, MyAbstractVaribableRef}`) when necessary and use the explicit types otherwise.

With JuMP 0.20 I accomplished this by extending `Base.:+`, `Base.:-`, and `Base.:*` as needed for the possible operations and that did the trick. However, now the dependence on MutableAirthmetics.jl and the associated changes to parsing macro expressions has made this approach not work entirely.

In particular, I am hoping it might be possible to do this without extending all of the `add_to_expression!` methods, but rather invoke the conversion rule prior to calling the appropriate `add_to_expression!` method. Perhaps by extending `_MA.mutable_operate!`.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [February 21, 2020, 12:51am UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/2 "2020-02-21T00:51:18Z")

</div>

What are you trying to do with your JuMP extension?

The process of building a JuMP extension is not well documented, and there might be a better way to do what you intend.

---

<div class="post-metadata">

### Author: ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)
#### Post date: [February 21, 2020, 1:29am UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/3 "2020-02-21T01:29:19Z")

</div>

The extension I am writing is [InfiniteOpt.jl](https://github.com/pulsipher/InfiniteOpt.jl). Which is designed as a general modeling interface for infinite dimensional optimization problems (e.g., dynamic, stochastic, etc.). It employs `InfiniteModel <: JuMP.AbstractModel` that uses multiple variable types such as infinite variables, point variables, and hold variables which are used to form constraints. These each have their own variable references with a certain hierarchy to keep track if constraints are infinite or not. This hierarchical information is then used to efficiently dispatch methods to ultimately discretize and solve the model. The documentation describes everything in detail (especially on the expressions page).

Previously, I tried implementing a single variable reference type that stored the variable type as an attribute (thus negating this thread), but this led to severe performance degradation since the hierarchical type information was lost and each expression had to be searched to determine what variable types it contained.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [February 21, 2020, 3:58pm UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/4 "2020-02-21T15:58:38Z")

</div>

Interesting! I’ll take a look. We should probably continue the discussion as an issue in that repo.

You should come to JuMP-dev: [JuMP-dev 2020 | JuMP](https://jump.dev/meetings/louvain2020/). I think you’d benefit from the discussions and we’d be keen to hear what you’ve been up to.

---

<div class="post-metadata">

### Author: ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)
#### Post date: [February 21, 2020, 5:20pm UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/5 "2020-02-21T17:20:35Z")

</div>

Thanks for your interest. There is an existing issue [here](https://github.com/pulsipher/InfiniteOpt.jl/issues/5). Any suggestions are more than welcome since like you said there is very little info on how to “properly” extend JuMP.

I have a busy summer, but JuMP-dev is on my radar…

---

<div class="post-metadata">

### Author: ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)
#### Post date: [February 26, 2020, 10:56pm UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/6 "2020-02-26T22:56:33Z")

</div>

As an update to this issue, I was able to extend JuMP v0.21 to allow for mixed variable reference types following a certain inheritance hierarchy by doing the following:

1. Implement a promoting method to return the common variable type reference between 2 references. (See [InfiniteOpt.jl/expressions.jl at master · infiniteopt/InfiniteOpt.jl · GitHub](https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/expressions.jl#L1-L49))
2. Extend `Base.convert` to change the variable reference type of `GenericAffExpr`s and `GenericQuadExpr`s. (See [InfiniteOpt.jl/utilities.jl at master · infiniteopt/InfiniteOpt.jl · GitHub](https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/utilities.jl#L1-L30))
3. Extend `Base.:+`, `Base.:-`, and `Base.:*` for operations that can involve mixed types. This enables expression definitions outside of macros. (See [https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/operators.jl](https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/operators.jl))
4. Extend `MutableArithmetics.mutable_operate!` for the methods that can involve mixed types. This enables the definition of expressions in macros. (See [https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/mutable\_arithmetics.jl](https://github.com/pulsipher/InfiniteOpt.jl/blob/master/src/mutable_arithmetics.jl))

Note that I have not yet figured how to extend nonlinear expressions that involve mixed variable reference types. The above approach only works for affine and quadratic expressions.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [February 26, 2020, 11:06pm UTC](https://discourse.julialang.org/t/multiple-variable-types-in-jump-extensions/34948/7 "2020-02-26T23:06:41Z")

</div>

Nonlinear expressions are treated very differently. It’s a sore point that is on our radar to correct, but is unlikely to happen pre JuMP 1.0. After releasing JuMP 1.0, we have plans for a big NLP re-write.
