I’d like to penalize negative values for a linear function of parameters without using an @constraint
(since I’d like it to be possible, but costly to violate the constraint)
Is there a way to do this within JuMP w/o defining a custom function?
My model is something like the following:
@variables m begin
coeff_0
coeffs_X[j = 1:P]
end
@NLexpression(
m,
B[i = 1:N],
coeff_0 + sum( X[i, j] * coeffs_X[j] for j = 1:P)
)
@NLobjective(
m,
Min,
sum( (y[i] - B[i]) for i = 1:N )^2
)
And I’d like to penalize B[i]
being negative.
A proposed solution, given help from @mbesancon:
@variables m begin
coeff_0
coeffs_X[j = 1:P]
negative_indicator[i = 1:N], Bin
end
@NLexpression(
m,
B[i = 1:N],
coeff_0 + sum( X[i, j] * coeffs_X[j] for j = 1:P)
)
@NLconstraint(
m,
i in 1:N,
-M * negative_indicator[i] <= B[i]
)
@NLobjective(
m,
Min,
sum( (y[i] - B[i]) for i = 1:N )^2 + sum(c * negative_indicator[i] for i = 1:N)
)
where M
is chosen to be large enough that it bounds the lowest value of B
and c
is a penalty coefficient
An alternative solution that penalizes the extent of the negativity of each B[i]
.
@variables m begin
coeff_0
coeffs_X[j = 1:P]
negative_penalizer[i = 1:N] >= 0
end
@NLexpression(
m,
B[i = 1:N],
coeff_0 + sum( X[i, j] * coeffs_X[j] for j = 1:P)
)
@NLconstraint(
m,
i in 1:N,
negative_penalizer[i] + B[i] >= 0
)
@NLobjective(
m,
Min,
sum( (y[i] - B[i]) for i = 1:N )^2 + sum(c * negative_penalizer[i] for i = 1:N)
)
where c > 0
is a penalty coefficient
I think all constraints and the objective are linear expressions, you can replace the constraint with @constraint ...
and the objective with @objective
1 Like
The objective has squares, but yeah
Oops sorry I had missed this one! In case of quadratic expressions, JuMP supports them directly, see Expressions and Constraints — JuMP -- Julia for Mathematical Optimization 0.18 documentation.
1 Like
Is there a particular benefit to defining quadratic expressions like this vs writing them out the way I did? Just an efficiency thing?
Not sure there,but I think you can get more information from the solving process and solution (dual values of constraints for instance).
JuMP will also pretty-print the constraints, which it will not do with non-linear expression I believe
1 Like