From b202512f12db8f5cc8b766d38cb2f547f5599f95 Mon Sep 17 00:00:00 2001 From: odow Date: Thu, 16 Jan 2025 08:42:10 +1300 Subject: [PATCH 1/3] Fix primal_feasibility_report with non-Float64 number types --- src/feasibility_checker.jl | 42 ++++++++++++++++++++++++++++++++ test/test_feasibility_checker.jl | 18 ++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/feasibility_checker.jl b/src/feasibility_checker.jl index 2773a7bbdb9..e5a149ff5ad 100644 --- a/src/feasibility_checker.jl +++ b/src/feasibility_checker.jl @@ -148,6 +148,48 @@ function _add_infeasible_constraints( return end +function _add_infeasible_constraints( + model::GenericModel{T}, + ::Type{F}, + ::Type{S}, + violated_constraints::Dict{Any,T}, + point_f::Function, + atol::T, +) where {T,F<:GenericNonlinearExpr,S} + for con in all_constraints(model, F, S) + obj = constraint_object(con) + # value(::GenericNonlinearExpr) returns `Float64`. Convert it to `T` for + # the case where the model is a different number type. + fn_value = convert(T, value(point_f, obj.func)) + d = _distance_to_set(fn_value, obj.set, T) + if d > atol + violated_constraints[con] = d + end + end + return +end + +function _add_infeasible_constraints( + model::GenericModel{T}, + ::Type{F}, + ::Type{S}, + violated_constraints::Dict{Any,T}, + point_f::Function, + atol::T, +) where {T,F<:Vector{<:GenericNonlinearExpr},S} + for con in all_constraints(model, F, S) + obj = constraint_object(con) + # value(::GenericNonlinearExpr) returns `Float64`. Convert it to `T` for + # the case where the model is a different number type. + fn_value = convert(Vector{T}, value.(point_f, obj.func)) + d = _distance_to_set(fn_value, obj.set, T) + if d > atol + violated_constraints[con] = d + end + end + return +end + function _add_infeasible_nonlinear_constraints( model::GenericModel{T}, violated_constraints::Dict{Any,T}, diff --git a/test/test_feasibility_checker.jl b/test/test_feasibility_checker.jl index a008b368751..2d0031c3286 100644 --- a/test/test_feasibility_checker.jl +++ b/test/test_feasibility_checker.jl @@ -197,4 +197,22 @@ function test_nonlinear_missing() ) end +function test_nonlinear_Float32() + model = GenericModel{Float32}() + @variable(model, x >= 2f0) + @constraint(model, c1, x == 1f0) + @constraint(model, c2, x*x == 0f0) + @constraint(model, c3, cos(x) == 1f0) + @constraint(model, c4, sqrt(x) == 1f0) + @constraint(model, c5, [-2+sqrt(x), 1f0] in Nonnegatives()) + report = primal_feasibility_report(model, Dict(x => 2f0)) + @test length(report) == 5 + @test report[c1] === 2f0 - 1f0 + @test report[c2] === 2f0^2 + @test report[c3] === 1f0 - cos(2f0) + @test report[c4] === sqrt(2f0) - 1f0 + @test report[c5] === 2 - sqrt(2f0) + return end + +end # module From b3e97e126933023287ffbf691c7ada4a213250dd Mon Sep 17 00:00:00 2001 From: odow Date: Thu, 16 Jan 2025 08:48:54 +1300 Subject: [PATCH 2/3] Update --- test/test_feasibility_checker.jl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/test_feasibility_checker.jl b/test/test_feasibility_checker.jl index 2d0031c3286..52fb5ad72e7 100644 --- a/test/test_feasibility_checker.jl +++ b/test/test_feasibility_checker.jl @@ -199,19 +199,19 @@ end function test_nonlinear_Float32() model = GenericModel{Float32}() - @variable(model, x >= 2f0) - @constraint(model, c1, x == 1f0) - @constraint(model, c2, x*x == 0f0) - @constraint(model, c3, cos(x) == 1f0) - @constraint(model, c4, sqrt(x) == 1f0) - @constraint(model, c5, [-2+sqrt(x), 1f0] in Nonnegatives()) - report = primal_feasibility_report(model, Dict(x => 2f0)) + @variable(model, x >= 2.0f0) + @constraint(model, c1, x == 1.0f0) + @constraint(model, c2, x*x == 0.0f0) + @constraint(model, c3, cos(x) == 1.0f0) + @constraint(model, c4, sqrt(x) == 1.0f0) + @constraint(model, c5, [-2 + sqrt(x), 1.0f0] in Nonnegatives()) + report = primal_feasibility_report(model, Dict(x => 2.0f0)) @test length(report) == 5 - @test report[c1] === 2f0 - 1f0 - @test report[c2] === 2f0^2 - @test report[c3] === 1f0 - cos(2f0) - @test report[c4] === sqrt(2f0) - 1f0 - @test report[c5] === 2 - sqrt(2f0) + @test report[c1] === 2.0f0 - 1.0f0 + @test report[c2] === 2.0f0^2 + @test report[c3] === 1.0f0 - cos(2.0f0) + @test report[c4] === sqrt(2.0f0) - 1.0f0 + @test report[c5] === 2.0f0 - sqrt(2.0f0) return end From 04144136f71ee71bc739f84f364cc6ab2a7c31dc Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Thu, 16 Jan 2025 10:05:47 +1300 Subject: [PATCH 3/3] Update test/test_feasibility_checker.jl --- test/test_feasibility_checker.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_feasibility_checker.jl b/test/test_feasibility_checker.jl index 52fb5ad72e7..6910a1e06a8 100644 --- a/test/test_feasibility_checker.jl +++ b/test/test_feasibility_checker.jl @@ -201,7 +201,7 @@ function test_nonlinear_Float32() model = GenericModel{Float32}() @variable(model, x >= 2.0f0) @constraint(model, c1, x == 1.0f0) - @constraint(model, c2, x*x == 0.0f0) + @constraint(model, c2, x * x == 0.0f0) @constraint(model, c3, cos(x) == 1.0f0) @constraint(model, c4, sqrt(x) == 1.0f0) @constraint(model, c5, [-2 + sqrt(x), 1.0f0] in Nonnegatives())