Abs in JuMP

Hi,

I’m fairly new to Julia and new to JuMP. I am trying to implement a simple optimisation problem. I haven’t asked many programming questions before so please forgive the formatting if it’s not appropriate.

I have defined a matrix S where each row is a shifted exponential with a negative exponent and the vector x is the target vector. I want to choose the optimal weighting of these shifted exponentials to minimise the absolute distance to x. After looking at a few similar questions, I have defined 4 binary vectors for each of the 4 weights 50, 25, 12.5 and 0. The issue is that I can’t take the absolute value of the difference. I think I need to do something like

expression[i] <= x[i]
-expression[i] <= x[i]

but I’m not sure exactly how to implement that there.

The code I have so far is


model = Model(HiGHS.Optimizer)
@variable(model, A[i=1:N], Bin)
@variable(model, B[i=1:N], Bin)
@variable(model, C[i=1:N], Bin)
@variable(model, D[i=1:N], Bin)

for i in range(1, N)
    @constraint(model, A[i] + B[i] + C[i] + D[i] == 1)
end

@objective(
                model, 
                Min,
                sum(sum(S[i, :].*(A[i] * 50 + B[i] * 25 + C[i] * 12.5 + D[i] * 0) for i in 1:N-1) .- x)
)

Thanks

This is not really JuMP/Julia-specific, but a common problem for linear programming, you can find the general trick to do absolutes in linear programs in Converting absolute value program into linear program - Mathematics Stack Exchange

1 Like

Hi!

I haven’t asked many programming questions before so please forgive the formatting if it’s not appropriate.

It’s a good question. You can make it a little better by providing the S and x matrices. Currently, I can’t run your example.

To model abs, you can use:

# To model: sum(abs.(y .- x))
@variable(model, t[1:length(x)] >= 0)
@constraint(model, t .>= y .- x)
@constraint(model, t .>= x .- y)
@objective(model, Min, sum(t))

But JuMP actually has special support for this with the NormOneCone:

# To model: sum(abs.(y .- x))
@variable(model, t)
@constraint(model, [t; y .- x] in MOI.NormOneCone(1 + length(x)))
@objective(model, Min, t)
1 Like