# Programmatically fixing variables with near-zero coefficients to zero in JuMP

**URL:** <https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [June 11, 2024, 3:08am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452 "2024-06-11T03:08:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [June 11, 2024, 3:08am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/1 "2024-06-11T03:08:29Z")

</div>

In JuMP, is there a way to programmatically `fix` the variables, that have zero or near-zero multiplicative coefficients, to zero? A simple toy example (where it is very easy to compute the coefficients) that shows what I want to do would be:

```julia
n = 10
m = Model(Gurobi.Optimizer)
coeff = [rand(0:1) for i in 1:n]
@variable(m, x[1:n] >= 0)
@objective(m, Max, sum(x[i] for i in 1:n))
@constraint(m, sum(x[i] * coeff[i] for i in 1:n) <= 1)
# fix the x[i] which have coefficient zero or near 0
for i in 1:n
    if abs(coeff[i]) <= 1e-6
        @info "Fixing x[$i] to 0"
        fix(x[i], 0.0; force = true)
    end
end
optimize!(m)
@show value.(x)

```

I have an optimization problem, where the model has many constraints and the model is fairly complex. I would like `fix` the variables, which have zero or near-zero multiplicative coefficients to zero in the final JuMP model, to `0`, e.g.,

`fix(x[i], 0.0; force = true) # x[i] has coefficient 0 or near-zero in all the constraints`

before optimizing the objective. Is there a way to do it programmatically in JuMP?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 11, 2024, 3:29am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/2 "2024-06-11T03:29:00Z")

</div>

Hey Shuvo,

You’ll need something like:

```Julia
using JuMP

function fix_if_small_coefficient(model; atol)
    to_check = Set(all_variables(model))
    for (F, S) in list_of_constraint_types(model)
        if F != AffExpr
            continue # Check only the affine constraints
        end
        for ci in all_constraints(model, F, S) 
            object = constraint_object(ci)
            for xi in to_check
                if abs(coefficient(object.func, xi)) >= atol
                    pop!(to_check, xi)
                end
            end
        end
    end
    for xi in to_check
        println("Fixing $xi")
        fix(xi, 0.0; force = true)
    end
    return
end

n = 10
coeff = rand(n)
model = Model()
@variable(model, x[1:n] >= 0)
@objective(model, Max, sum(x))
@constraint(model, coeff' * x <= 1)
fix_if_small_coefficient(model; atol = 0.2)

```

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [June 11, 2024, 3:29am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/3 "2024-06-11T03:29:21Z")

</div>

You could use a semi-continous variable, that is fixed to allow zero plus say 1e-6 and greater

It does make the optimization problem much harder but gurobi IIRC has specific support for it

> **[Variables · JuMP](https://jump.dev/JuMP.jl/stable/manual/variables/#Semi-integer-and-semi-continuous-variables)**
>
> Documentation for JuMP.

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [June 11, 2024, 4:54am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/4 "2024-06-11T04:54:03Z")

</div>

Thanks @odow! Essentially, what I want is to fix those variables which have near-zero coefficients in _all the constraints_ (loosely speaking, fix those variables to zero that do not participate in the model), but it seems that the code sometimes also sets variables that do not have zero coefficients in all the constraint to zero as well. Working example:

```julia
using JuMP, Gurobi
n = 10
my_tol = 0.2
coeff = [0.16557266662150705, 0.9658411317234747, 0.0024468455279631485, 0.8886233490516873, 0.46965833440253946, 0.4549252840587207, 0.011980761056146094, 0.9961512126831391, 0.3737326710328216, 0.08191931477002423]
model = Model(Gurobi.Optimizer)
@variable(model, x[1:n] >= 0)
@variable(model, y >= 0)    
@objective(model, Max, sum(x) + y^2)
@constraint(model, coeff' * x <= 1)
@constraint(model, x[1] + y^2 <= 1)
fix_if_small_coefficient(model; atol = my_tol)
@show fix_value(y)
optimize!(model)
# print solution
println("Objective value: ", objective_value(model))

```

This fixes:

```julia
Fixing x[1]
Fixing x[7]
Fixing x[10]
Fixing y
Fixing x[3]

```

Note that, `x[1]` has coefficients `1` in the second constraints, so it should not be `fix`ed to `0`. Same goes for `y`, it has coefficient 0 in the first constraint but coefficient 1 in the second constraint, so should not be fixed to `0`. Please let me know how to get the intended behavior, where only the variables that have near-zero coefficients over all the constraints are `fix`ed to `0`.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 11, 2024, 5:59am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/5 "2024-06-11T05:59:01Z")

</div>

Well sure, your second constraint is quadratic, and I have

```julia
        if F != AffExpr
            continue # Check only the affine constraints
        end

```

You’d need to relax this to also check quadratic.

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [June 11, 2024, 7:29am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/6 "2024-06-11T07:29:51Z")

</div>

Okay I think I understand what you meant, let me try it.

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [June 11, 2024, 8:32am UTC](https://discourse.julialang.org/t/programmatically-fixing-variables-with-near-zero-coefficients-to-zero-in-jump/115452/7 "2024-06-11T08:32:18Z")

</div>

@odow, it works as you suggested, thanks very much!
