Skip to content

Commit f8d29f3

Browse files
committed
Comments on division with remainder resolved
1 parent 58e36ff commit f8d29f3

5 files changed

Lines changed: 60 additions & 52 deletions

File tree

doc/source/gr_ore_poly.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,14 @@ Arithmetic
324324

325325
Sets *(Q, R)* to the unique pair such that `U = QV + R` and `ord(R) < ord(V)`.
326326

327+
.. function:: int _gr_ore_poly_div(gr_ptr Q, gr_srcptr U, slong lenU, gr_srcptr V, slong lenV, gr_ore_poly_ctx_t ctx)
328+
329+
Version of the divrem function which outputs only the quotient.
330+
331+
.. function:: int _gr_ore_poly_rem(gr_ptr R, gr_srcptr U, slong lenU, gr_srcptr V, slong lenV, gr_ore_poly_ctx_t ctx)
332+
333+
Version of the divrem function which outputs only the remainder.
334+
327335
.. raw:: latex
328336

329337
\newpage

src/gr_ore_poly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ WARN_UNUSED_RESULT int gr_ore_poly_mul(gr_ore_poly_t res, const gr_ore_poly_t po
282282

283283
WARN_UNUSED_RESULT int _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);
284284
WARN_UNUSED_RESULT int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U, gr_ore_poly_t V, gr_ore_poly_ctx_t ctx);
285+
WARN_UNUSED_RESULT 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);
286+
WARN_UNUSED_RESULT 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);
285287

286288
#ifdef __cplusplus
287289
}

src/gr_ore_poly/ctx.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,11 @@ gr_method_tab_input _gr_ore_poly_methods_input[] =
296296
{GR_METHOD_POW_FMPZ, (gr_funcptr) gr_ore_poly_pow_fmpz},
297297
{GR_METHOD_DIV, (gr_funcptr) gr_ore_poly_div},
298298
{GR_METHOD_INV, (gr_funcptr) gr_ore_poly_inv},
299-
300-
{GR_METHOD_EUCLIDEAN_DIV, (gr_funcptr) gr_ore_poly_euclidean_div},
301-
{GR_METHOD_EUCLIDEAN_REM, (gr_funcptr) gr_ore_poly_euclidean_rem},
302-
{GR_METHOD_EUCLIDEAN_DIVREM, (gr_funcptr) gr_ore_poly_euclidean_divrem},
303-
299+
*/
300+
{GR_METHOD_EUCLIDEAN_DIV, (gr_funcptr) gr_ore_poly_div},
301+
{GR_METHOD_EUCLIDEAN_REM, (gr_funcptr) gr_ore_poly_rem},
302+
{GR_METHOD_EUCLIDEAN_DIVREM, (gr_funcptr) gr_ore_poly_divrem},
303+
/*
304304
{GR_METHOD_GCD, (gr_funcptr) gr_ore_poly_gcd},
305305
306306
{GR_METHOD_FACTOR, (gr_funcptr) gr_ore_poly_factor},

src/gr_ore_poly/divrem.c

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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)
1718
int _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+
}

src/gr_ore_poly/test/t-divrem.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313
#include "ulong_extras.h"
1414
#include "gr_ore_poly.h"
1515

16-
TEST_FUNCTION_START(gr_ore_poly_divrem, state)
16+
TEST_GR_FUNCTION_START(gr_ore_poly_divrem, state, count_success, count_domain, count_unable)
1717
{
1818
slong iter;
19-
// slong success = 0, domain = 0, unable = 0, combined = 0;
2019
for (iter = 0; iter < 3000 * flint_test_multiplier(); iter++)
2120
{
2221
int status = GR_SUCCESS;
@@ -45,7 +44,7 @@ TEST_FUNCTION_START(gr_ore_poly_divrem, state)
4544

4645
if (status == GR_SUCCESS)
4746
{
48-
/* test aliasing */
47+
// test aliasing
4948
switch (n_randint(state, 5))
5049
{
5150
case 0:
@@ -84,18 +83,12 @@ TEST_FUNCTION_START(gr_ore_poly_divrem, state)
8483
flint_printf("Q*B + R = "); gr_ore_poly_print(QBR, ore_ctx); flint_printf("\n");
8584
flint_abort();
8685
}
87-
// success++;
8886
}
8987
}
9088

91-
/*if (status == GR_DOMAIN)
92-
domain++;
93-
94-
if (status == GR_UNABLE)
95-
unable++;
96-
97-
if (status == 3)
98-
combined++;*/
89+
count_success += (status == GR_SUCCESS);
90+
count_domain += ((status & GR_DOMAIN) != 0);
91+
count_unable += ((status & GR_UNABLE) != 0);
9992

10093
gr_ore_poly_clear(A, ore_ctx);
10194
gr_ore_poly_clear(B, ore_ctx);
@@ -106,9 +99,5 @@ TEST_FUNCTION_START(gr_ore_poly_divrem, state)
10699
gr_ore_poly_ctx_clear(ore_ctx);
107100
gr_ctx_clear(ctx);
108101
}
109-
/*flint_printf("GR_SUCCESS = %d\n", success);
110-
flint_printf("GR_DOMAIN = %d\n", domain);
111-
flint_printf("GR_UNABLE = %d\n", unable);
112-
flint_printf("Combined (3) = %d\n", combined);*/
113-
TEST_FUNCTION_END(state);
102+
TEST_GR_FUNCTION_END(state, count_success, count_domain, count_unable);
114103
}

0 commit comments

Comments
 (0)