Skip to content

Commit d58f296

Browse files
Middle product for fmpz_poly (#2610)
* Middle product for fmpz_poly: classical, KS, SS * Use _fmpz_poly_mulmid in some places
1 parent 633ec99 commit d58f296

27 files changed

+1243
-650
lines changed

doc/source/fmpz_poly.rst

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -592,15 +592,19 @@ Bit packing
592592
``bit_size``, negating the coefficients before packing
593593
if ``negate`` is set to `-1`.
594594

595-
.. function:: int _fmpz_poly_bit_unpack(fmpz * poly, slong len, nn_srcptr arr, flint_bitcnt_t bit_size, int negate)
595+
.. function:: int _fmpz_poly_bit_unpack(fmpz * poly, slong nlo, slong nhi, nn_srcptr arr, flint_bitcnt_t bit_size, int negate)
596596

597-
Unpacks the polynomial of given length from the array as packed into
597+
Unpacks the polynomial of given length `nhi` from the array as packed into
598598
fields of the given ``bit_size``, finally negating the coefficients
599599
if ``negate`` is set to `-1`. Returns borrow, which is nonzero if a
600600
leading term with coefficient `\pm1` should be added at
601-
position ``len`` of ``poly``.
601+
position ``nhi`` of ``poly``.
602+
603+
If `nlo` is zero, all coefficients are unpacked; otherwise the
604+
coefficients in the range `[nlo, nhi)` are unpacked and written to
605+
indices `[0, nhi-nlo)` in ``poly``.
602606

603-
.. function:: void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len, nn_srcptr arr, flint_bitcnt_t bit_size)
607+
.. function:: void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong nlo, slong nhi, nn_srcptr arr, flint_bitcnt_t bit_size)
604608

605609
Unpacks the polynomial of given length from the array as packed into
606610
fields of the given ``bit_size``. The coefficients are assumed to
@@ -669,19 +673,24 @@ Multiplication
669673
remainder to the corresponding coefficients of the product of ``poly1``
670674
and ``poly2``.
671675

672-
.. function:: void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2)
676+
.. function:: void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi)
677+
void _fmpz_poly_mulmid_KS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi)
678+
void _fmpz_poly_mulmid_SS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi)
679+
void _fmpz_poly_mulmid(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi)
673680

674-
Sets ``res`` to the middle ``len1 - len2 + 1`` coefficients of
675-
the product of ``(poly1, len1)`` and ``(poly2, len2)``, i.e. the
676-
coefficients from degree ``len2 - 1`` to ``len1 - 1`` inclusive.
677-
Assumes that ``len1 >= len2 > 0``.
681+
Sets ``(res, nhi - nlo)`` to the coefficients at indices `[nlo, nhi)`
682+
in the full product of ``(poly1, len1)`` and ``(poly2, len2)``.
683+
Assumes that ``len1`` and ``len2`` are positive and that
684+
`0 \le nlo < nhi \le len1 + len2 - 1`.
678685

679686
.. function:: void fmpz_poly_mulmid_classical(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2)
687+
void fmpz_poly_mulmid_KS(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2)
688+
void fmpz_poly_mulmid_SS(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2)
689+
void fmpz_poly_mulmid(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2)
680690

681-
Sets ``res`` to the middle ``len(poly1) - len(poly2) + 1``
682-
coefficients of ``poly1 * poly2``, i.e. the coefficient from degree
683-
``len2 - 1`` to ``len1 - 1`` inclusive. Assumes that
684-
``len1 >= len2``.
691+
Sets ``res`` to the polynomial formed by the coefficients at indices `[nlo, nhi)`
692+
in the product of ``poly1`` and ``poly2``. Equivalently, compute
693+
`[(poly1 \cdot poly2) \bmod x^{nhi}] / x^{nlo}`.
685694

686695
.. function:: void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2)
687696

@@ -748,10 +757,10 @@ Multiplication
748757
Sets ``res`` to the lowest `n` coefficients of the product of
749758
``poly1`` and ``poly2``.
750759

751-
.. function:: void _fmpz_poly_mul_SS(fmpz * output, const fmpz * input1, slong length1, const fmpz * input2, slong length2)
760+
.. function:: void _fmpz_poly_mul_SS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2)
752761

