@@ -3162,6 +3162,85 @@ def test_fmpz_mpoly_vec():
31623162 assert raises (lambda : vec .__setitem__ (0 , ctx1 .from_dict ({})), IncompatibleContextError )
31633163
31643164
3165+ def _all_polys_mpolys ():
3166+
3167+ for P , S , is_field in _all_polys ():
3168+ x = P ([0 , 1 ])
3169+ y = None
3170+ assert isinstance (x , (
3171+ flint .fmpz_poly ,
3172+ flint .fmpq_poly ,
3173+ flint .nmod_poly ,
3174+ flint .fmpz_mod_poly ,
3175+ flint .fq_default_poly ,
3176+ ))
3177+ characteristic_zero = isinstance (x , (flint .fmpz_poly , flint .fmpq_poly ))
3178+ yield P , S , [x , y ], is_field , characteristic_zero
3179+
3180+ for P , ctx_type , S , is_field in _all_mpolys ():
3181+ ctx = ctx_type (2 , flint .Ordering .lex , ["x" , "y" ])
3182+ x , y = ctx .gens ()
3183+ assert isinstance (x , (
3184+ flint .fmpz_mpoly ,
3185+ flint .fmpq_mpoly ,
3186+ ))
3187+ characteristic_zero = isinstance (x , (flint .fmpz_mpoly , flint .fmpq_mpoly ))
3188+ yield P , S , [x , y ], is_field , characteristic_zero
3189+
3190+
3191+ def test_factor_poly_mpoly ():
3192+ """Test that factor() is consistent across different poly/mpoly types."""
3193+
3194+ def factor (p ):
3195+ coeff , factors = p .factor ()
3196+ try :
3197+ lc = p .leading_coefficient ()
3198+ except AttributeError :
3199+ # XXX: Not all univariate types have a leading_coefficient method.
3200+ lc = p [0 ]
3201+ assert type (coeff ) is type (lc )
3202+ assert isinstance (factors , list )
3203+ assert all (isinstance (f , tuple ) for f in factors )
3204+ for fac , m in factors :
3205+ assert type (fac ) is type (p )
3206+ assert type (m ) is int
3207+ return coeff , sorted (factors , key = lambda p : (p [1 ], str (p [0 ])))
3208+
3209+ for P , S , [x , y ], is_field , characteristic_zero in _all_polys_mpolys ():
3210+
3211+ assert factor (x ) == (S (1 ), [(x , 1 )])
3212+ assert factor (x ** 2 ) == (S (1 ), [(x , 2 )])
3213+ assert factor (x * (x + 1 )) == (S (1 ), [(x , 1 ), (x + 1 , 1 )])
3214+ assert factor (2 * (x + 1 )) == (S (2 ), [(x + 1 , 1 )])
3215+
3216+ if characteristic_zero :
3217+ # primitive factors over Z for Z and Q.
3218+ assert factor (2 * x + 1 ) == (S (1 ), [(2 * x + 1 , 1 )])
3219+ else :
3220+ # monic factors over Z/pZ and GF(p^d)
3221+ assert factor (2 * x + 1 ) == (S (2 ), [(x + S (1 )/ 2 , 1 )])
3222+
3223+ if is_field :
3224+ if characteristic_zero :
3225+ # primitive factors over Z for Z and Q.
3226+ assert factor ((2 * x + 1 )/ 7 ) == (S (1 )/ 7 , [(2 * x + 1 , 1 )])
3227+ else :
3228+ # monic factors over Z/pZ and GF(p^d)
3229+ assert factor ((2 * x + 1 )/ 7 ) == (S (2 )/ 7 , [(x + S (1 )/ 2 , 1 )])
3230+
3231+ if y is not None :
3232+
3233+ assert factor (x * y + 1 ) == (S (1 ), [(x * y + 1 , 1 )])
3234+ assert factor (x * y ) == (S (1 ), [(x , 1 ), (y , 1 )])
3235+
3236+ if characteristic_zero :
3237+ # primitive factors over Z for Z and Q.
3238+ assert factor (2 * x + y ) == (S (1 ), [(2 * x + y , 1 )])
3239+ else :
3240+ # monic factors over Z/pZ and GF(p^d)
3241+ assert factor (2 * x + y ) == (S (1 )/ 2 , [(x + y / 2 , 1 )])
3242+
3243+
31653244def _all_matrices ():
31663245 """Return a list of matrix types and scalar types."""
31673246 R163 = flint .fmpz_mod_ctx (163 )
@@ -4081,6 +4160,8 @@ def test_all_tests():
40814160 test_division_poly ,
40824161 test_division_matrix ,
40834162
4163+ test_factor_poly_mpoly ,
4164+
40844165 test_polys ,
40854166 test_mpolys ,
40864167
0 commit comments