# Optim.jl violates inequality constraint

**URL:** https://discourse.julialang.org/t/optim-jl-violates-inequality-constraint/75573
**Category:** Optimization (Mathematical)
**Tags:** optim
**Created:** [February 1, 2022, 12:31pm UTC](https://discourse.julialang.org/t/optim-jl-violates-inequality-constraint/75573 "2022-02-01T12:31:42Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)
#### Post date: [February 1, 2022, 12:31pm UTC](https://discourse.julialang.org/t/optim-jl-violates-inequality-constraint/75573/1 "2022-02-01T12:31:42Z")

</div>

I’m trying to do maximum likelihood estimation with constraints:

```julia-auto
p[1] + p[2] + p[3] + ... == 1
p[1] * a[1] / (1 - b[1]) + p[2] * a[2] / (1 - b[2]) + ... < 1

```

However, Optim seems to ignore the inequality constraint.

## Constraints code

I set up both constraints like this:

```julia
function constr1(θ::AV)
    par = get_params(θ)

    sum(par[:p]) - 1 # == 0
end

function constr2(θ::AV)
    par = get_params(θ)
    p, α, β = par[:p], par[:α], par[:β]

    sum(p .* α ./ (1 .- β)) - 1 # <= 0
end

constr(θ::AV) = [constr1(θ), constr2(θ)]

constr!(c::AV, θ::AV)::AV = (c .= constr(θ); c)

constr_jac!(J::AM, θ::AV)::AM = ForwardDiff.jacobian!(J, constr, θ)

function constr_hess!(H::AM, θ::AV, λ::AV)::AM
    myH = similar(H)

    ForwardDiff.hessian!(myH, constr1, θ)
    H .+= λ[1] .* myH

    ForwardDiff.hessian!(myH, constr2, θ)
    H .+= λ[2] .* myH

    H
end

```

Here, `get_params` extracts parameter vectors `p, μ, ω, α, β` from the parameter vector `θ`.

## Setting up optimization problem

```julia
K = 2
# Initial guess
θ0 = [
    ones(K) ./ K; #p
    zeros(K); # μ
    rand(K); # ω
    zeros(K) .+ 1e-5; # α
    zeros(K) .+ 1e-5
]

objective(θ) = D(θ, 1.0, data)

# Lower bounds
θ_lo = [
    zeros(K); # p
    fill(-Inf, K); # μ
    zeros(K); # ω
    zeros(K); zeros(K) # α, β
]
# Upper bounds
θ_hi = [
    ones(K);
    fill(Inf, K);
    fill(Inf, K);
    fill(Inf, K); fill(1., K); # α, β
]

# constr1 == 0
# -Inf <= constr2 <= 0
constr_lo = [0, -Inf]
constr_hi = [0, 0.]

dfc = TwiceDifferentiableConstraints(
    constr!, constr_jac!, constr_hess!,
    θ_lo, θ_hi, constr_lo, constr_hi
)

optimize(objective, dfc, θ0, IPNewton(), autodiff=:forward)

```

As far as I understand, `constr(θ)` must return a vector of two elements (because there are two constraints), where:

- the first element is exactly zero, since the constraint is `== 0`
- the second element must be _negative_, since the constraint is `... - 1 < 0`

Indeed, `constr(θ0) == [0.0, -0.999989999899999]`, so the initial guess seems fine.

## Problem

However, optimization fails after some steps. If I `@show constr(ForwardDiff.value.(θ))` inside the objective function, I get this:

```
constr(ForwardDiff.value.(θ)) = [4.440892098500626e-16, 0.06428113096769317]

```

…where the second element is _not_ negative, so the constraint is _not_ satisfied.

* * *

What am I doing wrong with the inequality constraint?

A reproducible example can be found here: [Optim.jl violates inequality constraint? · GitHub](https://gist.github.com/ForceBru/847d5b214c2102547f056dcb1956cdae)

---

_[View the full topic](https://discourse.julialang.org/t/optim-jl-violates-inequality-constraint/75573)._
