@@ -2223,3 +2223,162 @@ function setup_test(
22232223end
22242224
22252225version_added (:: typeof (test_nonlinear_quadratic_4)) = v " 1.35.0"
2226+
2227+ function test_vector_nonlinear_oracle (
2228+ model:: MOI.ModelLike ,
2229+ config:: Config{T} ,
2230+ ) where {T}
2231+ @requires _supports (config, MOI. optimize!)
2232+ @requires MOI. supports_constraint (
2233+ model,
2234+ MOI. VectorOfVariables,
2235+ MOI. VectorNonlinearOracle{T},
2236+ )
2237+ set = MOI. VectorNonlinearOracle (;
2238+ dimension = 5 ,
2239+ l = T[0 , 0 ],
2240+ u = T[0 , 0 ],
2241+ eval_f = (ret, x) -> begin
2242+ @test length (ret) == 2
2243+ @test length (x) == 5
2244+ ret[1 ] = x[1 ]^ 2 - x[4 ]
2245+ ret[2 ] = x[2 ]^ 2 + x[3 ]^ 3 - x[5 ]
2246+ return
2247+ end ,
2248+ jacobian_structure = [(1 , 1 ), (2 , 2 ), (2 , 3 ), (1 , 4 ), (2 , 5 )],
2249+ eval_jacobian = (ret, x) -> begin
2250+ @test length (ret) == 5
2251+ @test length (x) == 5
2252+ ret[1 ] = T (2 ) * x[1 ]
2253+ ret[2 ] = T (2 ) * x[2 ]
2254+ ret[3 ] = T (3 ) * x[3 ]^ 2
2255+ ret[4 ] = - T (1 )
2256+ ret[5 ] = - T (1 )
2257+ return
2258+ end ,
2259+ hessian_lagrangian_structure = [(1 , 1 ), (2 , 2 ), (3 , 3 )],
2260+ eval_hessian_lagrangian = (ret, x, u) -> begin
2261+ @test length (ret) == 3
2262+ @test length (x) == 5
2263+ @test length (u) == 2
2264+ ret[1 ] = T (2 ) * u[1 ]
2265+ ret[2 ] = T (2 ) * u[2 ]
2266+ ret[3 ] = T (6 ) * x[3 ] * u[2 ]
2267+ return
2268+ end ,
2269+ )
2270+ @test MOI. dimension (set) == 5
2271+ x = T[1 , 2 , 3 , 4 , 5 ]
2272+ ret = T[0 , 0 ]
2273+ set. eval_f (ret, x)
2274+ @test ret == T[- 3 , 26 ]
2275+ ret = T[0 , 0 , 0 , 0 , 0 ]
2276+ set. eval_jacobian (ret, x)
2277+ @test ret == T[2 , 4 , 27 , - 1 , - 1 ]
2278+ ret = T[0 , 0 , 0 ]
2279+ set. eval_hessian_lagrangian (ret, x, T[2 , 3 ])
2280+ @test ret == T[4 , 6 , 54 ]
2281+ x, y = MOI. add_variables (model, 3 ), MOI. add_variables (model, 2 )
2282+ MOI. add_constraints .(model, x, MOI. EqualTo .(T (1 ): T (3 )))
2283+ c = MOI. add_constraint (model, MOI. VectorOfVariables ([x; y]), set)
2284+ MOI. optimize! (model)
2285+ x_v = MOI. get .(model, MOI. VariablePrimal (), x)
2286+ y_v = MOI. get .(model, MOI. VariablePrimal (), y)
2287+ @test ≈ (y_v, [x_v[1 ]^ 2 , x_v[2 ]^ 2 + x_v[3 ]^ 3 ], config)
2288+ @test ≈ (MOI. get (model, MOI. ConstraintPrimal (), c), [x_v; y_v], config)
2289+ @test ≈ (MOI. get (model, MOI. ConstraintDual (), c), zeros (T, 5 ), config)
2290+ return
2291+ end
2292+
2293+ function setup_test (
2294+ :: typeof (test_vector_nonlinear_oracle),
2295+ model:: MOIU.MockOptimizer ,
2296+ config:: Config{T} ,
2297+ ) where {T}
2298+ MOI. Utilities. set_mock_optimize! (
2299+ model,
2300+ mock -> MOI. Utilities. mock_optimize! (
2301+ mock,
2302+ config. optimal_status,
2303+ T[1 , 2 , 3 , 1 , 31 ],
2304+ (MOI. VectorOfVariables, MOI. VectorNonlinearOracle{T}) =>
2305+ [zeros (T, 5 )],
2306+ ),
2307+ )
2308+ model. eval_variable_constraint_dual = false
2309+ return () -> model. eval_variable_constraint_dual = true
2310+ end
2311+
2312+ version_added (:: typeof (test_vector_nonlinear_oracle)) = v " 1.46.0"
2313+
2314+ function test_vector_nonlinear_oracle_no_hessian (
2315+ model:: MOI.ModelLike ,
2316+ config:: Config{T} ,
2317+ ) where {T}
2318+ @requires _supports (config, MOI. optimize!)
2319+ @requires MOI. supports_constraint (
2320+ model,
2321+ MOI. VectorOfVariables,
2322+ MOI. VectorNonlinearOracle{T},
2323+ )
2324+ set = MOI. VectorNonlinearOracle (;
2325+ dimension = 5 ,
2326+ l = T[0 , 0 ],
2327+ u = T[0 , 0 ],
2328+ eval_f = (ret, x) -> begin
2329+ ret[1 ] = x[1 ]^ 2 - x[4 ]
2330+ ret[2 ] = x[2 ]^ 2 + x[3 ]^ 3 - x[5 ]
2331+ return
2332+ end ,
2333+ jacobian_structure = [(1 , 1 ), (2 , 2 ), (2 , 3 ), (1 , 4 ), (2 , 5 )],
2334+ eval_jacobian = (ret, x) -> begin
2335+ ret[1 ] = T (2 ) * x[1 ]
2336+ ret[2 ] = T (2 ) * x[2 ]
2337+ ret[3 ] = T (3 ) * x[3 ]^ 2
2338+ ret[4 ] = - T (1 )
2339+ ret[5 ] = - T (1 )
2340+ return
2341+ end ,
2342+ )
2343+ @test MOI. dimension (set) == 5
2344+ x = T[1 , 2 , 3 , 4 , 5 ]
2345+ ret = T[0 , 0 ]
2346+ set. eval_f (ret, x)
2347+ @test ret == T[- 3 , 26 ]
2348+ ret = T[0 , 0 , 0 , 0 , 0 ]
2349+ set. eval_jacobian (ret, x)
2350+ @test ret == T[2 , 4 , 27 , - 1 , - 1 ]
2351+ @test isempty (set. hessian_lagrangian_structure)
2352+ @test set. eval_hessian_lagrangian === nothing
2353+ x, y = MOI. add_variables (model, 3 ), MOI. add_variables (model, 2 )
2354+ MOI. add_constraints .(model, x, MOI. EqualTo .(T (1 ): T (3 )))
2355+ c = MOI. add_constraint (model, MOI. VectorOfVariables ([x; y]), set)
2356+ MOI. optimize! (model)
2357+ x_v = MOI. get .(model, MOI. VariablePrimal (), x)
2358+ y_v = MOI. get .(model, MOI. VariablePrimal (), y)
2359+ @test ≈ (y_v, [x_v[1 ]^ 2 , x_v[2 ]^ 2 + x_v[3 ]^ 3 ], config)
2360+ @test ≈ (MOI. get (model, MOI. ConstraintPrimal (), c), [x_v; y_v], config)
2361+ @test ≈ (MOI. get (model, MOI. ConstraintDual (), c), zeros (T, 5 ), config)
2362+ return
2363+ end
2364+
2365+ function setup_test (
2366+ :: typeof (test_vector_nonlinear_oracle_no_hessian),
2367+ model:: MOIU.MockOptimizer ,
2368+ config:: Config{T} ,
2369+ ) where {T}
2370+ MOI. Utilities. set_mock_optimize! (
2371+ model,
2372+ mock -> MOI. Utilities. mock_optimize! (
2373+ mock,
2374+ config. optimal_status,
2375+ T[1 , 2 , 3 , 1 , 31 ],
2376+ (MOI. VectorOfVariables, MOI. VectorNonlinearOracle{T}) =>
2377+ [zeros (T, 5 )],
2378+ ),
2379+ )
2380+ model. eval_variable_constraint_dual = false
2381+ return () -> model. eval_variable_constraint_dual = true
2382+ end
2383+
2384+ version_added (:: typeof (test_vector_nonlinear_oracle_no_hessian)) = v " 1.46.0"
0 commit comments