1212#include "flint.h"
1313#include "gr.h"
1414#include "gr_ore_poly.h"
15+ #include "gr_vec.h"
1516
1617// Returns the unique pair (Q, R) such that U = QV + R and ord(R) < ord(V)
1718int _gr_ore_poly_divrem (gr_ptr Q , gr_ptr R , gr_srcptr U , slong lenU , gr_srcptr V , slong lenV , gr_ore_poly_ctx_t ctx )
@@ -21,25 +22,18 @@ int _gr_ore_poly_divrem(gr_ptr Q, gr_ptr R, gr_srcptr U, slong lenU, gr_srcptr V
2122 slong lenQ , lenR , ordV , ordR ;
2223 int status = GR_SUCCESS ;
2324
24- if (GR_ORE_POLY_CTX (ctx )-> sigma_delta == NULL )
25- return GR_UNABLE ;
26-
2725 lenQ = lenU - lenV + 1 ;
2826 lenR = lenU ;
2927 ordV = lenV - 1 ;
3028 ordR = lenR - 1 ;
3129
3230 // Set Q to 0
33- for (slong k = 0 ; k < lenQ ; k ++ )
34- status |= gr_zero (GR_ENTRY (Q , k , el_size ), cctx );
31+ status |= _gr_vec_zero (Q , lenQ , cctx );
3532
3633 // Set R to U
37- for (slong k = 0 ; k < lenU ; k ++ )
38- status |= gr_set (GR_ENTRY (R , k , el_size ), GR_ENTRY (U , k , el_size ), cctx );
34+ status |= _gr_vec_set (R , U , lenU , cctx );
3935
40- gr_ptr lcR , lcV , denominator , c ;
41- GR_TMP_INIT (lcR , cctx );
42- GR_TMP_INIT (lcV , cctx );
36+ gr_ptr denominator , c ;
4337 GR_TMP_INIT (denominator , cctx );
4438 GR_TMP_INIT (c , cctx );
4539
@@ -48,20 +42,21 @@ int _gr_ore_poly_divrem(gr_ptr Q, gr_ptr R, gr_srcptr U, slong lenU, gr_srcptr V
4842 _gr_vec_init (A , lenQ , cctx );
4943 _gr_vec_init (B , lenU , cctx );
5044
45+ for (slong i = 0 ; i < ordR - ordV + 1 ; i ++ )
46+ status |= gr_zero (GR_ENTRY (A , i , el_size ), cctx );
47+
48+ gr_ptr sigma_pows = flint_malloc (lenQ * el_size );
49+ _gr_vec_init (sigma_pows , lenQ , cctx );
50+ status |= gr_set (GR_ENTRY (sigma_pows , 0 , el_size ), GR_ENTRY (V , ordV , el_size ), cctx );
51+ for (slong i = 1 ; i < lenQ ; i ++ )
52+ status |= gr_ore_poly_sigma (GR_ENTRY (sigma_pows , i , el_size ), GR_ENTRY (sigma_pows , i - 1 , el_size ), ctx );
53+
5154 while (ordR > ordV )
5255 {
5356 slong k = ordR - ordV ;
5457
55- status |= gr_set (lcR , GR_ENTRY (R , ordR , el_size ), cctx );
56- status |= gr_set (lcV , GR_ENTRY (V , ordV , el_size ), cctx );
57-
58- // Compute denominator = sigma ^ k (lc(V))
59- status |= gr_set (denominator , lcV , cctx );
60- for (slong i = 0 ; i < k ; i ++ )
61- status |= gr_ore_poly_sigma (denominator , denominator , ctx );
62-
63- // c = lc(R) / denominator
64- status |= gr_div (c , lcR , denominator , cctx );
58+ // c = lc(R) / sigma ^ k (lc(V)) using sigma_pows computed above
59+ status |= gr_div (c , GR_ENTRY (R , ordR , el_size ), GR_ENTRY (sigma_pows , k , el_size ), cctx );
6560
6661 // R -= c * x^k * V. We compute A = c * x^k, then B = A * V
6762 // A = c * x^k, so A[k] = c, rest 0
@@ -84,9 +79,8 @@ int _gr_ore_poly_divrem(gr_ptr Q, gr_ptr R, gr_srcptr U, slong lenU, gr_srcptr V
8479 ordR -- ;
8580 }
8681
87- gr_clear (lcR , cctx );
88- gr_clear (lcV , cctx );
89- gr_clear (denominator , cctx );
82+ _gr_vec_clear (sigma_pows , lenQ , cctx );
83+ flint_free (sigma_pows );
9084 gr_clear (c , cctx );
9185
9286 _gr_vec_clear (A , lenQ , cctx );
@@ -115,19 +109,14 @@ int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U,
115109
116110 if (lenU < lenV )
117111 {
118- gr_ore_poly_t tU ;
119- // take care of aliasing case with temp
120- gr_ore_poly_init (tU , ctx );
121- status |= gr_ore_poly_set (tU , U , ctx );
112+ status |= gr_ore_poly_set (R , U , ctx );
122113 status |= gr_ore_poly_zero (Q , ctx );
123- status |= gr_ore_poly_set (R , tU , ctx );
124- gr_ore_poly_clear (tU , ctx );
125114 return status ;
126115 }
127116
128117 slong lenQ = lenU - lenV + 1 ;
129118
130- if (Q == U || Q == V || R == U || R == V ) // treat aliasing case separately
119+ if (Q == U || Q == V || R == U || R == V || Q == R ) // treat aliasing case separately
131120 {
132121 gr_ore_poly_t tQ , tR ;
133122 gr_ore_poly_init (tQ , ctx );
@@ -158,3 +147,23 @@ int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U,
158147 }
159148 return status ;
160149}
150+
151+ int gr_ore_poly_div (gr_ore_poly_t Q , const gr_ore_poly_t U , gr_ore_poly_t V , gr_ore_poly_ctx_t ctx )
152+ {
153+ gr_ore_poly_t R ;
154+ int status ;
155+ gr_ore_poly_init (R , ctx );
156+ status = gr_ore_poly_divrem (Q , R , U , V , ctx );
157+ gr_ore_poly_clear (R , ctx );
158+ return status ;
159+ }
160+
161+ int gr_ore_poly_rem (gr_ore_poly_t R , const gr_ore_poly_t U , gr_ore_poly_t V , gr_ore_poly_ctx_t ctx )
162+ {
163+ gr_ore_poly_t Q ;
164+ int status ;
165+ gr_ore_poly_init (Q , ctx );
166+ status = gr_ore_poly_divrem (Q , R , U , V , ctx );
167+ gr_ore_poly_clear (Q , ctx );
168+ return status ;
169+ }
0 commit comments