# How to compare JuMP variables?

I have a LP problem with many variables that represent different things. One of my variables can assume negatives or positives values, according to the timeslice. Inside an expression(@expression) I would like to accumulate ONLY the values positives of this variable. My variable is var_x. In reality, I have other loops nested, but to make it simpler the general idea is to get something that looks like that :

``````                for t in timeslice
if var_x[t]> 0
acc_x = @expression(model,acc_x + var_x[t] )
end
end
``````

I have tried this idea but I got the following error :

``````ERROR: LoadError: MethodError: no method matching isless(::Int64, ::JuMP.Variable)
``````

Anyone knows another way to compare variables JuMP? Thanks in advance.

You cannot compare variable with numbers since the variable value is unknown during the modeling phase.
What you would like to do is to have an expression having the value `sum(max.(0, var_x))`.
You could do

``````@variable m x_plus[timeslice] >= 0
@constraint m x_plus .>= var_x
``````

If you minimize the expression, in an optimial solution, you will automatically have `x_plus` equal to 0 when `var_x` is negative and equal to `var_x` otherwise.

Thanks for you answer. But I already have a objective function(minimization) that, among other expressions, needs to use the result of the accumulation I would like to do . Like:

``````min( acc_x * parameter_costs + ......)
``````

I didn’t understand your suggestion. That means I have to solve two problems of optimization? I really cannot see how to do it…

If you minimize the expression, in an optimial solution

Thanks in advance if you could help me.

You don’t have to actually minimize the expression separately. You simply have that the sum of the `x_plus` is not necessarily equal to the sum of `max(0, var_x)`, it is also allowed to be larger. You still need to show that in an optimal solution, it will always be equal.
This is the case if you minimize this sum alone but it is also the case in many other situations.
In fact, this will work if your problem is convex. That is, if it can be reformulated as

``````min_x g(x)
f_i(x) <= 0
``````

where `g(x)` and the `f_i` are convex functions.
Indeed, this can be reformulated as

``````min z
g(x) - z <= 0
f_i(x) <= 0
``````

which is equivalent since `z` is minimized so in an optimal solution, `g(x) - z` will be tight.

Here, `max(0, x)` is convex so `sum max(0, x_i)` is a convex function and the problem is convex.

``````min_x sum max(0, x_i)
...
``````

If you reformulate it as

``````min_x sum z_i
max(0, x_i) - z_i = 0
...
``````

it is not convex since `max(0, x_i) - z_i` is not linear.
However, since you minimize `z_i`, constraining `max(0, x_i) - z_i <= 0` is sufficient since it will be tight for optimal solution so you can reformulate it as

``````min_x sum z_i
max(0, x_i) - z_i <= 0
...
``````

which is convex since `max(0, x_i) - z_i` is convex.

If in your objective, you have the sum of the `max(0, x_i)` multiplied by a positive constant plus other stuff, the argument still works.

1 Like

Thanks a lot for your detailed explanation. I don’t have a great math base, so could you like to confirm my conclusions to solve this problem? Consider var_x as the variable that I want to accumulate when its value is positive.

1. Firstly, I have to include an expression like that:
``````@expression(model, myExpression, sum(max(0,var_x))
``````
1. Then my objective function takes this form
``````@objective(model, Min, myExpression*(parameter) + other sum*(other parameters)
``````
1. To finalize, I also have to include a constraint that uses myExpression. Like that:
``````@constraint(model, myConstraint, myExpression - myObjectiveFunction) <=0
``````

Thanks again!!

Firstly, I have to include an expression like that:

``````@expression(model, myExpression, sum(max(0,var_x))
``````

You need to explicitely create the `x_plus` variables that I mentioned above

To finalize, I also have to include a constraint that uses myExpression. Like that:

``````@constraint(model, myConstraint, myExpression - myObjectiveFunction) <=0
``````

What do you mean by that ? You want to add a constraint that `myExpression*(1-parameter) - other sum*(other parameters)` is nonpositive ?

I think I understood now, in fact I only need to create x_plus and its constraint, right?

``````@variable m x_plus[timeslice] >= 0
@constraint m x_plus .>= var_x
``````

And then, instead of having an expression `sum(var_x)` I would have an expression`(sum (x_plus))`

I don’t need to create explicitly an expression like bellow, once I will have to deal with the same error `no method matching isless`
`@expression(model, myExpression, sum(max(0,var_x))`

Also, as my problem is convex I can be sure that
`sum(var_x)` is equal to `sum (x_plus)`
Yes, exactly Thanks a lot for your time and patience  