# How to extend the JuMP @variable so that it can construct a sparse array which can be used as a full matrix?

**URL:** <https://discourse.julialang.org/t/how-to-extend-the-jump-variable-so-that-it-can-construct-a-sparse-array-which-can-be-used-as-a-full-matrix/69125>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump\
**Created:** [October 3, 2021, 1:15am UTC](https://discourse.julialang.org/t/how-to-extend-the-jump-variable-so-that-it-can-construct-a-sparse-array-which-can-be-used-as-a-full-matrix/69125 "2021-10-03T01:15:04Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![iiitr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iiitr/32/24586_2.png) [@iiitr](https://discourse.julialang.org/u/iiitr)\
**Post date:** [October 3, 2021, 1:15am UTC](https://discourse.julialang.org/t/how-to-extend-the-jump-variable-so-that-it-can-construct-a-sparse-array-which-can-be-used-as-a-full-matrix/69125/1 "2021-10-03T01:15:04Z")

</div>

Hi all

In fact, this question is a derivative of my last question.

> [@Can JuMP.jl create a sparse array variable that can be used as a full matrix?](https://discourse.julialang.org/t/can-jump-jl-create-a-sparse-array-variable-that-can-be-used-as-a-full-matrix/69114/2):
>
> One option would be as follows: julia\> using JuMP julia\> model = Model() A JuMP Model Feasibility problem with: Variables: 0 Model mode: AUTOMATIC CachingOptimizer state: NO\_OPTIMIZER Solver name: No optimizer attached. julia\> x = zeros(AffExpr, 3, 3) 3×3 Matrix{AffExpr}: 0 0 0 0 0 0 0 0 0 julia\> x[1, 1] = @variable(model, base\_name = "x[1, 1]") x[1, 1] julia\> x[2, 2] = @variable(model, base\_name = "x[2, 2]") x[2, 2] julia\> x[1, 3] = @variable(model, base\_name = "x[1, 3]") x[1, 3]…

I want to create a 4x4 array variables, but it only has a value at the index (1, 2), (2, 1), (2, 3), (3, 2) and the rest is 0.

@blegat provide several solutions, one of which best meets my expectations, as follows:

```julia
model = Model()
x = zeros(AffExpr, 3, 3)
x[1, 1] = @variable(model, base_name = "x[1, 1]")
x[2, 2] = @variable(model, base_name = "x[2, 2]")
x[1, 3] = @variable(model, base_name = "x[1, 3]")
x[3, 1] = @variable(model, base_name = "x[3, 1]")
x[3, 3] = @variable(model, base_name = "x[3, 3]")

julia> x
3×3 Matrix{AffExpr}:
 x[1, 1] 0 x[1, 3]
 0 x[2, 2] 0
 x[3, 1] 0 x[3, 3]

```

After my simple test, the “sparse” array variable `x` can be used as a “full” matrix.

For example, the most concerned am I is matrix multiplication and indexing:

```julia
julia> rand(3, 3) * x
3×3 Matrix{AffExpr}:
 0.39383698459321326 x[1, 1] + 0.48046499431872314 x[3, 1] 0.1500480109188398 x[2, 2] 0.39383698459321326 x[1, 3] + 0.48046499431872314 x[3, 3]
 0.9024020538088555 x[1, 1] + 0.21740175234965387 x[3, 1] 0.7251245455266802 x[2, 2] 0.9024020538088555 x[1, 3] + 0.21740175234965387 x[3, 3]
 0.47900776569507086 x[1, 1] + 0.9605059975897137 x[3, 1] 0.832551981599313 x[2, 2] 0.47900776569507086 x[1, 3] + 0.9605059975897137 x[3, 3]

julia> x[1, 1] + x[1, 2]
x[1, 1]

```

Thank you very much for the help provided by @blegat

Now, what I want to do is to make these codes more generic. I think I can extend `@variable`

In the following link, there is a very simple example to teach me how to extend `@variable`  
[https://jump.dev/JuMP.jl/v0.21.8/developers/extensions/](https://jump.dev/JuMP.jl/v0.21.8/developers/extensions/)

Maybe it’s because my level is too low. I cannot follow it very well. (To be honest, I am confused about it.)

So, I want to study exactly how `@variable` works, but I am prevented from accessing both `JuMP.add_variable` and `JuMP.build_variable` functions because of Macros.

For example, when I create a JuMP variable

```julia
@variable(model, x[1:3, 1:3])

```

How does JuMP identify `x` as a “name”, and identify `[1:3, 1:3]` as a “dimension”, …?

What information should I refer to, in order to achieve my idea? like the form shown as follows:

```julia
@variable(model, x[1:3, 1:3], Sparse, row=[1, 2, 2, 3], col=[2, 1, 3, 2])

```

I hope you won’t get bored with my long descriptions

Thanks a lot!

---

<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:** [October 3, 2021, 1:54am UTC](https://discourse.julialang.org/t/how-to-extend-the-jump-variable-so-that-it-can-construct-a-sparse-array-which-can-be-used-as-a-full-matrix/69125/2 "2021-10-03T01:54:41Z")

</div>

I’ve recently improved this in the dev documentation: [Variables · JuMP](https://jump.dev/JuMP.jl/dev/manual/variables/#User-defined-containers).

Namely: don’t extend JuMP, just use regular Julia data structures:

```nohighlight
using JuMP, SparseArrays
model = Model()
x = @variable(model, [1:4])

julia> X = sparse([1, 2, 2, 3], [2, 1, 3, 2], x)
3×3 SparseMatrixCSC{VariableRef, Int64} with 4 stored entries:
 ⋅ noname ⋅
 noname ⋅ noname
 ⋅ noname ⋅

julia> b = [1, 2, 3];

julia> X * b
3-element Vector{AffExpr}:
 2 noname
 noname + 3 noname
 2 noname

```

Now you might run into some weirdness, because of how `zero(VariableRef)` works (it is not the type `VariableRef`!).

So things like

```julia
julia> X .* X
3×3 SparseMatrixCSC{QuadExpr, Int64} with 9 stored entries:
 0 noname² 0
 noname² 0 noname²
 0 noname² 0

```

Will become dense.
