@@ -3826,6 +3826,377 @@ def test_fq_default():
38263826
38273827 assert (a * a ).is_square ()
38283828
3829+
3830+ def test_fq_default_poly ():
3831+ from flint import fq_default_ctx , fq_default_poly_ctx , fq_default , fq_default_poly , fmpz , fmpz_poly
3832+
3833+ # fmpz_mod_poly_ctx tests
3834+ F = fq_default_ctx (11 , 3 )
3835+ R1 = fq_default_poly_ctx (F )
3836+ R2 = fq_default_poly_ctx (11 , 3 )
3837+ R3 = fq_default_poly_ctx (13 , 5 )
3838+
3839+ assert raises (lambda : fq_default_poly_ctx ("AAA" ), TypeError )
3840+ assert (R1 == R1 ) is True
3841+ assert (R1 != R1 ) is False
3842+ assert (R1 == R2 ) is True
3843+ assert (R1 != R2 ) is False
3844+ assert (R1 != R3 ) is True
3845+ assert (R1 == R3 ) is False
3846+ assert (R1 != "AAA" ) is True
3847+ assert (R1 == "AAA" ) is False
3848+
3849+ assert (hash (R1 ) == hash (R1 )) is True
3850+ assert (hash (R1 ) == hash (R2 )) is True
3851+ assert (hash (R1 ) != hash (R3 )) is True
3852+
3853+ assert str (R1 ) == "Context for fq_default_poly with field: Context for fq_default in GF(11^3)[z]/(z^3 + 2*z + 9)"
3854+ assert str (R1 ) == str (R2 )
3855+ assert repr (R3 ) == "fq_default_poly_ctx(fq_default_ctx(13, 5, 'z', x^5 + 4*x + 11, 'FQ_NMOD'))"
3856+
3857+ assert R1 .characteristic () == 11
3858+ assert R3 .prime () == 13
3859+
3860+ assert R1 .zero ().is_zero ()
3861+ assert R1 .zero () == 0
3862+ assert R1 .one ().is_one ()
3863+ assert R1 .one () == 1
3864+ assert R1 .gen ().is_gen ()
3865+ assert R1 .gen () == R1 ([0 ,1 ])
3866+
3867+ # Random testing
3868+ f = R1 .random_element ()
3869+ assert f .degree () <= 3
3870+ f = R1 .random_element (degree = 5 , monic = True )
3871+ assert f .degree () <= 5
3872+ assert f .is_monic ()
3873+ f = R1 .random_element (degree = 100 , irreducible = True )
3874+ assert f .degree () <= 100
3875+ assert f .is_irreducible ()
3876+ f = R1 .random_element (degree = 1 , monic = True , irreducible = True )
3877+ assert f .degree () <= 1
3878+ assert f .is_irreducible ()
3879+ assert f .is_monic ()
3880+ assert raises (lambda : R1 .random_element (degree = - 123 ), ValueError )
3881+ assert raises (lambda : R1 .random_element (monic = "A" ), ValueError )
3882+ assert raises (lambda : R1 .random_element (irreducible = "A" ), ValueError )
3883+
3884+ # Conversion tests
3885+ F = fq_default_ctx (11 )
3886+ F_other = fq_default_ctx (13 )
3887+ R = fq_default_poly_ctx (F )
3888+ R_other = fq_default_poly_ctx (F_other )
3889+
3890+ assert raises (lambda : fq_default_poly (1 , "A" ), TypeError ) # Need a valid context
3891+ assert raises (lambda : R (R_other ([1 ,2 ,3 ])), ValueError ) # field must match
3892+ assert raises (lambda : R (F_other (2 )), ValueError ) # field must match
3893+ assert raises (lambda : R ([F (1 ), F_other (2 )]), ValueError ) # field must match
3894+ assert raises (lambda : R ([F (1 ), "A" ]), TypeError ) # need to be able to cast to fmpz_mod
3895+
3896+ f1 = R ([int (- 1 ),int (- 2 ),int (- 3 )])
3897+ f2 = R ([fmpz (- 1 ),fmpz (- 2 ),fmpz (- 3 )])
3898+ f3 = R ([F (- 1 ),F (- 2 ),F (- 3 )])
3899+ f4 = R (fmpz_poly ([- 1 , - 2 , - 3 ]))
3900+ f5 = R (f4 )
3901+
3902+ assert str (f1 ) == "8*x^2 + 9*x + 10"
3903+ assert str (f2 ) == "8*x^2 + 9*x + 10"
3904+ assert str (f3 ) == "8*x^2 + 9*x + 10"
3905+ assert str (f4 ) == "8*x^2 + 9*x + 10"
3906+ assert str (f5 ) == "8*x^2 + 9*x + 10"
3907+
3908+ f1 = R (5 )
3909+ f2 = R (fmpz (6 ))
3910+ f3 = R (F (7 ))
3911+ assert str (f1 ) == "5"
3912+ assert str (f2 ) == "6"
3913+ assert str (f3 ) == "7"
3914+
3915+ # Printing
3916+ f = R ([5 , 6 , 7 , 8 ])
3917+ assert str (f ) == "8*x^3 + 7*x^2 + 6*x + 5"
3918+
3919+ # Get and Set tests
3920+ f = R ([5 , 6 , 7 , 8 ])
3921+ assert f [0 ] == 5
3922+ assert repr (f [0 ]) == "5"
3923+ f [0 ] = 7
3924+ assert repr (f [0 ]) == "7"
3925+ assert str (f ) == "8*x^3 + 7*x^2 + 6*x + 7"
3926+
3927+ # TODO: currently repr does pretty printing
3928+ # just like str, we should address this. Mainly,
3929+ # the issue is we want nice `repr` behaviour in
3930+ # interactive shells, which currently is why this
3931+ # choice has been made
3932+ assert str (f ) == repr (f )
3933+
3934+ assert f [- 1 ] == 0
3935+ assert raises (lambda : f .__setitem__ (- 1 , 1 ), ValueError )
3936+ assert raises (lambda : f .__setitem__ (1 , "A" ), TypeError )
3937+
3938+ # Comparisons
3939+ f1 = R ([1 ,2 ,3 ])
3940+ f2 = R ([12 ,13 ,14 ])
3941+ f3 = R ([4 ,5 ,6 ])
3942+ f4 = R ([3 ])
3943+
3944+ assert (f1 == f2 ) is True
3945+ assert (f1 != f3 ) is True
3946+ assert (f1 != "1" ) is True
3947+ assert (f4 == 3 ) is True
3948+ assert (hash (f1 ) == hash (f2 )) is True
3949+ assert raises (lambda : f1 > f2 , TypeError )
3950+ assert raises (lambda : f1 >= f2 , TypeError )
3951+ assert raises (lambda : f1 < f2 , TypeError )
3952+ assert raises (lambda : f1 <= f2 , TypeError )
3953+
3954+ assert len (f1 ) == f1 .length () == 3
3955+ assert f1 .degree () == 2
3956+
3957+ f1 = R ([0 ])
3958+ f2 = R ([1 ])
3959+ f3 = R ([0 , 1 ])
3960+
3961+ assert f1 .is_zero () is True
3962+ assert f2 .is_one () is True
3963+ assert f3 .is_gen () is True
3964+
3965+ # Arithmetic
3966+ p_sml = 163
3967+ p_med = 1013
3968+ p_big = 2 ** 127 - 1
3969+
3970+ R_sml = fq_default_poly_ctx (p_sml )
3971+ R_med = fq_default_poly_ctx (p_med )
3972+ R_big = fq_default_poly_ctx (p_big )
3973+ R_sml_ext = fq_default_poly_ctx (p_sml , 5 )
3974+ R_med_ext = fq_default_poly_ctx (p_med , 3 )
3975+ R_big_ext = fq_default_poly_ctx (p_big , 2 )
3976+
3977+ F_cmp = fq_default_ctx (11 )
3978+ R_cmp = fq_default_poly_ctx (F_cmp )
3979+ f_cmp = R_cmp ([1 ,2 ,3 ,4 ,5 ])
3980+
3981+ for R_test in [R_sml , R_med , R_big , R_sml_ext , R_med_ext , R_big_ext ]:
3982+ F_test = R_test .base_field ()
3983+ while True :
3984+ nqr = F_test .random_element ()
3985+ if not nqr .is_square ():
3986+ break
3987+
3988+ f = R_test ([- 1 ,- 2 ])
3989+ g = R_test ([- 3 ,- 4 ])
3990+
3991+ # pos, neg
3992+ assert f is + f
3993+ assert - f == R_test ([1 ,2 ])
3994+
3995+ # add
3996+ assert raises (lambda : f + f_cmp , ValueError )
3997+ assert raises (lambda : f + "AAA" , TypeError )
3998+ assert raises (lambda : "AAA" + f , TypeError )
3999+ assert f + g == R_test ([- 4 ,- 6 ])
4000+ assert f + 1 == R_test ([0 ,- 2 ])
4001+ assert f + fmpz (1 ) == R_test ([0 ,- 2 ])
4002+ assert f + F_test (1 ) == R_test ([0 ,- 2 ])
4003+ assert 1 + f == R_test ([0 ,- 2 ])
4004+ assert fmpz (1 ) + f == R_test ([0 ,- 2 ])
4005+ assert F_test (1 ) + f == R_test ([0 ,- 2 ])
4006+
4007+ # sub
4008+ assert raises (lambda : f - f_cmp , ValueError )
4009+ assert raises (lambda : f - "AAA" , TypeError )
4010+ assert raises (lambda : "AAA" - f , TypeError )
4011+ assert f - g == R_test ([2 , 2 ])
4012+ assert f - 1 == R_test ([- 2 ,- 2 ])
4013+ assert f - fmpz (1 ) == R_test ([- 2 ,- 2 ])
4014+ assert f - F_test (1 ) == R_test ([- 2 ,- 2 ])
4015+ assert 1 - f == R_test ([2 , 2 ])
4016+ assert fmpz (1 ) - f == R_test ([2 , 2 ])
4017+ assert F_test (1 ) - f == R_test ([2 , 2 ])
4018+
4019+ # mul
4020+ assert raises (lambda : f * f_cmp , ValueError )
4021+ assert raises (lambda : f * "AAA" , TypeError )
4022+ assert raises (lambda : "AAA" * f , TypeError )
4023+ assert f * g == R_test ([3 , 4 + 6 , 8 ])
4024+ assert f * 2 == R_test ([- 2 ,- 4 ])
4025+ assert f * fmpz (2 ) == R_test ([- 2 ,- 4 ])
4026+ assert f * F_test (2 ) == R_test ([- 2 ,- 4 ])
4027+ assert 2 * f == R_test ([- 2 ,- 4 ])
4028+ assert fmpz (2 ) * f == R_test ([- 2 ,- 4 ])
4029+ assert F_test (2 ) * f == R_test ([- 2 ,- 4 ])
4030+
4031+ # Exact division
4032+ assert raises (lambda : f .exact_division (f_cmp ), ValueError )
4033+ assert raises (lambda : f .exact_division ("AAA" ), TypeError )
4034+ assert raises (lambda : f .exact_division (0 ), ZeroDivisionError )
4035+
4036+ assert (f * g ).exact_division (g ) == f
4037+ assert raises (lambda : f .exact_division (g ), DomainError )
4038+
4039+ # true div
4040+ assert raises (lambda : f / "AAA" , TypeError )
4041+ assert raises (lambda : f / 0 , ZeroDivisionError )
4042+
4043+ assert (f + f ) / 2 == f
4044+ assert (f + f ) / fmpz (2 ) == f
4045+ assert (f + f ) / F_test (2 ) == f
4046+
4047+ # floor div
4048+ assert raises (lambda : f // f_cmp , ValueError )
4049+ assert raises (lambda : f // "AAA" , TypeError )
4050+ assert raises (lambda : "AAA" // f , TypeError )
4051+ assert (f * g ) // g == f
4052+ assert (f + f ) // 2 == f
4053+ assert (f + f ) // fmpz (2 ) == f
4054+ assert (f + f ) // F_test (2 ) == f
4055+ assert 2 // R_test (2 ) == 1
4056+ assert (f + 1 ) // f == 1
4057+
4058+ # pow
4059+ assert raises (lambda : f ** (- 2 ), ValueError )
4060+ assert f * f == f ** 2
4061+ assert f * f == f ** fmpz (2 )
4062+
4063+ # pow_mod
4064+ # assert ui and fmpz exp agree for polynomials and generators
4065+ R_gen = R_test .gen ()
4066+ assert pow (f , 2 ** 60 , g ) == pow (pow (f , 2 ** 30 , g ), 2 ** 30 , g )
4067+ assert pow (R_gen , 2 ** 60 , g ) == pow (pow (R_gen , 2 ** 30 , g ), 2 ** 30 , g )
4068+
4069+ # Check other typechecks for pow_mod
4070+ assert raises (lambda : pow (f , - 2 , g ), ValueError )
4071+ assert raises (lambda : pow (f , 1 , "A" ), TypeError )
4072+ assert raises (lambda : pow (f , "A" , g ), TypeError )
4073+ assert raises (lambda : f .pow_mod (2 ** 32 , g , mod_rev_inv = "A" ), TypeError )
4074+
4075+ # Shifts
4076+ assert raises (lambda : R_test ([1 ,2 ,3 ]).left_shift (- 1 ), ValueError )
4077+ assert raises (lambda : R_test ([1 ,2 ,3 ]).right_shift (- 1 ), ValueError )
4078+ assert R_test ([1 ,2 ,3 ]).left_shift (3 ) == R_test ([0 ,0 ,0 ,1 ,2 ,3 ])
4079+ assert R_test ([1 ,2 ,3 ]).right_shift (1 ) == R_test ([2 ,3 ])
4080+
4081+ # Mod
4082+ assert raises (lambda : f % "AAA" , TypeError )
4083+ assert raises (lambda : tuple () % f , TypeError ), f'{ "AAA" % f = } '
4084+
4085+ assert f % 1 == 0
4086+ assert R_test .one () % 1 == 0
4087+ assert 100 % R_test .one () == 0
4088+ assert (f * g + 1 ) % f == 1
4089+ assert (f * g + g ) % f == (g % f )
4090+ assert f % R_test ([0 ,1 ]) == f .constant_coefficient ()
4091+
4092+ # Evaluation
4093+ h = R_test ([0 , 1 ])
4094+ assert h (1 ) == 1
4095+ assert h (- 1 ) == R_test .base_field ()(- 1 )
4096+ h = R_test ([0 , 0 , 1 ])
4097+ assert h (1 ) == h (- 1 )
4098+ assert raises (lambda : h ("AAA" ), TypeError )
4099+
4100+ # compose
4101+ assert raises (lambda : h .compose ("AAA" ), TypeError )
4102+
4103+ # compose mod
4104+ mod = R_test ([1 ,2 ,3 ,4 ])
4105+ assert f .compose (h ) % mod == f .compose_mod (h , mod )
4106+ assert raises (lambda : h .compose_mod ("AAA" , mod ), TypeError )
4107+ assert raises (lambda : h .compose_mod (f , "AAA" ), TypeError )
4108+ assert raises (lambda : h .compose_mod (f , R_test (0 )), ZeroDivisionError )
4109+
4110+ # Reverse
4111+ assert raises (lambda : h .reverse (degree = - 100 ), ValueError )
4112+ assert R_test ([- 1 ,- 2 ,- 3 ]).reverse () == R_test ([- 3 ,- 2 ,- 1 ])
4113+
4114+ # monic
4115+ assert R_test ([1 ,2 ]).monic () == R_test ([1 / F_test (2 ), 1 ])
4116+
4117+ # Square
4118+ assert f * f == f ** 2 == f .square ()
4119+
4120+ # mulmod
4121+ assert f .mul_mod (f , g ) == (f * f ) % g
4122+ assert raises (lambda : f .mul_mod (f , "AAA" ), TypeError )
4123+ assert raises (lambda : f .mul_mod ("AAA" , g ), TypeError )
4124+
4125+ # pow_mod
4126+ assert f .pow_mod (2 , g ) == (f * f ) % g
4127+ assert raises (lambda : f .pow_mod (2 , "AAA" ), TypeError )
4128+
4129+ # divmod
4130+ S , T = f .divmod (g )
4131+ assert S * g + T == f
4132+ assert raises (lambda : f .divmod ("AAA" ), TypeError )
4133+
4134+ # gcd
4135+ assert raises (lambda : f .gcd ("f" ), TypeError )
4136+
4137+ # xgcd
4138+ assert raises (lambda : (f ).xgcd ("f_cmp" ), TypeError )
4139+
4140+ f_inv = f .inverse_series_trunc (2 )
4141+ assert (f * f_inv ) % R_test ([0 ,0 ,1 ]) == 1
4142+ assert raises (lambda : R_test ([0 ,1 ]).inverse_series_trunc (2 ), ZeroDivisionError )
4143+
4144+ # sqrt
4145+ f1 = R_test .random_element (irreducible = True )
4146+ assert raises (lambda : f1 .sqrt (), ValueError )
4147+ assert (f1 * f1 ).sqrt () in [f1 , - f1 ]
4148+
4149+ # sqrt series
4150+ f_non_square = R_test ([nqr , 1 , 1 , 1 ])
4151+ f_zero = R_test ([0 , 1 , 1 , 1 ])
4152+ assert raises (lambda : f_non_square .sqrt_trunc (1 ), ValueError )
4153+ assert raises (lambda : f_zero .sqrt_trunc (1 ), ZeroDivisionError )
4154+ assert raises (lambda : f_non_square .inv_sqrt_trunc (1 ), ValueError )
4155+ assert raises (lambda : f_zero .inv_sqrt_trunc (1 ), ZeroDivisionError )
4156+
4157+ # deflation
4158+ f1 = R_test ([1 ,0 ,2 ,0 ,3 ])
4159+ assert raises (lambda : f1 .deflate (100 ), ValueError )
4160+ assert f1 .deflate (2 ) == R_test ([1 ,2 ,3 ])
4161+
4162+ # factor
4163+ ff = R_test ([3 ,2 ,1 ]) * R_test ([3 ,2 ,1 ]) * R_test ([5 ,4 ,3 ])
4164+ ff_rebuild = R_test .one ()
4165+ c , facs = ff .factor ()
4166+ ff_rebuild *= c
4167+ for p , e in facs :
4168+ assert p .is_irreducible ()
4169+ ff_rebuild *= p ** e
4170+ assert ff_rebuild == ff
4171+
4172+ assert set (ff .factor ()[1 ]) == set (ff .factor ()[1 ])
4173+ assert raises (lambda : R_test ([0 ,0 ,1 ]).complex_roots (), DomainError )
4174+
4175+ # truncate things
4176+ f = R_test .random_element ()
4177+ g = R_test .random_element ()
4178+ h = R_test .random_element ()
4179+ x = R_test .gen ()
4180+ f_trunc = f % x ** 3
4181+
4182+ assert f .equal_trunc (f_trunc , 3 )
4183+ assert not f .equal_trunc ("A" , 3 )
4184+ assert not f .equal_trunc (f_cmp , 3 )
4185+
4186+ assert raises (lambda : f .add_trunc ("A" , 1 ), TypeError )
4187+ assert raises (lambda : f .add_trunc (f_cmp , 1 ), ValueError )
4188+ assert f .add_trunc (g , 3 ) == (f + g ) % x ** 3
4189+
4190+ assert raises (lambda : f .sub_trunc ("A" , 1 ), TypeError )
4191+ assert raises (lambda : f .sub_trunc (f_cmp , 1 ), ValueError )
4192+ assert f .sub_trunc (g , 3 ) == (f - g ) % x ** 3
4193+
4194+ assert raises (lambda : f .mul_low ("A" , h ), TypeError )
4195+ assert raises (lambda : f .mul_low (g , "A" ), TypeError )
4196+ assert f .mul_low (g , 3 ) == (f * g ) % x ** 3
4197+
4198+ assert raises (lambda : f .pow_trunc (- 1 , 5 ), ValueError )
4199+
38294200def test_all_tests ():
38304201 test_funcs = {f for name , f in globals ().items () if name .startswith ("test_" )}
38314202 untested = test_funcs - set (all_tests )
@@ -3892,6 +4263,7 @@ def test_all_tests():
38924263 test_matrices_solve ,
38934264
38944265 test_fq_default ,
4266+ test_fq_default_poly ,
38954267
38964268 test_arb ,
38974269
0 commit comments