# How can I get the maximum of an absolute value of an objective

Hi,

How can I get the maximum of an absolute value of an objective? Something like

``````@objective(model, Max, abs(var_ref))
``````

But I got the following

``````ERROR: LoadError: MethodError: no method matching abs(::AffExpr)
``````
1 Like
1 Like

Thank you for your swift reply! But I found in the link “They do not work if you are trying to maximize |x|”, which is exactly what I hope to do.

1 Like

Oops. I didnt see that. I thought your original code had `Min`.

The reformulation is a bit more involved because you need binary variables. I’m on my phone so its hard to type, so someone else may beat me to replying. I dont think its in the docs, so we should add it.

1 Like

Sorry for the typo in my original code and thanks a lot for your reply.

1 Like

Heres a link to the math you need

https://docs.mosek.com/modeling-cookbook/mio.html#exact-absolute-value

3 Likes

Thanks a lot! I have read the link. I wonder if there is any difference between using binary variables and simply writing

``````@constraint(model, var_ref >= 0.0)
@objective(model, Max, var_ref)
``````

If you want a variable that takes only non-negative values, then yes, you can just do that. But it’s not equivalent to adding a variable and taking the absolute value.

The reformulation would be something like this:

``````function add_abs_constraint(model, x)
l, u = lower_bound(x), upper_bound(x)
pos = @variable(model, lower_bound = 0, upper_bound = u)
neg = @variable(model, lower_bound = 0, upper_bound = l)
z = @variable(model, binary = true)
@constraint(model, pos <= u * z)
@constraint(model, neg <= l * (1 - z))
@constraint(model, x == pos - neg)
return pos + neg
end

model = Model()
@variable(model, -2 <= x <= 2)
@objective(model, Max, abs_x)
``````
1 Like

Many thanks! But I tried this and get `status is INFEASIBLE`.

If `l` equals `-2`, then 0<= `neg` <=-2? This seems not to be straightforward to me. Also, in the link

https://docs.mosek.com/modeling-cookbook/mio.html#exact-absolute-value

you posted, there seems should be

``````@constraint(model, pos <= M * z)
@constraint(model, neg <= M * (1 - z))
``````

and the constant `M` is an a priori known upper bound on |x|, which should be positive.

And indeed in my case the objective to be optimized is of type `AffExpr`, so I added a line

``````@constraint(model, x == x_AffExpr)
``````

where `x_AffExpr` is a known expression.

It would be great if you can explain a little bit more. Thanks!

The example above can be tweaked to change

to

``````     l, u = abs(lower_bound(x)), abs(upper_bound(x))
``````

The full example would then be:

``````using JuMP

l, u = abs(lower_bound(x)), abs(upper_bound(x))
pos = @variable(model, lower_bound = 0, upper_bound = u)
neg = @variable(model, lower_bound = 0, upper_bound = l)
z = @variable(model, binary = true)
@constraint(model, pos <= u * z)
@constraint(model, neg <= l * (1 - z))
@constraint(model, x == pos - neg)
return pos + neg
end

model = Model()
@variable(model, -3 <= x <= -2)
@objective(model, Max, abs_x)

## Solve:
using HiGHS
JuMP.set_optimizer(model, HiGHS.Optimizer)

JuMP.optimize!(model)
JuMP.objective_value(model)
# 3.0

@objective(model, Min, abs_x)
JuMP.optimize!(model)
JuMP.objective_value(model)
# 2.0
``````
2 Likes