@@ -918,6 +918,76 @@ function _test_odd_chunks_Hessian_products(N)
918918 return
919919end
920920
921+ function _dense_jacobian (jacobian_sparsity, V, m, n)
922+ I = [i for (i, j) in jacobian_sparsity]
923+ J = [j for (i, j) in jacobian_sparsity]
924+ raw = SparseArrays. sparse (I, J, V, m, n)
925+ return Matrix (raw)
926+ end
927+
928+ function test_jacobians_and_jacvec ()
929+ model = Nonlinear. Model ()
930+ x = MOI. VariableIndex .(1 : 3 )
931+ a, b, c = x
932+ Nonlinear. set_objective (model, :($ a * $ b + $ c^ 2 ))
933+ Nonlinear. add_constraint (model, :($ c * $ b), MOI. LessThan (1.0 ))
934+ Nonlinear. add_constraint (model, :($ a^ 2 / 2 ), MOI. LessThan (1.0 ))
935+ evaluator = Nonlinear. Evaluator (model, Nonlinear. SparseReverseMode (), x)
936+ MOI. initialize (evaluator, [:Jac , :JacVec ])
937+ values = [1.0 , 2.0 , 3.0 ] # For a, b, c.
938+ jacobian_sparsity = MOI. jacobian_structure (evaluator)
939+ V = zeros (length (jacobian_sparsity))
940+ MOI. eval_constraint_jacobian (evaluator, V, values)
941+ correct_jacobian = [0.0 3.0 2.0 ; 1.0 0.0 0.0 ]
942+ @test _dense_jacobian (jacobian_sparsity, V, 2 , 3 ) ≈ correct_jacobian
943+ v = [2.4 , 3.5 , 1.2 ]
944+ product_storage = zeros (2 )
945+ MOI. eval_constraint_jacobian_product (evaluator, product_storage, values, v)
946+ @test product_storage ≈ correct_jacobian * v
947+ w = [0.6 , 4.3 ]
948+ product_storage = zeros (3 )
949+ MOI. eval_constraint_jacobian_transpose_product (
950+ evaluator,
951+ product_storage,
952+ values,
953+ w,
954+ )
955+ @test product_storage ≈ correct_jacobian' * w
956+ return
957+ end
958+
959+ function test_jacobians_and_jacvec_with_subexpressions ()
960+ model = Nonlinear. Model ()
961+ x = MOI. VariableIndex .(1 : 3 )
962+ a, b, c = x
963+ bc = Nonlinear. add_expression (model, :($ b * $ c))
964+ Nonlinear. set_objective (model, :($ a * $ b + $ c^ 2 ))
965+ Nonlinear. add_constraint (model, :($ bc), MOI. LessThan (1.0 ))
966+ Nonlinear. add_constraint (model, :($ a^ 2 / 2 ), MOI. LessThan (1.0 ))
967+ evaluator = Nonlinear. Evaluator (model, Nonlinear. SparseReverseMode (), x)
968+ MOI. initialize (evaluator, [:Jac , :JacVec ])
969+ values = [1.0 , 2.0 , 3.0 ] # For a, b, c.
970+ jacobian_sparsity = MOI. jacobian_structure (evaluator)
971+ V = zeros (length (jacobian_sparsity))
972+ MOI. eval_constraint_jacobian (evaluator, V, values)
973+ correct_jacobian = [0.0 3.0 2.0 ; 1.0 0.0 0.0 ]
974+ @test _dense_jacobian (jacobian_sparsity, V, 2 , 3 ) ≈ correct_jacobian
975+ v = [2.4 , 3.5 , 1.2 ]
976+ product_storage = zeros (2 )
977+ MOI. eval_constraint_jacobian_product (evaluator, product_storage, values, v)
978+ @test product_storage ≈ correct_jacobian * v
979+ w = [0.6 , 4.3 ]
980+ product_storage = zeros (3 )
981+ MOI. eval_constraint_jacobian_transpose_product (
982+ evaluator,
983+ product_storage,
984+ values,
985+ w,
986+ )
987+ @test product_storage ≈ correct_jacobian' * w
988+ return
989+ end
990+
921991end # module
922992
923993TestReverseAD. runtests ()
0 commit comments