Best practice for constraints with initial condition "exception"

While translating the DICE model from GAMS code to JuMP I come up with situations where I have different constraints for initial values and following ones.
This for exampe works:

@constraint(m, mres0, RES0[1] == res00)
@constraint(m, mres[ti in tidx[2:end]], RES0[ti] ==  emshare0*tau0*alpha[ti]*(Eco2[ti]/3.667))*(1-exp(-tstep/(tau0*alpha[ti])))+RES0[ti-1]*exp(-tstep/(tau0*alpha[ti]))

This however, doesn’t, because if is not supported:

@constraint(m, mres[ti in tidx], RES0[ti] == (ti ==1) ? res00 : (emshare0*tau0*alpha[ti]*(Eco2[ti]/3.667))*(1-exp(-tstep/(tau0*alpha[ti])))+RES0[ti-1]*exp(-tstep/(tau0*alpha[ti])))

Aside that one can use fix (but in other cases with Ipopt I had better results using a constraint than fixing a variable, so I guess it depends), are there other ways to have a single constrain c_name[1,2,3...] rather than c-name0 and c_name[2,3,4,...] ?

This however, doesn’t, because if is not supported:

It is supported, you just need an additional set of parentheses around the if statement:

julia> using JuMP

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> @constraint(model, c[t in 1:2], x[t] == ((t == 1) ? 0 : x[t-1]))
2-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
 c[1] : x[1] = 0
 c[2] : -x[1] + x[2] = 0

Note that this is a Julia syntax thing, not a JuMP-specific issue:

julia> :(x == (t == 1) ? a : b)
:(if x == (t == 1)
      a
  else
      b
  end)

julia> :(x == ((t == 1) ? a : b))
:(x == if t == 1
          a
      else
          b
      end)
1 Like