753-
Sets ``(output, length1 + length2 - 1)`` to the product of
754-
``(input1, length1)`` and ``(input2, length2)``.
762+
Sets ``(res, len1 + len2 - 1)`` to the product of
763+
``(poly1, len1)`` and ``(poly2, len2)``.
755764

756765
We must have ``len1 > 1`` and ``len2 > 1``. Allows zero-padding
757766
of the two input polynomials. Supports aliasing of inputs and outputs.
@@ -761,7 +770,7 @@ Multiplication
761770
Sets ``res`` to the product of ``poly1`` and ``poly2``. Uses the
762771
Schönhage-Strassen algorithm.
763772

764-
.. function:: void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong length1, const fmpz * input2, slong length2, slong n)
773+
.. function:: void _fmpz_poly_mullow_SS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong n)
765774

766775
Sets ``(res, n)`` to the lowest `n` coefficients of the product of
767776
``(poly1, len1)`` and ``(poly2, len2)``.
@@ -783,7 +792,6 @@ Multiplication
783792
zero-padding of the two input polynomials. Does not support aliasing
784793
between the inputs and the output.
785794

786-
787795
.. function:: void fmpz_poly_mul(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2)
788796

789797
Sets ``res`` to the product of ``poly1`` and ``poly2``. Chooses

