diff --git a/src/nlp_expr.jl b/src/nlp_expr.jl index 813cfd27112..c17e1b0bd22 100644 --- a/src/nlp_expr.jl +++ b/src/nlp_expr.jl @@ -120,19 +120,18 @@ end # # However, ifelse is a builtin, so we can't add methods to it. -_to_float(x) = x -_to_float(x::Real) = convert(Float64, x) - # We need only very generic fallbacks for these, because all other cases are # caught with more specific methods. for f in (:+, :-, :*, :^, :/, :atan) op = Meta.quot(f) @eval begin - function Base.$(f)(x::AbstractJuMPScalar, y::_Scalar) - return NonlinearExpr($op, x, _to_float(y)) + function Base.$(f)(x::AbstractJuMPScalar, y::_Constant) + rhs = convert(Float64, _constant_to_number(y)) + return NonlinearExpr($op, x, rhs) end - function Base.$(f)(x::_Scalar, y::AbstractJuMPScalar) - return NonlinearExpr($op, _to_float(x), y) + function Base.$(f)(x::_Constant, y::AbstractJuMPScalar) + lhs = convert(Float64, _constant_to_number(x)) + return NonlinearExpr($op, lhs, y) end function Base.$(f)(x::AbstractJuMPScalar, y::AbstractJuMPScalar) return NonlinearExpr($op, x, y) diff --git a/test/nlp_expr.jl b/test/nlp_expr.jl index 64f0b1615b6..7923b4d7ddb 100644 --- a/test/nlp_expr.jl +++ b/test/nlp_expr.jl @@ -179,6 +179,7 @@ function test_constraint_name() @test name(c) == "c" set_name(c, "d") @test name(c) == "d" + @test startswith(string(c), "d: ") return end @@ -287,8 +288,7 @@ function test_nlobjective_with_nlexpr() y = sin(x) @NLobjective(model, Min, y^2) nlp = nonlinear_model(model) - expr = :(sin($(index(x)))^2) - @test nlp.objective == MOI.Nonlinear.parse_expression(nlp, expr) + @test isequal_canonical(jump_function(model, nlp.objective), sin(x)^2) return end @@ -298,9 +298,22 @@ function test_nlconstraint_with_nlexpr() y = sin(x) @NLconstraint(model, c, y^2 <= 1) nlp = nonlinear_model(model) - expr = :(sin($(index(x)))^2 - 1.0) - @test nlp.constraints[index(c)].expression == - MOI.Nonlinear.parse_expression(nlp, expr) + @test isequal_canonical( + jump_function(model, nlp.constraints[index(c)].expression), + sin(x)^2 - 1, + ) + 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