Skip to content

Commit 45c867a

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

5 files changed

Lines changed: 65 additions & 67 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: 44 additions & 45 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,78 +22,61 @@ 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);
43-
GR_TMP_INIT(denominator, cctx);
36+
gr_ptr c;
4437
GR_TMP_INIT(c, cctx);
4538

46-
gr_ptr A = flint_malloc(lenQ * el_size);
47-
gr_ptr B = flint_malloc(lenU * el_size);
48-
_gr_vec_init(A, lenQ, cctx);
49-
_gr_vec_init(B, lenU, cctx);
39+
gr_ptr A, B;
40+
GR_TMP_INIT_VEC(A, lenQ, cctx);
41+
GR_TMP_INIT_VEC(B, lenU, cctx);
42+
43+
gr_ptr sigma_pows;
44+
GR_TMP_INIT_VEC(sigma_pows, lenQ, cctx);
45+
status |= gr_set(GR_ENTRY(sigma_pows, 0, el_size), GR_ENTRY(V, ordV, el_size), cctx);
46+
for (slong i = 1; i < lenQ; i++)
47+
status |= gr_ore_poly_sigma(GR_ENTRY(sigma_pows, i, el_size), GR_ENTRY(sigma_pows, i - 1, el_size), ctx);
5048

5149
while (ordR > ordV)
5250
{
5351
slong k = ordR - ordV;
5452

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);
53+
// c = lc(R) / sigma ^ k (lc(V)) using sigma_pows computed above
54+
status |= gr_div(c, GR_ENTRY(R, ordR, el_size), GR_ENTRY(sigma_pows, k, el_size), cctx);
6555

6656
// R -= c * x^k * V. We compute A = c * x^k, then B = A * V
6757
// A = c * x^k, so A[k] = c, rest 0
6858
slong lenA = k + 1;
69-
for (slong i = 0; i < lenA; i++)
70-
status |= gr_zero(GR_ENTRY(A, i, el_size), cctx);
59+
status |= _gr_vec_zero(A, lenA, cctx);
7160
status |= gr_set(GR_ENTRY(A, k, el_size), c, cctx);
7261

7362
// B = A * V
7463
status |= _gr_ore_poly_mul(B, A, lenA, V, lenV, ctx);
7564

7665
// R -= B
7766
slong lenB = lenA + lenV - 1;
78-
for (slong i = 0; i < lenB; i++)
79-
status |= gr_sub(GR_ENTRY(R, i, el_size), GR_ENTRY(R, i, el_size), GR_ENTRY(B, i, el_size), cctx);
80-
67+
status |= _gr_vec_sub(R, R, B, lenB, cctx);
68+
8169
// Q += c * x^k, so Q[k] += c
8270
status |= gr_add(GR_ENTRY(Q, k, el_size), GR_ENTRY(Q, k, el_size), c, cctx);
8371

8472
ordR--;
8573
}
8674

87-
gr_clear(lcR, cctx);
88-
gr_clear(lcV, cctx);
89-
gr_clear(denominator, cctx);
90-
gr_clear(c, cctx);
75+
GR_TMP_CLEAR_VEC(sigma_pows, lenQ, cctx);
76+
GR_TMP_CLEAR(c, cctx);
9177

92-
_gr_vec_clear(A, lenQ, cctx);
93-
_gr_vec_clear(B, lenU, cctx);
94-
flint_free(A);
95-
flint_free(B);
78+
GR_TMP_CLEAR_VEC(A, lenQ, cctx);
79+
GR_TMP_CLEAR_VEC(B, lenU, cctx);
9680

9781
return status;
9882
}
@@ -115,19 +99,14 @@ int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U,
11599

116100
if (lenU < lenV)
117101
{
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);
102+
status |= gr_ore_poly_set(R, U, ctx);
122103
status |= gr_ore_poly_zero(Q, ctx);
123-
status |= gr_ore_poly_set(R, tU, ctx);
124-
gr_ore_poly_clear(tU, ctx);
125104
return status;
126105
}
127106

128107
slong lenQ = lenU - lenV + 1;
129108

130-
if (Q == U || Q == V || R == U || R == V) // treat aliasing case separately
109+
if (Q == U || Q == V || R == U || R == V || Q == R) // treat aliasing case separately
131110
{
132111
gr_ore_poly_t tQ, tR;
133112
gr_ore_poly_init(tQ, ctx);
@@ -158,3 +137,23 @@ int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U,
158137
}
159138
return status;
160139
}
140+
141+
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)
142+
{
143+
gr_ore_poly_t R;
144+
int status;
145+
gr_ore_poly_init(R, ctx);
146+
status = gr_ore_poly_divrem(Q, R, U, V, ctx);
147+
gr_ore_poly_clear(R, ctx);
148+
return status;
149+
}
150+
151+
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)
152+
{
153+
gr_ore_poly_t Q;
154+
int status;
155+
gr_ore_poly_init(Q, ctx);
156+
status = gr_ore_poly_divrem(Q, R, U, V, ctx);
157+
gr_ore_poly_clear(Q, ctx);
158+
return status;
159+
}

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)