@@ -1127,22 +1127,40 @@ _order(x::VariableIndex, y::Real, z::VariableIndex) = (y, x, z)
11271127_order (x:: VariableIndex , y:: VariableIndex , z:: Real ) = (z, x, y)
11281128_order (x, y, z) = nothing
11291129
1130+ _order_quad (x, y) = nothing
1131+ _order_quad (x:: VariableIndex , y:: VariableIndex ) = (x, y)
1132+
11301133function Base. convert (
11311134 :: Type{ScalarQuadraticTerm{T}} ,
11321135 f:: ScalarNonlinearFunction ,
11331136) where {T}
1134- if f. head != :* || length (f. args) != 3
1135- throw (InexactError (:convert , ScalarQuadraticTerm, f))
1136- end
1137- ret = _order (f. args[1 ], f. args[2 ], f. args[3 ])
1138- if ret === nothing
1137+ if f. head != :*
11391138 throw (InexactError (:convert , ScalarQuadraticTerm, f))
1139+ elseif length (f. args) == 2
1140+ # Deal with *(x, y)
1141+ ret_2 = _order_quad (f. args[1 ], f. args[2 ])
1142+ if ret_2 === nothing
1143+ throw (InexactError (:convert , ScalarQuadraticTerm, f))
1144+ end
1145+ coef = one (T)
1146+ if ret_2[1 ] == ret_2[2 ]
1147+ coef *= 2
1148+ end
1149+ return ScalarQuadraticTerm (coef, ret_2[1 ], ret_2[2 ])
1150+ elseif length (f. args) == 3
1151+ # *(constant, x, y)
1152+ ret = _order (f. args[1 ], f. args[2 ], f. args[3 ])
1153+ if ret === nothing
1154+ throw (InexactError (:convert , ScalarQuadraticTerm, f))
1155+ end
1156+ coef = convert (T, ret[1 ])
1157+ if ret[2 ] == ret[3 ]
1158+ coef *= 2
1159+ end
1160+ return ScalarQuadraticTerm (coef, ret[2 ], ret[3 ])
1161+ else
1162+ return throw (InexactError (:convert , ScalarQuadraticTerm, f))
11401163 end
1141- coef = convert (T, ret[1 ])
1142- if ret[2 ] == ret[3 ]
1143- coef *= 2
1144- end
1145- return ScalarQuadraticTerm (coef, ret[2 ], ret[3 ])
11461164end
11471165
11481166function _add_to_function (
@@ -1157,7 +1175,11 @@ function _add_to_function(
11571175 arg:: ScalarNonlinearFunction ,
11581176) where {T}
11591177 if arg. head == :* && length (arg. args) == 2
1160- push! (f. affine_terms, convert (ScalarAffineTerm{T}, arg))
1178+ if _order_quad (arg. args[1 ], arg. args[2 ]) === nothing
1179+ push! (f. affine_terms, convert (ScalarAffineTerm{T}, arg))
1180+ else
1181+ push! (f. quadratic_terms, convert (ScalarQuadraticTerm{T}, arg))
1182+ end
11611183 elseif arg. head == :* && length (arg. args) == 3
11621184 push! (f. quadratic_terms, convert (ScalarQuadraticTerm{T}, arg))
11631185 else
@@ -1176,7 +1198,12 @@ function Base.convert(
11761198 if f. head == :*
11771199 if length (f. args) == 2
11781200 quad_terms = ScalarQuadraticTerm{T}[]
1179- affine_terms = [convert (ScalarAffineTerm{T}, f)]
1201+ affine_terms = ScalarAffineTerm{T}[]
1202+ if _order_quad (f. args[1 ], f. args[2 ]) === nothing
1203+ push! (affine_terms, convert (ScalarAffineTerm{T}, f))
1204+ else
1205+ push! (quadratic_terms, convert (ScalarQuadraticTerm{T}, f))
1206+ end
11801207 return ScalarQuadraticFunction {T} (quad_terms, affine_terms, zero (T))
11811208 elseif length (f. args) == 3
11821209 quad_terms = [convert (ScalarQuadraticTerm{T}, f)]
0 commit comments