@@ -3826,6 +3826,377 @@ def test_fq_default():
3826
3826
3827
3827
assert (a * a ).is_square ()
3828
3828
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
+
3829
4200
def test_all_tests ():
3830
4201
test_funcs = {f for name , f in globals ().items () if name .startswith ("test_" )}
3831
4202
untested = test_funcs - set (all_tests )
@@ -3892,6 +4263,7 @@ def test_all_tests():
3892
4263
test_matrices_solve ,
3893
4264
3894
4265
test_fq_default ,
4266
+ test_fq_default_poly ,
3895
4267
3896
4268
test_arb ,
3897
4269
0 commit comments