src/fmpq_poly/exp_series.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ static void _fmpq_poly_integral_offset(fmpz * rpoly, fmpz_t rden,
194194
static void
195195
MULLOW(fmpz * z, fmpz_t zden, const fmpz * x, const fmpz_t xden, slong xn, const fmpz * y, const fmpz_t yden, slong yn, slong n)
196196
{
197-
if (xn + yn - 1 < n)
198-
flint_throw(FLINT_ERROR, "(%s)\n", __func__);
197+
FLINT_ASSERT(xn + yn - 1 >= n);
199198

200199
if (xn >= yn)
201200
_fmpz_poly_mullow(z, x, xn, y, yn, n);
@@ -205,6 +204,15 @@ MULLOW(fmpz * z, fmpz_t zden, const fmpz * x, const fmpz_t xden, slong xn, const
205204
fmpz_mul(zden, xden, yden);
206205
}
207206

207+
static void
208+
MULMID(fmpz * z, fmpz_t zden, const fmpz * x, const fmpz_t xden, slong xn, const fmpz * y, const fmpz_t yden, slong yn, slong nlo, slong nhi)
209+
{
210+
FLINT_ASSERT(xn + yn - 1 >= nhi);
211+
212+
_fmpz_poly_mulmid(z, x, xn, y, yn, nlo, nhi);
213+
fmpz_mul(zden, xden, yden);
214+
}
215+
208216
/* Assuming that the low m coefficients of poly have denominator
209217
den in canonical form and that the high n - m coefficients have
210218
denominator high_den in canonical form, combine the high and lower
@@ -309,9 +317,9 @@ _fmpq_poly_exp_series_newton(fmpz * f, fmpz_t fden,
309317
CONCATENATE(hprime, hprimeden, uden, m - 1, l);
310318
}
311319

312-
MULLOW(t, tden, hprime, hprimeden, l, f, fden, m, r);
313-
_fmpq_poly_canonicalise(t + m - 1, tden, r + 1 - m);
314-
MULLOW(g + m, uden, g, gden, n - m, t + m - 1, tden, r + 1 - m, n - m);
320+
MULMID(t, tden, hprime, hprimeden, l, f, fden, m, m - 1, r);
321+
_fmpq_poly_canonicalise(t, tden, r + 1 - m);
322+
MULLOW(g + m, uden, g, gden, n - m, t, tden, r + 1 - m, n - m);
315323
_fmpq_poly_canonicalise(g + m, uden, n - m);
316324
_fmpq_poly_integral_offset(g + m, uden, g + m, uden, n - m, m);
317325
MULLOW(f + m, uden, f, fden, n - m, g + m, uden, n - m, n - m);
@@ -323,9 +331,9 @@ _fmpq_poly_exp_series_newton(fmpz * f, fmpz_t fden,
323331
/* g := exp(-h) + O(x^n); not needed if we only want exp(x) */
324332
if (i != 0 || inverse)
325333
{
326-
MULLOW(t, tden, f, fden, n, g, gden, m, n);
327-
_fmpq_poly_canonicalise(t + m, tden, n - m);
328-
MULLOW(g + m, uden, g, gden, m, t + m, tden, n - m, n - m);
334+
MULMID(t, tden, f, fden, n, g, gden, m, m, n);
335+
_fmpq_poly_canonicalise(t, tden, n - m);
336+
MULLOW(g + m, uden, g, gden, m, t, tden, n - m, n - m);
329337
/* Assuming that the low part is canonicalised on input,
330338
we just need to canonicalise the high part. */
331339
_fmpq_poly_canonicalise(g + m, uden, n - m);

src/fmpq_poly/inv_series_newton.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ _fmpq_poly_inv_series_newton(fmpz * Qinv, fmpz_t Qinvden,
115115
Wlen = FLINT_MIN(Qnlen + m - 1, n);
116116
W2len = Wlen - m;
117117

118-
MULLOW(W, Q, Qnlen, Qinv, m, Wlen);
118+
_fmpz_poly_mulmid(W, Q, Qnlen, Qinv, m, m, Wlen);
119119
fmpz_mul(Wden, Qden, Qinvden);
120120

121-
MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m);
121+
MULLOW(Qinv + m, Qinv, m, W, W2len, n - m);
122122
fmpz_mul(Qinvden, Qinvden, Wden);
123123

124124
_fmpz_vec_scalar_mul_fmpz(Qinv, Qinv, m, Wden);

src/fmpq_poly/invsqrt_series.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,18 @@
1212

1313
#include "fmpz.h"
1414
#include "fmpz_vec.h"
15+
#include "fmpz_poly.h"
1516
#include "fmpq_poly.h"
1617

18+
static void
19+
_fmpq_poly_mulmid(fmpz * rpoly, fmpz_t rden,
20+
const fmpz * poly1, const fmpz_t den1, slong len1,
21+
const fmpz * poly2, const fmpz_t den2, slong len2, slong nlo, slong nhi)
22+
{
23+
_fmpz_poly_mulmid(rpoly, poly1, len1, poly2, len2, nlo, nhi);
24+
fmpz_mul(rden, den1, den2);
25+
}
26+
1727
void
1828
_fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden,
1929
const fmpz * poly, const fmpz_t den, slong len, slong n)
@@ -45,12 +55,12 @@ _fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden,
4555
fmpz_zero(t + n - 1);
4656

4757
_fmpq_poly_mullow(u, uden, t, tden, n, rpoly, rden, n, n);
48-
_fmpq_poly_mullow(t, tden, u, uden, n, poly, den, len, n);
58+
_fmpq_poly_mulmid(t + m, tden, u, uden, n, poly, den, len, m, n);
4959
_fmpz_vec_neg(t + m, t + m, n - m);
5060
_fmpz_vec_zero(t, m);
5161
fmpz_mul_ui(tden, tden, UWORD(2));
5262
_fmpq_poly_canonicalise(t, tden, n);
53-
63+
/* todo: concatenate instead of zero+add */
5464
_fmpq_poly_add(rpoly, rden, rpoly, rden, m, t, tden, n);
5565

5666
fmpz_clear(tden);

src/fmpz_poly.h

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -331,23 +331,13 @@ void _fmpz_poly_scale_2exp(fmpz * pol, slong len, slong k);
331331

332332
/* Bit packing *************************************************************/
333333

334-
void _fmpz_poly_bit_pack(nn_ptr arr, const fmpz * poly,
335-
slong len, flint_bitcnt_t bit_size, int negate);
334+
void _fmpz_poly_bit_pack(nn_ptr arr, const fmpz * poly, slong len, flint_bitcnt_t bit_size, int negate);
335+
void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, flint_bitcnt_t bit_size);
336336

337-
int _fmpz_poly_bit_unpack(fmpz * poly, slong len,
338-
nn_srcptr arr, flint_bitcnt_t bit_size, int negate);
339-
340-
void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len,
341-
nn_srcptr arr, flint_bitcnt_t bit_size);
342-
343-
void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly,
344-
flint_bitcnt_t bit_size);
345-
346-
void fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f,
347-
flint_bitcnt_t bit_size);
348-
349-
void fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f,
350-
flint_bitcnt_t bit_size);
337+
int _fmpz_poly_bit_unpack(fmpz * poly, slong nlo, slong nhi, nn_srcptr arr, flint_bitcnt_t bit_size, int negate);
338+
void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong nlo, slong nhi, nn_srcptr arr, flint_bitcnt_t bit_size);
339+
void fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, flint_bitcnt_t bit_size);
340+
void fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f, flint_bitcnt_t bit_size);
351341

