Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed May 2, 2024
1 parent b76a8b2 commit 04ff92a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 27 deletions.
8 changes: 8 additions & 0 deletions src/nlp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ struct NonlinearParameter <: AbstractJuMPScalar
index::Int
end

function check_belongs_to_model(arg::NonlinearParameter, model::AbstractModel)
return arg.model === model
end

function MOI.Nonlinear.parse_expression(
model::MOI.Nonlinear.Model,
expr::MOI.Nonlinear.Expression,
Expand Down Expand Up @@ -313,6 +317,10 @@ struct NonlinearExpression <: AbstractJuMPScalar
index::Int
end

function check_belongs_to_model(arg::NonlinearExpression, model::AbstractModel)
return arg.model === model
end

function MOI.Nonlinear.parse_expression(
model::MOI.Nonlinear.Model,
expr::MOI.Nonlinear.Expression,
Expand Down
13 changes: 4 additions & 9 deletions src/nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ struct GenericNonlinearExpr{V<:AbstractVariableRef} <: AbstractJuMPScalar
) where {V<:AbstractVariableRef}
for arg in args
_throw_if_not_real(arg)
_throw_if_legacy(arg)
end
return new{V}(head, Any[a for a in args])
end
Expand All @@ -98,20 +97,16 @@ struct GenericNonlinearExpr{V<:AbstractVariableRef} <: AbstractJuMPScalar
) where {V<:AbstractVariableRef}
for arg in args
_throw_if_not_real(arg)
_throw_if_legacy(arg)
end
return new{V}(head, args)
end
end

_throw_if_legacy(::Any) = nothing

function _throw_if_legacy(arg::Union{NonlinearExpression,NonlinearParameter})
function moi_function(arg::Union{NonlinearExpression,NonlinearParameter})
return error(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $arg",
"You cannot mix legacy nonlinear object of type $(typeof(arg)) with " *
"the new nonlinear API. To use the legacy nonlinear API, all " *
"nonlinear objects must be in a `@NL` macro.",
)
end

Expand Down
62 changes: 44 additions & 18 deletions test/test_nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,26 @@ function test_extension_recursion_stackoverflow(
return
end

function test_nlparameter_interaction()
model = Model()
@variable(model, x)
@NLparameter(model, p == 1)
e = x + p
@test e isa GenericNonlinearExpr
@test string(e) == "x + ($p)"
return
end

function test_nlexpression_interaction()
model = Model()
@variable(model, x)
@NLexpression(model, expr, sin(x))
e = x + expr
@test e isa GenericNonlinearExpr
@test string(e) == "x + ($expr)"
return
end

function test_nlobjective_with_nlexpr()
model = Model()
@variable(model, x)
Expand All @@ -394,6 +414,18 @@ function test_nlconstraint_with_nlexpr()
return
end

function test_jump_function_nonlinearexpr()
model = Model()
@variable(model, x)
@NLparameter(model, p == 1)
@NLexpression(model, expr1, sin(p + x))
@NLexpression(model, expr2, sin(expr1))
nlp = nonlinear_model(model)
@test string(jump_function(model, nlp[index(expr1)])) == "sin(($p) + $x)"
@test string(jump_function(model, nlp[index(expr2)])) == "sin($expr1)"
return
end

function test_constraint_object()
model = Model()
@variable(model, x)
Expand Down Expand Up @@ -1065,15 +1097,13 @@ function test_error_legacy_expression_constructor()
@variable(model, x)
@NLexpression(model, arg, x^3)
err = ErrorException(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $arg",
"You cannot mix legacy nonlinear object of type $(typeof(arg)) with " *
"the new nonlinear API. To use the legacy nonlinear API, all " *
"nonlinear objects must be in a `@NL` macro.",
)
@test_throws err GenericNonlinearExpr(:*, Any[x, arg])
@test_throws err GenericNonlinearExpr(:*, x, arg)
@test_throws err (x * arg)
@test_throws err (arg * x)
@test_throws err @objective(model, Min, arg)
@test_throws err @constraint(model, arg <= 0)
@test_throws err @constraint(model, arg in MOI.LessThan(0.0))
return
end

Expand All @@ -1082,17 +1112,13 @@ function test_error_legacy_parameter_constructor()
@variable(model, x)
@NLparameter(model, p == 1)
err = ErrorException(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $p",
"You cannot mix legacy nonlinear object of type $(typeof(p)) with " *
"the new nonlinear API. To use the legacy nonlinear API, all " *
"nonlinear objects must be in a `@NL` macro.",
)
@test_throws err GenericNonlinearExpr(:*, Any[x, p])
@test_throws err GenericNonlinearExpr(:*, Any[p, x])
@test_throws err GenericNonlinearExpr(:*, x, p)
@test_throws err GenericNonlinearExpr(:*, p, x)
@test_throws err (x * p)
@test_throws err (p * x)
@test_throws err @objective(model, Min, p)
@test_throws err @constraint(model, p <= 0)
@test_throws err @constraint(model, p in MOI.LessThan(0.0))
return
end

Expand Down

0 comments on commit 04ff92a

Please sign in to comment.