File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1072,9 +1072,17 @@ function canonicalize!(
10721072end
10731073
10741074function canonicalize! (f:: MOI.ScalarNonlinearFunction )
1075- for (i, arg) in enumerate (f. args)
1076- if ! is_canonical (arg)
1077- f. args[i] = canonicalize! (arg)
1075+ # Don't use recursion here. This gets called for all scalar nonlinear
1076+ # constraints.
1077+ stack = MOI. ScalarNonlinearFunction[f]
1078+ while ! isempty (stack)
1079+ g = pop! (stack)
1080+ for (i, arg) in enumerate (g. args)
1081+ if arg isa MOI. ScalarNonlinearFunction
1082+ push! (stack, arg)
1083+ elseif ! is_canonical (arg)
1084+ g. args[i] = canonicalize! (arg)
1085+ end
10781086 end
10791087 end
10801088 return f
Original file line number Diff line number Diff line change @@ -2044,6 +2044,19 @@ function test_ScalarNonlinearFunction_is_canonical()
20442044 f = MOI. ScalarNonlinearFunction (:sin , Any[f])
20452045 end
20462046 @test MOI. Utilities. is_canonical (f)
2047+ @test MOI. Utilities. canonicalize! (f) isa MOI. ScalarNonlinearFunction
2048+ g = MOI. ScalarNonlinearFunction (:^ , Any[1.0 * x + 1.0 * x, 2 ])
2049+ for _ in 1 : 100_000
2050+ g = MOI. ScalarNonlinearFunction (:sin , Any[g])
2051+ end
2052+ @test ! MOI. Utilities. is_canonical (g)
2053+ MOI. Utilities. canonicalize! (g)
2054+ h = MOI. ScalarNonlinearFunction (:^ , Any[2.0 * x, 2 ])
2055+ for _ in 1 : 100_000
2056+ h = MOI. ScalarNonlinearFunction (:sin , Any[h])
2057+ end
2058+ @test MOI. Utilities. is_canonical (h)
2059+ @test isapprox (g, h)
20472060 return
20482061end
20492062
You can’t perform that action at this time.
0 commit comments