352342

353343
/* Multiplication **********************************************************/
@@ -370,11 +360,14 @@ void _fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1,
370360
void fmpz_poly_mulhigh_classical(fmpz_poly_t res,
371361
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong start);
372362

373-
void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1,
374-
slong len1, const fmpz * poly2, slong len2);
375-
376-
void fmpz_poly_mulmid_classical(fmpz_poly_t res,
377-
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
363+
void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi);
364+
void fmpz_poly_mulmid_classical(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong nlo, slong nhi);
365+
void _fmpz_poly_mulmid_SS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi);
366+
void fmpz_poly_mulmid_SS(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong nlo, slong nhi);
367+
void _fmpz_poly_mulmid_KS(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi);
368+
void fmpz_poly_mulmid_KS(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong nlo, slong nhi);
369+
void _fmpz_poly_mulmid(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong nlo, slong nhi);
370+
void fmpz_poly_mulmid(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong nlo, slong nhi);
378371

379372
void fmpz_poly_mul_karatsuba(fmpz_poly_t res,
380373
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
@@ -409,14 +402,14 @@ void _fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, slong len1,
409402
void fmpz_poly_mullow_KS(fmpz_poly_t res, const fmpz_poly_t poly1,
410403
const fmpz_poly_t poly2, slong n);
411404

412-
void _fmpz_poly_mul_SS(fmpz * output, const fmpz * input1, slong length1,
413-
const fmpz * input2, slong length2);
405+
void _fmpz_poly_mul_SS(fmpz * res, const fmpz * poly1, slong len1,
406+
const fmpz * poly2, slong len2);
414407

415408
void fmpz_poly_mul_SS(fmpz_poly_t res,
416409
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
417410

418-
void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong length1,
419-
const fmpz * input2, slong length2, slong n);
411+
void _fmpz_poly_mullow_SS(fmpz * res, const fmpz * poly1, slong len1,
412+
const fmpz * poly2, slong len2, slong n);
420413

421414
void fmpz_poly_mullow_SS(fmpz_poly_t res,
422415
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);

src/fmpz_poly/bit_unpack.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "fmpz_poly.h"
1515

1616
int
17-
_fmpz_poly_bit_unpack(fmpz * poly, slong len,
17+
_fmpz_poly_bit_unpack(fmpz * poly, slong nlo, slong nhi,
1818
nn_srcptr arr, flint_bitcnt_t bit_size, int negate)
1919
{
2020
flint_bitcnt_t bits = 0;
@@ -24,10 +24,18 @@ _fmpz_poly_bit_unpack(fmpz * poly, slong len,
2424
int borrow = 0;
2525
slong i;
2626

27-
for (i = 0; i < len; i++)
27+
if (nlo != 0)
28+
{
29+
borrow = (arr[(nlo * bit_size - 1) / FLINT_BITS] >>
30+
((nlo * bit_size - 1) % FLINT_BITS)) & 1;
31+
limbs = (nlo * bit_size) / FLINT_BITS;
32+
bits = (nlo * bit_size) % FLINT_BITS;
33+
}
34+
35+
for (i = nlo; i < nhi; i++)
2836
{
2937
borrow =
30-
fmpz_bit_unpack(poly + i, arr + limbs, bits, bit_size, negate,
38+
fmpz_bit_unpack(poly + i - nlo, arr + limbs, bits, bit_size, negate,
3139
borrow);
3240
limbs += l;
3341
bits += b;
@@ -42,7 +50,7 @@ _fmpz_poly_bit_unpack(fmpz * poly, slong len,
4250
}
4351

4452
void
45-
_fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len,
53+
_fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong nlo, slong nhi,
4654
nn_srcptr arr, flint_bitcnt_t bit_size)
4755
{
4856
flint_bitcnt_t bits = 0;
@@ -51,9 +59,15 @@ _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len,
5159
slong l = bit_size / FLINT_BITS;
5260
slong i;
5361

54-
for (i = 0; i < len; i++)
62+
if (nlo != 0)
5563
{
56-
fmpz_bit_unpack_unsigned(poly + i, arr + limbs, bits, bit_size);
64+
limbs = (nlo * bit_size) / FLINT_BITS;
65+
bits = (nlo * bit_size) % FLINT_BITS;
66+
}
67+
68+
for (i = nlo; i < nhi; i++)
69+
{
70+
fmpz_bit_unpack_unsigned(poly + i - nlo, arr + limbs, bits, bit_size);
5771
limbs += l;
5872
bits += b;
5973
if (bits >= FLINT_BITS)
@@ -64,6 +78,7 @@ _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len,
6478
}
6579
}
6680

81+
6782
void
6883
fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f,
6984
flint_bitcnt_t bit_size)
@@ -90,7 +105,7 @@ fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f,
90105

91106
fmpz_poly_fit_length(poly, len);
92107

93-
_fmpz_poly_bit_unpack_unsigned(poly->coeffs, len, tmp->_mp_d, bit_size);
108+
_fmpz_poly_bit_unpack_unsigned(poly->coeffs, 0, len, tmp->_mp_d, bit_size);
94109
_fmpz_poly_set_length(poly, len);
95110
_fmpz_poly_normalise(poly);
96111

@@ -123,7 +138,7 @@ fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, flint_bitcnt_t bit_size)
123138

124139
fmpz_poly_fit_length(poly, len + 1);
125140

126-
borrow = _fmpz_poly_bit_unpack(poly->coeffs, len,
141+
borrow = _fmpz_poly_bit_unpack(poly->coeffs, 0, len,
127142
tmp->_mp_d, bit_size, negate);
128143

129144
if (borrow)

src/fmpz_poly/gcd_heuristic.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1,
190190
flint_mpn_zero(arrayg + limbsg, limbs2-limbsg);
191191

192192
/* unpack gcd */
193-
_fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0);
193+
_fmpz_poly_bit_unpack(G, 0, glen, arrayg, pack_bits, 0);
194194
while (G[glen - 1] == 0) glen--;
195195

196196
/* divide by any content */
@@ -215,7 +215,7 @@ _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1,
215215
/* unpack quotient of first poly by gcd */
216216
Q = _fmpz_vec_init(len1);
217217
t = _fmpz_vec_init(len1 + glen);
218-
_fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
218+
_fmpz_poly_bit_unpack(Q, 0, qlen, q, pack_bits, 0);
219219
while (Q[qlen - 1] == 0) qlen--;
220220

221221
/* divide by content */
@@ -241,7 +241,7 @@ _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1,
241241
if (flint_mpn_divides(q, array2, limbs2, arrayg, limbsg, temp))
242242
{
243243
/* unpack quotient of second poly by gcd */
244-
_fmpz_poly_bit_unpack(Q, qlen2, q, pack_bits, 0);
244+
_fmpz_poly_bit_unpack(Q, 0, qlen2, q, pack_bits, 0);
245245
while (Q[qlen2 - 1] == 0) qlen2--;
246246

247247
/* check if we really need to multiply out to check for exact quotient */

src/fmpz_poly/inv_series.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ _fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong Qlen, slong n)
282282
slong *a, i, m, Qnlen, Wlen, W2len;
283283
fmpz * W;
284284

285-
W = _fmpz_vec_init(n);
285+
W = _fmpz_vec_init(n / 2);
286286
a = flint_malloc(sizeof(slong) * FLINT_BITS);
287287

288288
a[i = 0] = n;
@@ -299,12 +299,12 @@ _fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong Qlen, slong n)
299299
Qnlen = FLINT_MIN(Qlen, n);
300300
Wlen = FLINT_MIN(Qnlen + m - 1, n);
301301
W2len = Wlen - m;
302-
MULLOW(W, Q, Qnlen, Qinv, m, Wlen);
303-
MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m);
302+
_fmpz_poly_mulmid(W, Q, Qnlen, Qinv, m, m, Wlen);
303+
MULLOW(Qinv + m, Qinv, m, W, W2len, n - m);
304304
_fmpz_vec_neg(Qinv + m, Qinv + m, n - m);
305305
}
306306

307-
_fmpz_vec_clear(W, n);
307+
_fmpz_vec_clear(W, n / 2);
308308
flint_free(a);
309309
}
310310
}

0 commit comments

Comments
 (0)