# Extending JuMP @variable

**URL:** <https://discourse.julialang.org/t/extending-jump-variable/118094>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, metaprogramming, package-extensions\
**Created:** [August 12, 2024, 12:45pm UTC](https://discourse.julialang.org/t/extending-jump-variable/118094 "2024-08-12T12:45:01Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![shawn\_T](https://avatars.discourse-cdn.com/v4/letter/s/858c86/32.png) [@shawn\_T](https://discourse.julialang.org/u/shawn_T)\
**Post date:** [August 12, 2024, 12:45pm UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/1 "2024-08-12T12:45:01Z")

</div>

Hi,

I am planning to extend JuMP @variable macro by defining a new struct to replace the VariableInfo struct defined in JuMP, the code below is following the extension page:

```julia
struct My_var <: JuMP.AbstractVariable

    bound::Vector{Real}
end

function JuMP.build_variable(
    _err::Function,
    tb::Vector{Real},
    ::Type{My_var};
    kwargs...
)
    println("Can also use $kwargs here.")
    return My_var(tb)
end

function JuMP.add_variable(
    model::JuMP.Model,
    duplicate::My_var,
    name::String,
)
    a = JuMP.add_variable(
        model,
        duplicate,
        "$(name)_a",
    )
    b = JuMP.add_variable(
        model,
        duplicate,
        "$(name)_b",
    )
    return (a, b)
end

m = JuMP.Model()
JuMP.@variable(m, x[i=1:2], variable_type = Dy_var)

```

In the example, the user-defined struct only has a field with the type of VariableInfo, but I want to use my own type such as the struct My\_var in the above code, and in the add\_variable() function I am directly putting the My\_var type as the argument, since I also do not want to use JuMP.ScalarVariable shown in the example, but this error always appears:

```julia
ERROR: LoadError: `@variable(m, x[i = 1:2], variable_type = Dy_var)`: Unrecognized positional arguments: (Main.My_var,). (You may have passed it as a positional argument, or as a keyword value to `variable_type`.)

If you're trying to create a JuMP extension, you need to implement `build_variable`. Read the docstring for more details.

```

May I ask if I can only use fields with VariableInfo and not my own types? If not then what have I done wrong? Thank you.

---

<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:** [August 12, 2024, 11:01pm UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/2 "2024-08-12T23:01:52Z")

</div>

Hi @shawn_T, I guess you’re following [Extensions · JuMP](https://jump.dev/JuMP.jl/stable/developers/extensions/#extend_variable_macro).

Can you explain what your end goal is?

The flow is:

- the `variable_type` keyword will call `JuMP.build_variable(error_fn::Function, info::JuMP.VariableInfo, ::Type{MyVar}; kwargs...)`
- `build_variable` should return an instance that is passed to `add_variable(::Model, thing, ::String)`

Your code needs some changes because:

- You _must_ accept `VariableInfo` in the `build_variable` signature.
- Your `add_variable` function recursively calls itself.

But it’ll be easier to offer advice if I know what you’re trying to achieve.

---

<div class="post-metadata">

**Author:** ![shawn\_T](https://avatars.discourse-cdn.com/v4/letter/s/858c86/32.png) [@shawn\_T](https://discourse.julialang.org/u/shawn_T)\
**Post date:** [August 13, 2024, 8:54am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/3 "2024-08-13T08:54:48Z")

</div>

Thank you,

The thing is that I would like to use dynamic variables, which is time-dependent hence it should have different fields than in “VariableInfo” so I cannot accept this struct type, according to your advice, I think it is better to not extending this macro then.

---

<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:** [August 13, 2024, 9:01am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/4 "2024-08-13T09:01:23Z")

</div>

What is your ideal API? Can you provide a small example of what you would like to have working?

---

<div class="post-metadata">

**Author:** ![shawn\_T](https://avatars.discourse-cdn.com/v4/letter/s/858c86/32.png) [@shawn\_T](https://discourse.julialang.org/u/shawn_T)\
**Post date:** [August 13, 2024, 9:14am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/5 "2024-08-13T09:14:30Z")

</div>

Something like @variable(model, x, t) and the user could also specify the bounds of the variable x and t directly inside the macro, it is quite similar to JuMP only that the VariableInfo cannot be directly used

---

<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:** [August 13, 2024, 9:27am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/6 "2024-08-13T09:27:42Z")

</div>

What is `t`? How would you specify the bounds?

Have you seen: [GitHub - infiniteopt/InfiniteOpt.jl: An intuitive modeling interface for infinite-dimensional optimization problems.](https://github.com/infiniteopt/InfiniteOpt.jl)

---

<div class="post-metadata">

**Author:** ![shawn\_T](https://avatars.discourse-cdn.com/v4/letter/s/858c86/32.png) [@shawn\_T](https://discourse.julialang.org/u/shawn_T)\
**Post date:** [August 13, 2024, 9:36am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/7 "2024-08-13T09:36:17Z")

</div>

I should have a look, you mean I can learn from the way they do the extension.

---

<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:** [August 13, 2024, 9:41am UTC](https://discourse.julialang.org/t/extending-jump-variable/118094/8 "2024-08-13T09:41:59Z")

</div>

Yes, @pulsipher has extended the JuMP macros.

But InfiniteOpt also supports time-staged problems.

So far though, its not obvious to me why you need to write a JuMP extension. Can you elaborate more on your example?
