@@ -356,6 +356,179 @@ function test_objective_norm_of_matrix_with_sum()
356356 return
357357end
358358
359+ function test_objective_norm_of_product_of_matrices ()
360+ model = Nonlinear. Model ()
361+ x1 = MOI. VariableIndex (1 )
362+ x2 = MOI. VariableIndex (2 )
363+ x3 = MOI. VariableIndex (3 )
364+ x4 = MOI. VariableIndex (4 )
365+ Nonlinear. set_objective (model, :(norm ([$ x1 $ x2; $ x3 $ x4] * [1 0 ; 0 1 ])))
366+ evaluator = Nonlinear. Evaluator (model, ArrayDiff. Mode (), [x1, x2, x3, x4])
367+ MOI. initialize (evaluator, [:Grad ])
368+ sizes = evaluator. backend. objective. expr. sizes
369+ @test sizes. ndims == [0 , 2 , 2 , 2 , 0 , 0 , 2 , 0 , 0 , 2 , 2 , 0 , 0 , 2 , 0 , 0 ]
370+ @test sizes. size_offset ==
371+ [0 , 12 , 10 , 8 , 0 , 0 , 6 , 0 , 0 , 4 , 2 , 0 , 0 , 0 , 0 , 0 ]
372+ @test sizes. size == [1 , 2 , 1 , 2 , 2 , 2 , 1 , 2 , 1 , 2 , 2 , 2 , 2 , 2 ]
373+ @test sizes. storage_offset ==
374+ [0 , 1 , 5 , 9 , 11 , 12 , 13 , 15 , 16 , 17 , 21 , 23 , 24 , 25 , 27 , 28 , 29 ]
375+ x1 = 1.0
376+ x2 = 2.0
377+ x3 = 3.0
378+ x4 = 4.0
379+ @test MOI. eval_objective (evaluator, [x1, x2, x3, x4]) == sqrt (30.0 )
380+ g = ones (4 )
381+ MOI. eval_objective_gradient (evaluator, g, [x1, x2, x3, x4])
382+ @test g == [
383+ 1.0 / sqrt (30.0 ),
384+ 2.0 / sqrt (30.0 ),
385+ 3.0 / sqrt (30.0 ),
386+ 4.0 / sqrt (30.0 ),
387+ ]
388+ return
389+ end
390+
391+ function test_objective_norm_of_product_of_matrices_with_sum ()
392+ model = Nonlinear. Model ()
393+ x1 = MOI. VariableIndex (1 )
394+ x2 = MOI. VariableIndex (2 )
395+ x3 = MOI. VariableIndex (3 )
396+ x4 = MOI. VariableIndex (4 )
397+ Nonlinear. set_objective (
398+ model,
399+ :(norm (([$ x1 $ x2; $ x3 $ x4] + [1 1 ; 1 1 ]) * [1 0 ; 0 1 ])),
400+ )
401+ evaluator = Nonlinear. Evaluator (model, ArrayDiff. Mode (), [x1, x2, x3, x4])
402+ MOI. initialize (evaluator, [:Grad ])
403+ sizes = evaluator. backend. objective. expr. sizes
404+ @test sizes. ndims == [
405+ 0 ,
406+ 2 ,
407+ 2 ,
408+ 2 ,
409+ 2 ,
410+ 0 ,
411+ 0 ,
412+ 2 ,
413+ 0 ,
414+ 0 ,
415+ 2 ,
416+ 2 ,
417+ 0 ,
418+ 0 ,
419+ 2 ,
420+ 0 ,
421+ 0 ,
422+ 2 ,
423+ 2 ,
424+ 0 ,
425+ 0 ,
426+ 2 ,
427+ 0 ,
428+ 0 ,
429+ ]
430+ @test sizes. size_offset == [
431+ 0 ,
432+ 20 ,
433+ 18 ,
434+ 16 ,
435+ 14 ,
436+ 0 ,
437+ 0 ,
438+ 12 ,
439+ 0 ,
440+ 0 ,
441+ 10 ,
442+ 8 ,
443+ 0 ,
444+ 0 ,
445+ 6 ,
446+ 0 ,
447+ 0 ,
448+ 4 ,
449+ 2 ,
450+ 0 ,
451+ 0 ,
452+ 0 ,
453+ 0 ,
454+ 0 ,
455+ ]
456+ @test sizes. size ==
457+ [1 , 2 , 1 , 2 , 2 , 2 , 1 , 2 , 1 , 2 , 2 , 2 , 1 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ]
458+ @test sizes. storage_offset == [
459+ 0 ,
460+ 1 ,
461+ 5 ,
462+ 9 ,
463+ 13 ,
464+ 15 ,
465+ 16 ,
466+ 17 ,
467+ 19 ,
468+ 20 ,
469+ 21 ,
470+ 25 ,
471+ 27 ,
472+ 28 ,
473+ 29 ,
474+ 31 ,
475+ 32 ,
476+ 33 ,
477+ 37 ,
478+ 39 ,
479+ 40 ,
480+ 41 ,
481+ 43 ,
482+ 44 ,
483+ 45 ,
484+ ]
485+ x1 = 1.0
486+ x2 = 2.0
487+ x3 = 3.0
488+ x4 = 4.0
489+ @test MOI. eval_objective (evaluator, [x1, x2, x3, x4]) == sqrt (54.0 )
490+ g = ones (4 )
491+ MOI. eval_objective_gradient (evaluator, g, [x1, x2, x3, x4])
492+ @test g == [
493+ 2.0 / sqrt (54.0 ),
494+ 3.0 / sqrt (54.0 ),
495+ 4.0 / sqrt (54.0 ),
496+ 5.0 / sqrt (54.0 ),
497+ ]
498+ return
499+ end
500+
501+ function test_objective_norm_of_mtx_vector_product ()
502+ model = Nonlinear. Model ()
503+ x1 = MOI. VariableIndex (1 )
504+ x2 = MOI. VariableIndex (2 )
505+ x3 = MOI. VariableIndex (3 )
506+ x4 = MOI. VariableIndex (4 )
507+ Nonlinear. set_objective (model, :(norm (([$ x1 $ x2; $ x3 $ x4] * [1 ; 1 ]))))
508+ evaluator = Nonlinear. Evaluator (model, ArrayDiff. Mode (), [x1, x2, x3, x4])
509+ MOI. initialize (evaluator, [:Grad ])
510+ sizes = evaluator. backend. objective. expr. sizes
511+ @test sizes. ndims == [0 , 2 , 2 , 2 , 0 , 0 , 2 , 0 , 0 , 2 , 0 , 0 ]
512+ @test sizes. size_offset == [0 , 8 , 6 , 4 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 ]
513+ @test sizes. size == [2 , 1 , 1 , 2 , 1 , 2 , 2 , 2 , 2 , 1 ]
514+ @test sizes. storage_offset ==
515+ [0 , 1 , 3 , 7 , 9 , 10 , 11 , 13 , 14 , 15 , 17 , 18 , 19 ]
516+ x1 = 1.0
517+ x2 = 2.0
518+ x3 = 3.0
519+ x4 = 4.0
520+ @test MOI. eval_objective (evaluator, [x1, x2, x3, x4]) == sqrt (58.0 )
521+ g = ones (4 )
522+ MOI. eval_objective_gradient (evaluator, g, [x1, x2, x3, x4])
523+ @test g == [
524+ 3.0 / sqrt (58.0 ),
525+ 3.0 / sqrt (58.0 ),
526+ 7.0 / sqrt (58.0 ),
527+ 7.0 / sqrt (58.0 ),
528+ ]
529+ return
530+ end
531+
359532end # module
360533
361534TestArrayDiff. runtests ()
0 commit comments