diff --git a/.codecov.yml b/.codecov.yml index 69cb76019a..57a3000ca8 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1 +1,3 @@ comment: false +ignore: + - 'src/Nonlinear/univariate_expressions_generator.jl' diff --git a/test/Nonlinear/Nonlinear.jl b/test/Nonlinear/Nonlinear.jl index 114acb86f4..0e67502e6b 100644 --- a/test/Nonlinear/Nonlinear.jl +++ b/test/Nonlinear/Nonlinear.jl @@ -880,6 +880,18 @@ function test_evaluate_subexpressions() return end +function test_evaluate_manny_arguments() + model = MOI.Nonlinear.Model() + x = MOI.VariableIndex.(1:20) + v = Dict(xi => xi.value for xi in x) + expr = MOI.Nonlinear.add_expression( + model, + Expr(:call, :+, [:(sqrt($(x[i]))) for i in 1:20]...), + ) + @test Nonlinear.evaluate(v, model, expr) ≈ sum(sqrt(i) for i in 1:20) + return +end + function test_NLPBlockData() model = Nonlinear.Model() x = MOI.VariableIndex(1) @@ -1251,6 +1263,70 @@ function test_univariate_sign() end end +function test_show_Model() + model = MOI.Nonlinear.Model() + @test sprint(show, model) == + "A Nonlinear.Model with:\n 0 objectives\n 0 parameters\n 0 expressions\n 0 constraints" + p = MOI.Nonlinear.add_parameter(model, 2.0) + @test sprint(show, model) == + "A Nonlinear.Model with:\n 0 objectives\n 1 parameter\n 0 expressions\n 0 constraints" + return +end + +function test_set_objective_nothing() + model = MOI.Nonlinear.Model() + x = MOI.VariableIndex(1) + MOI.Nonlinear.set_objective(model, :(sin($x))) + @test sprint(show, model) == + "A Nonlinear.Model with:\n 1 objective\n 0 parameters\n 0 expressions\n 0 constraints" + MOI.Nonlinear.set_objective(model, nothing) + @test sprint(show, model) == + "A Nonlinear.Model with:\n 0 objectives\n 0 parameters\n 0 expressions\n 0 constraints" + return +end + +function test_copy_evaluator() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + evaluator = Nonlinear.Evaluator(model, Nonlinear.ExprGraphOnly(), [x]) + @test_throws( + ErrorException("Copying nonlinear problems not yet implemented"), + copy(evaluator), + ) + return +end + +function test_no_objective() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + evaluator = Nonlinear.Evaluator(model, Nonlinear.ExprGraphOnly(), [x]) + @test_throws( + ErrorException( + "Unable to query objective_expr because no nonlinear objective was set", + ), + MOI.objective_expr(evaluator), + ) + return +end + +function test_convert_to_expr() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + expr = MOI.Nonlinear.add_expression(model, :(sin($x))) + evaluator = Nonlinear.Evaluator(model, Nonlinear.ExprGraphOnly(), [x]) + @test MOI.Nonlinear.convert_to_expr( + evaluator, + model[expr]; + moi_output_format = true, + ) == :(sin(x[$x])) + @test MOI.Nonlinear.convert_to_expr( + evaluator, + model[expr]; + moi_output_format = false, + ) == :(sin($x)) + return +end + end # TestNonlinear TestNonlinear.runtests() diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index 60694e7671..f1cbe0394a 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -1152,6 +1152,87 @@ function test_univariate_operator_with_no_second_order() return end +function test_no_objective() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x]) + MOI.initialize(evaluator, [:Grad]) + @test_throws( + ErrorException("No nonlinear objective."), + MOI.eval_objective(evaluator, [1.0]), + ) + g = [0.0] + @test_throws( + ErrorException("No nonlinear objective."), + MOI.eval_objective_gradient(evaluator, g, [1.0]), + ) + return +end + +function test_x_power_1() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + MOI.Nonlinear.set_objective(model, :($x^1)) + evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x]) + MOI.initialize(evaluator, [:Grad, :Hess]) + @test MOI.eval_objective(evaluator, [2.0]) ≈ 2.0 + H = [NaN] + MOI.eval_hessian_lagrangian(evaluator, H, [2.0], 1.5, Float64[]) + @test H == [0.0] + return +end + +function test_variable_first_node_in_tape() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + expr = MOI.Nonlinear.add_expression(model, :($x)) + MOI.Nonlinear.set_objective(model, :(sin($expr))) + evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x]) + MOI.initialize(evaluator, [:Grad, :Jac, :Hess]) + H = [NaN] + MOI.eval_hessian_lagrangian(evaluator, H, [2.0], 1.5, []) + @test H ≈ [-1.5 * sin(2.0)] + return +end + +function test_subexpression_first_node_in_tape() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + expr = MOI.Nonlinear.add_expression(model, :($x)) + expr2 = MOI.Nonlinear.add_expression(model, :($expr)) + MOI.Nonlinear.set_objective(model, :(sin($expr2))) + evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x]) + MOI.initialize(evaluator, [:Grad, :Jac, :Hess]) + H = [NaN] + MOI.eval_hessian_lagrangian(evaluator, H, [2.0], 1.5, []) + @test H ≈ [-1.5 * sin(2.0)] + return +end + +function test_parameter_in_hessian() + model = Nonlinear.Model() + x = MOI.VariableIndex(1) + p = MOI.Nonlinear.add_parameter(model, 3.0) + MOI.Nonlinear.set_objective(model, :(sin($x + $p))) + evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x]) + MOI.initialize(evaluator, [:Grad, :Jac, :Hess]) + H = [NaN] + MOI.eval_hessian_lagrangian(evaluator, H, [2.0], 1.5, []) + @test H ≈ [-1.5 * sin(2.0 + 3.0)] + return +end + +function test_unsafe_vector_view() + x = Float64[] + GC.@preserve x begin + view = MOI.Nonlinear.ReverseAD._UnsafeVectorView(x, 3) + @test length(x) == 3 + view[2] = 1.0 + @test x[2] == 1.0 + end + return +end + end # module TestReverseAD.runtests()