@@ -1113,17 +1113,27 @@ def set_bad(i):
11131113 raises (lambda : Q (1 ,2 ,[3 ,4 ]) * Q (1 ,3 ,[5 ,6 ,7 ]), ValueError )
11141114 raises (lambda : Q (1 ,2 ,[3 ,4 ]) * Z (1 ,3 ,[5 ,6 ,7 ]), ValueError )
11151115 raises (lambda : Z (1 ,2 ,[3 ,4 ]) * Q (1 ,3 ,[5 ,6 ,7 ]), ValueError )
1116+
11161117 A = Q ([[3 ,4 ],[5 ,7 ]]) / 11
11171118 X = Q ([[1 ,2 ],[3 ,4 ]])
11181119 B = A * X
11191120 assert A .solve (B ) == X
11201121 for algorithm in None , "fflu" , "dixon" :
11211122 assert A .solve (B , algorithm = algorithm ) == X
1123+ for _ in range (2 ):
1124+ A = Q (flint .fmpz_mat .randtest (30 , 30 , 10 ))
1125+ if A .det () == 0 :
1126+ continue
1127+ B = Q (flint .fmpz_mat .randtest (30 , 1 , 10 ))
1128+ X = A .solve (B )
1129+ assert A * X == B
1130+
11221131 assert raises (lambda : A .solve (B , algorithm = "invalid" ), ValueError )
11231132 assert raises (lambda : A .solve (None ), TypeError )
11241133 assert raises (lambda : A .solve ([1 ,2 ]), TypeError )
11251134 assert raises (lambda : A .solve (Q ([[1 ,2 ]])), ValueError )
11261135 assert raises (lambda : Q ([[1 ,2 ],[2 ,4 ]]).solve (Q ([[1 ],[2 ]])), ZeroDivisionError )
1136+
11271137 M = Q ([[1 ,2 ,3 ],[flint .fmpq (1 ,2 ),5 ,6 ]])
11281138 Mcopy = Q (M )
11291139 Mrref = Q ([[1 ,0 ,flint .fmpq (3 ,4 )],[0 ,1 ,flint .fmpq (9 ,8 )]])
@@ -1466,16 +1476,24 @@ def set_bad2():
14661476 assert raises (set_bad2 , TypeError )
14671477 assert bool (P ([], 5 )) is False
14681478 assert bool (P ([1 ], 5 )) is True
1479+
14691480 assert P ([1 ,2 ,1 ],3 ).gcd (P ([1 ,1 ],3 )) == P ([1 ,1 ],3 )
1470- raises (lambda : P ([1 ,2 ],3 ).gcd ([]), TypeError )
1471- raises (lambda : P ([1 ,2 ],3 ).gcd (P ([1 ,2 ],5 )), ValueError )
1481+ assert raises (lambda : P ([1 ,2 ],3 ).gcd ([]), TypeError )
1482+ assert raises (lambda : P ([1 ,2 ],3 ).gcd (P ([1 ,2 ],5 )), ValueError )
1483+ assert P ([1 ,2 ,1 ],3 ).xgcd (P ([1 ,1 ],3 )) == (P ([1 , 1 ], 3 ), P ([0 ], 3 ), P ([1 ], 3 ))
1484+ assert raises (lambda : P ([1 ,2 ],3 ).xgcd ([]), TypeError )
1485+ assert raises (lambda : P ([1 ,2 ],3 ).xgcd (P ([1 ,2 ],5 )), ValueError )
1486+ assert raises (lambda : P ([1 ,2 ],6 ).xgcd (P ([1 ,2 ],6 )), DomainError )
1487+
14721488 p3 = P ([1 ,2 ,3 ,4 ,5 ,6 ],7 )
14731489 f3 = (N (6 ,7 ), [(P ([6 , 1 ],7 ), 5 )])
14741490 assert p3 .factor () == f3
14751491 # XXX: factor ignores an invalid algorithm string
14761492 for alg in [None , 'berlekamp' , 'cantor-zassenhaus' ]:
14771493 assert p3 .factor (alg ) == f3
14781494 assert p3 .factor (algorithm = alg ) == f3
1495+ assert raises (lambda : p3 .factor (algorithm = "invalid" ), ValueError )
1496+
14791497 assert P ([1 ], 11 ).roots () == []
14801498 assert P ([1 , 2 , 3 ], 11 ).roots () == [(8 , 1 ), (6 , 1 )]
14811499 assert P ([1 , 6 , 1 , 8 ], 11 ).roots () == [(5 , 3 )]
@@ -1608,6 +1626,33 @@ def test_nmod_series():
16081626 # XXX: currently no code in nmod_series.pyx
16091627 pass
16101628
1629+
1630+ def test_nmod_contexts ():
1631+ # XXX: Generalise this test to cover fmpz_mod, fq_default, etc.
1632+ C = flint .nmod_ctx
1633+ CP = flint .nmod_poly_ctx
1634+ G = flint .nmod
1635+ P = flint .nmod_poly
1636+
1637+ for c , name in [(C , 'nmod' ), (CP , 'nmod_poly' )]:
1638+ ctx = c .new (17 )
1639+ assert ctx .modulus () == 17
1640+ assert str (ctx ) == f"Context for { name } with modulus: 17"
1641+ assert repr (ctx ) == f"{ name } _ctx(17)"
1642+ assert raises (lambda : c (3 ), TypeError )
1643+ assert raises (lambda : ctx .new (3.0 ), TypeError )
1644+
1645+ ctx = C .new (17 )
1646+ assert ctx (3 ) == G (3 ,17 ) == G (3 , ctx )
1647+ assert raises (lambda : ctx (3.0 ), TypeError )
1648+ assert raises (lambda : G (3 , []), TypeError )
1649+
1650+ ctx_poly = CP .new (17 )
1651+ assert ctx_poly ([1 ,2 ,3 ]) == P ([1 ,2 ,3 ],17 ) == P ([1 ,2 ,3 ], ctx_poly )
1652+ assert raises (lambda : ctx_poly ([1 ,2.0 ,3 ]), TypeError )
1653+ assert raises (lambda : P ([1 ,2 ,3 ], []), TypeError )
1654+
1655+
16111656def test_arb ():
16121657 A = flint .arb
16131658 assert A (3 ) > A (2.5 )
@@ -2211,7 +2256,7 @@ def test_fmpz_mod_poly():
22112256
22122257 f_inv = f .inverse_series_trunc (2 )
22132258 assert (f * f_inv ) % R_test ([0 ,0 ,1 ]) == 1
2214- assert raises (lambda : R_cmp ([0 ,0 ,1 ]).inverse_series_trunc (2 ), ValueError )
2259+ assert raises (lambda : R_cmp ([0 ,0 ,1 ]).inverse_series_trunc (2 ), ZeroDivisionError )
22152260
22162261 # Resultant
22172262 f1 = R_test ([- 3 , 1 ])
@@ -2846,6 +2891,50 @@ def setbad(obj, i, val):
28462891 if type (p ) == flint .fq_default_poly :
28472892 assert raises (lambda : p .integral (), NotImplementedError )
28482893
2894+ if characteristic == 0 :
2895+ assert not hasattr (P (0 ), "inverse_series_trunc" )
2896+ elif composite_characteristic :
2897+ x = P ([0 , 1 ])
2898+ if type (x ) is flint .fmpz_mod_poly :
2899+ assert (1 + x ).inverse_series_trunc (4 ) == 1 - x + x ** 2 - x ** 3
2900+ if characteristic .gcd (3 ) != 1 :
2901+ assert (3 + x ).inverse_series_trunc (4 ) == 1 - x + x ** 2 - x ** 3
2902+ else :
2903+ assert (3 + x ).inverse_series_trunc (4 )\
2904+ == S (1 )/ 3 - S (1 )/ 9 * x + S (1 )/ 27 * x ** 2 - S (1 )/ 81 * x ** 3
2905+ elif type (x ) is flint .nmod_poly :
2906+ assert raises (lambda : (1 + x ).inverse_series_trunc (4 ), DomainError )
2907+ else :
2908+ assert False
2909+ else :
2910+ x = P ([0 , 1 ])
2911+ assert (1 + x ).inverse_series_trunc (4 ) == 1 - x + x ** 2 - x ** 3
2912+ assert (3 + x ).inverse_series_trunc (4 )\
2913+ == S (1 )/ 3 - S (1 )/ 9 * x + S (1 )/ 27 * x ** 2 - S (1 )/ 81 * x ** 3
2914+ assert raises (lambda : (1 + x ).inverse_series_trunc (- 1 ), ValueError )
2915+ assert raises (lambda : x .inverse_series_trunc (4 ), ZeroDivisionError )
2916+
2917+ if characteristic == 0 :
2918+ assert not hasattr (P (0 ), "pow_mod" )
2919+ elif composite_characteristic :
2920+ pass
2921+ else :
2922+ x = P ([0 , 1 ])
2923+ assert (1 + x ).pow_mod (4 , x ** 2 + 1 ) == - 4
2924+ assert (3 + x ).pow_mod (4 , x ** 2 + 1 ) == 96 * x + 28
2925+ assert x .pow_mod (4 , x ** 2 + 1 ) == 1
2926+
2927+ assert x .pow_mod (2 ** 127 , x - 1 ) == 1
2928+ assert (1 + x ).pow_mod (2 ** 127 , x - 1 ) == pow (2 , 2 ** 127 , characteristic )
2929+
2930+ if type (x ) is not flint .fq_default_poly :
2931+ assert (1 + x ).pow_mod (2 ** 127 , x - 1 , S (1 )/ 2 ) == pow (2 , 2 ** 127 , characteristic )
2932+ assert raises (lambda : (1 + x ).pow_mod (2 ** 127 , x - 1 , []), TypeError )
2933+
2934+ assert raises (lambda : (1 + x ).pow_mod (4 , []), TypeError )
2935+ assert raises (lambda : (1 + x ).pow_mod ([], x ), TypeError )
2936+ assert raises (lambda : (1 + x ).pow_mod (- 1 , x ), ValueError )
2937+
28492938
28502939def _all_mpolys ():
28512940 return [
@@ -3989,6 +4078,8 @@ def test_matrices_pow():
39894078 # XXX: Allow unimodular matrices?
39904079 assert raises (lambda : M1234 ** - 1 , DomainError )
39914080
4081+ assert raises (lambda : pow (M1234 , 2 , 3 ), NotImplementedError )
4082+
39924083 Mr = M ([[1 , 2 , 3 ], [4 , 5 , 6 ]])
39934084 assert raises (lambda : Mr ** 0 , ValueError )
39944085 assert raises (lambda : Mr ** 1 , ValueError )
@@ -4552,6 +4643,8 @@ def test_all_tests():
45524643 test_nmod_mat ,
45534644 test_nmod_series ,
45544645
4646+ test_nmod_contexts ,
4647+
45554648 test_fmpz_mod ,
45564649 test_fmpz_mod_dlog ,
45574650 test_fmpz_mod_poly ,
0 commit comments