@@ -3233,6 +3233,85 @@ def test_fmpz_mpoly_vec():
32333233 assert raises (lambda : vec .__setitem__ (0 , ctx1 .from_dict ({})), IncompatibleContextError )
32343234
32353235
3236+ def _all_polys_mpolys ():
3237+
3238+ for P , S , is_field in _all_polys ():
3239+ x = P ([0 , 1 ])
3240+ y = None
3241+ assert isinstance (x , (
3242+ flint .fmpz_poly ,
3243+ flint .fmpq_poly ,
3244+ flint .nmod_poly ,
3245+ flint .fmpz_mod_poly ,
3246+ flint .fq_default_poly ,
3247+ ))
3248+ characteristic_zero = isinstance (x , (flint .fmpz_poly , flint .fmpq_poly ))
3249+ yield P , S , [x , y ], is_field , characteristic_zero
3250+
3251+ for P , ctx_type , S , is_field in _all_mpolys ():
3252+ ctx = ctx_type (2 , flint .Ordering .lex , ["x" , "y" ])
3253+ x , y = ctx .gens ()
3254+ assert isinstance (x , (
3255+ flint .fmpz_mpoly ,
3256+ flint .fmpq_mpoly ,
3257+ ))
3258+ characteristic_zero = isinstance (x , (flint .fmpz_mpoly , flint .fmpq_mpoly ))
3259+ yield P , S , [x , y ], is_field , characteristic_zero
3260+
3261+
3262+ def test_factor_poly_mpoly ():
3263+ """Test that factor() is consistent across different poly/mpoly types."""
3264+
3265+ def factor (p ):
3266+ coeff , factors = p .factor ()
3267+ try :
3268+ lc = p .leading_coefficient ()
3269+ except AttributeError :
3270+ # XXX: Not all univariate types have a leading_coefficient method.
3271+ lc = p [0 ]
3272+ assert type (coeff ) is type (lc )
3273+ assert isinstance (factors , list )
3274+ assert all (isinstance (f , tuple ) for f in factors )
3275+ for fac , m in factors :
3276+ assert type (fac ) is type (p )
3277+ assert type (m ) is int
3278+ return coeff , sorted (factors , key = lambda p : (p [1 ], str (p [0 ])))
3279+
3280+ for P , S , [x , y ], is_field , characteristic_zero in _all_polys_mpolys ():
3281+
3282+ assert factor (x ) == (S (1 ), [(x , 1 )])
3283+ assert factor (x ** 2 ) == (S (1 ), [(x , 2 )])
3284+ assert factor (x * (x + 1 )) == (S (1 ), [(x , 1 ), (x + 1 , 1 )])
3285+ assert factor (2 * (x + 1 )) == (S (2 ), [(x + 1 , 1 )])
3286+
3287+ if characteristic_zero :
3288+ # primitive factors over Z for Z and Q.
3289+ assert factor (2 * x + 1 ) == (S (1 ), [(2 * x + 1 , 1 )])
3290+ else :
3291+ # monic factors over Z/pZ and GF(p^d)
3292+ assert factor (2 * x + 1 ) == (S (2 ), [(x + S (1 )/ 2 , 1 )])
3293+
3294+ if is_field :
3295+ if characteristic_zero :
3296+ # primitive factors over Z for Z and Q.
3297+ assert factor ((2 * x + 1 )/ 7 ) == (S (1 )/ 7 , [(2 * x + 1 , 1 )])
3298+ else :
3299+ # monic factors over Z/pZ and GF(p^d)
3300+ assert factor ((2 * x + 1 )/ 7 ) == (S (2 )/ 7 , [(x + S (1 )/ 2 , 1 )])
3301+
3302+ if y is not None :
3303+
3304+ assert factor (x * y + 1 ) == (S (1 ), [(x * y + 1 , 1 )])
3305+ assert factor (x * y ) == (S (1 ), [(x , 1 ), (y , 1 )])
3306+
3307+ if characteristic_zero :
3308+ # primitive factors over Z for Z and Q.
3309+ assert factor (2 * x + y ) == (S (1 ), [(2 * x + y , 1 )])
3310+ else :
3311+ # monic factors over Z/pZ and GF(p^d)
3312+ assert factor (2 * x + y ) == (S (1 )/ 2 , [(x + y / 2 , 1 )])
3313+
3314+
32363315def _all_matrices ():
32373316 """Return a list of matrix types and scalar types."""
32383317 R163 = flint .fmpz_mod_ctx (163 )
@@ -4152,6 +4231,8 @@ def test_all_tests():
41524231 test_division_poly ,
41534232 test_division_matrix ,
41544233
4234+ test_factor_poly_mpoly ,
4235+
41554236 test_polys ,
41564237 test_mpolys ,
41574238
0 commit comments