Creating three dimensional variable using JuMP

I have created a two dimensional variable using the following code.

  fnew = Vector{Vector{VariableRef}}(undef, c)
  eta = Vector{Vector{VariableRef}}(undef, c)

  for i = 1:c
      newlines = nm_new[i]
      if newlines > 0
          fnew[i] = [@variable(TNEP, base_name="fnew[$(i),$k]") for k = 1:newlines]
          eta[i] = [@variable(TNEP, binary=true, base_name="η[$(i),$k]") for k = 1:newlines]

Now I want to make these two variables fnew and eta three dimensional. What’s the best way to do this.

I tried to do this in the following way. However, this results in error.

    fnew = Vector{Vector{Vector{VariableRef}}}((undef, r))
    eta = Vector{Vector{Vector{VariableRef}}}((undef, r))
    for i in rows
        newlines = nm_new[i]
        if newlines > 0
            fnew[i] = [ [@variable(JSTEP, base_name="fnew[$(i),$j,$k]") for j in 1:s] for k in 1:newlines ]
            eta[i] = [ [@variable(JSTEP, binary=true, base_name="η[$(i),$j,$k]") for j in 1:s] for k in 1:newlines ]

You can directly create arbitrary arrays of variables with a slightly easier sytax (Variables · JuMP):

@variables(model, x[1:m, 1:n, 1:p])

I have to create the variable only when the condition newlines > 0 is met.

The last example in the docs I linked to seems to do something similar?

julia> model = Model();

julia> @variable(model, v[i = 1:9; mod(i, 3) == 0])
JuMP.Containers.SparseAxisArray{VariableRef, 1, Tuple{Int64}} with 3 entries:
  [3]  =  v[3]
  [6]  =  v[6]
  [9]  =  v[9]

This example puts a condition on the index itself. Can I put a condition on some value accessed using an index

I haven’t tested it myself but I think it should work just fine

@variable(model, v[i = 1:9; nm_new[i] > 0])

Something like this should work:

JSTEP = Model()
@variable(JSTEP, fnew[i=rows, 1:s, 1:nm_new[i]; nm_new[i] > 0])
@variable(JSTEP, eta[i=rows, 1:s, 1:nm_new[i]; nm_new[i] > 0], Bin)
fnew[1, 2, 3]

As a general hint, if you find your JuMP model becoming verbose, there’s usually a better way to write things.