Skip to content

Commit 00ddb74

Browse files
committed
Reduce multiplication depth in _gr_poly_compose_axnc
1 parent c0d1790 commit 00ddb74

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

src/gr_generic/generic.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,23 +2612,32 @@ gr_generic_vec_dot_fmpz(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr v
26122612
int
26132613
gr_generic_vec_set_powers(gr_ptr res, gr_srcptr x, slong len, gr_ctx_t ctx)
26142614
{
2615+
int status = GR_SUCCESS;
2616+
slong sz = ctx->sizeof_elem;
2617+
if (len <= 0) return status;
2618+
status |= gr_one(GR_ENTRY(res, 0, sz), ctx);
2619+
if (len <= 1) return status;
2620+
status |= gr_set(GR_ENTRY(res, 1, sz), x, ctx);
2621+
if (len <= 2) return status;
2622+
26152623
gr_method_binary_op mul = GR_BINARY_OP(ctx, MUL);
26162624
gr_method_unary_op sqr = GR_UNARY_OP(ctx, SQR);
2617-
int status = GR_SUCCESS;
26182625
slong i;
2619-
slong sz = ctx->sizeof_elem;;
26202626

2621-
for (i = 0; i < len; i++)
2627+
/* Prefer squaring for powers? */
2628+
if (gr_ctx_is_finite(ctx) == T_TRUE || gr_ctx_has_real_prec(ctx) == T_TRUE)
26222629
{
2623-
if (i == 0)
2624-
status |= gr_one(GR_ENTRY(res, i, sz), ctx);
2625-
else if (i == 1)
2626-
status |= gr_set(GR_ENTRY(res, i, sz), x, ctx);
2627-
else if (i % 2 == 0)
2628-
status |= sqr(GR_ENTRY(res, i, sz), GR_ENTRY(res, i / 2, sz), ctx);
2629-
else
2630-
status |= mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i - 1, sz), x, ctx);
2630+
for (i = 2; i < len; i++)
2631+
{
2632+
if (i % 2 == 0)
2633+
status |= sqr(GR_ENTRY(res, i, sz), GR_ENTRY(res, i / 2, sz), ctx);
2634+
else
2635+
status |= mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i - 1, sz), x, ctx);
2636+
}
26312637
}
2638+
else
2639+
for (i = 2; i < len; i++)
2640+
status |= mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i - 1, sz), x, ctx);
26322641

26332642
return status;
26342643
}

src/gr_poly/compose.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "gr_vec.h"
1515
#include "gr_poly.h"
16+
#include "longlong.h"
1617

1718
/* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */
1819
static int
@@ -39,19 +40,48 @@ _gr_poly_compose_axnc(gr_ptr res, gr_srcptr poly1, slong len1,
3940
}
4041
else
4142
{
42-
gr_ptr t;
43-
GR_TMP_INIT(t, ctx);
44-
45-
status |= gr_set(t, a, ctx);
46-
47-
for (i = 1; i < len1; i++)
43+
int maxbit = FLINT_CLOG2(len1);
44+
gr_ptr pw, t;
45+
/* Prefer squaring for powers? cf. _gr_vec_set_powers */
46+
if (gr_ctx_is_finite(ctx) == T_TRUE || gr_ctx_has_real_prec(ctx) == T_TRUE)
4847
{
49-
status |= gr_mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i, sz), t, ctx);
50-
if (i + 1 < len1)
51-
status |= gr_mul(t, t, a, ctx);
48+
GR_TMP_INIT_VEC(pw, maxbit, ctx);
49+
GR_TMP_INIT_VEC(t, maxbit, ctx);
50+
51+
status |= gr_set(GR_ENTRY(pw, 0, sz), a, ctx);
52+
status |= gr_mul(GR_ENTRY(res, 1, sz), GR_ENTRY(res, 1, sz), a, ctx);
53+
for (i = 2; i < len1; i++)
54+
{
55+
int j = flint_ctz(i);
56+
if (i == ((slong)1 << j))
57+
{
58+
status |= gr_sqr(GR_ENTRY(pw, j, sz), GR_ENTRY(pw, j-1, sz), ctx);
59+
status |= gr_set(GR_ENTRY(t, j, sz), GR_ENTRY(pw, j, sz), ctx);
60+
}
61+
else
62+
status |= gr_mul(GR_ENTRY(t, j, sz), GR_ENTRY(t, flint_ctz(i - ((slong)1 << j)), sz),
63+
GR_ENTRY(pw, j, sz), ctx);
64+
status |= gr_mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i, sz), GR_ENTRY(t, j, sz), ctx);
65+
}
66+
67+
GR_TMP_CLEAR_VEC(pw, maxbit, ctx);
68+
GR_TMP_CLEAR_VEC(t, maxbit, ctx);
5269
}
70+
else
71+
{
72+
GR_TMP_INIT(t, ctx);
5373

54-
GR_TMP_CLEAR(t, ctx);
74+
status |= gr_set(t, a, ctx);
75+
76+
for (i = 1; i < len1; i++)
77+
{
78+
status |= gr_mul(GR_ENTRY(res, i, sz), GR_ENTRY(res, i, sz), t, ctx);
79+
if (i + 1 < len1)
80+
status |= gr_mul(t, t, a, ctx);
81+
}
82+
83+
GR_TMP_CLEAR(t, ctx);
84+
}
5585
}
5686
}
5787

src/gr_poly/compose_series_brent_kung.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ _gr_poly_compose_series_brent_kung(gr_ptr res, gr_srcptr poly1, slong len1,
4646
status |= _gr_vec_set(Brow(i), GR_ENTRY(poly1, i * m, sz), m, ctx);
4747
status |= _gr_vec_set(Brow(i), GR_ENTRY(poly1, i * m, sz), len1 % m, ctx);
4848

49-
/* Set rows of A to powers of poly2 */
49+
/* Set rows of A to powers of poly2 (cf. _gr_vec_set_powers) */
5050
status |= gr_one(Arow(0), ctx);
5151
status |= _gr_vec_set(Arow(1), poly2, len2, ctx);
5252

0 commit comments

Comments
 (0)