Skip to content

Commit b04ff1f

Browse files
Merge pull request #2613 from fredrik-johansson/mulmid2
Middle products for `arb_poly`, `acb_poly`, `nmod_poly`, `gr_poly`
2 parents d58f296 + d88503f commit b04ff1f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2391
-386
lines changed

doc/source/acb_poly.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,16 @@ Arithmetic
347347
If the same variable is passed for *A* and *B*, sets *C* to
348348
the square of *A*.
349349

350+
.. function:: void _acb_poly_mulmid_transpose(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
351+
void acb_poly_mulmid_transpose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec)
352+
void _acb_poly_mulmid_classical(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
353+
void acb_poly_mulmid_classical(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec)
354+
void _acb_poly_mulmid(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
355+
void acb_poly_mulmid(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec)
356+
357+
Analogous to *mullow* functions, but compute the product truncated
358+
at length *nhi* and right-shifted by *nlo*.
359+
350360
.. function:: void _acb_poly_inv_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong len, slong prec)
351361

352362
Sets *{Qinv, len}* to the power series inverse of *{Q, Qlen}*. Uses Newton iteration.

doc/source/arb_poly.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,16 @@ Arithmetic
343343
If the same variable is passed for *A* and *B*, sets *C* to the
344344
square of *A*.
345345

346+
.. function:: void _arb_poly_mulmid_block(arb_ptr z, arb_srcptr x, slong xlen, arb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
347+
void arb_poly_mulmid_block(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong nlo, slong nhi, slong prec)
348+
void _arb_poly_mulmid_classical(arb_ptr z, arb_srcptr x, slong xlen, arb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
349+
void arb_poly_mulmid_classical(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong nlo, slong nhi, slong prec)
350+
void _arb_poly_mulmid(arb_ptr z, arb_srcptr x, slong xlen, arb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec)
351+
void arb_poly_mulmid(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong nlo, slong nhi, slong prec)
352+
353+
Analogous to *mullow* functions, but compute the product truncated
354+
at length *nhi* and right-shifted by *nlo*.
355+
346356
.. function:: void _arb_poly_inv_series(arb_ptr Q, arb_srcptr A, slong Alen, slong len, slong prec)
347357

348358
Sets *{Q, len}* to the power series inverse of *{A, Alen}*. Uses Newton iteration.

doc/source/gr_poly.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ Arithmetic
183183
by default, which currently always delegates to :func:`_gr_poly_mullow_classical`.
184184
This can be overridden by specific rings.
185185

186+
.. function:: int _gr_poly_mulmid(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx)
187+
int _gr_poly_mulmid_generic(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx)
188+
int gr_poly_mulmid(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, slong nlo, slong nhi, gr_ctx_t ctx)
189+
186190
Multiplication algorithms
187191
-------------------------------------------------------------------------------
188192

doc/source/nmod_poly.rst

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,12 @@ Bit packing and unpacking
554554
coefficient of ``poly`` is bigger than ``bits/2`` bits. We
555555
also assume ``bits < 3 * FLINT_BITS``.
556556

557-
.. function:: void _nmod_poly_bit_unpack(nn_ptr res, slong len, nn_srcptr mpn, ulong bits, nmod_t mod)
557+
.. function:: void _nmod_poly_bit_unpack(nn_ptr res, slong nlo, slong nhi, nn_srcptr mpn, ulong bits, nmod_t mod)
558558

559-
Unpacks ``len`` coefficients stored in the big integer ``mpn``
560-
in bit fields of the given number of bits, reduces them modulo the
561-
given modulus, then stores them in the polynomial ``res``.
562-
We assume ``len > 0`` and ``3 * FLINT_BITS > bits > 0``.
559+
Unpacks ``nhi - nlo`` coefficients stored in the big integer ``mpn``
560+
in bit fields of the given number of bits, starting at offset ``nlo``,
561+
reduces them modulo the given modulus, then stores them in the polynomial ``res``.
562+
We assume ``3 * FLINT_BITS > bits > 0``.
563563
There are no restrictions on the size of the actual coefficients as
564564
stored within the bitfields.
565565

@@ -679,19 +679,14 @@ Multiplication
679679
coefficients from ``start`` onwards into the high coefficients of
680680
``res``, the remaining coefficients being arbitrary but reduced.
681681

682-
.. function:: void _nmod_poly_mul_KS(nn_ptr out, nn_srcptr in1, slong len1, nn_srcptr in2, slong len2, flint_bitcnt_t bits, nmod_t mod)
682+
.. function:: void _nmod_poly_mul_KS(nn_ptr out, nn_srcptr in1, slong len1, nn_srcptr in2, slong len2, nmod_t mod)
683683

684-
Sets ``res`` to the product of ``in1`` and ``in2``
685-
assuming the output coefficients are at most the given number of
686-
bits wide. If ``bits`` is set to `0` an appropriate value is
687-
computed automatically. Assumes that ``len1 >= len2 > 0``.
684+
Sets ``res`` to the product of ``in1`` and ``in2``.
685+
Assumes that ``len1 >= len2 > 0``.
688686

689-
.. function:: void nmod_poly_mul_KS(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, flint_bitcnt_t bits)
687+
.. function:: void nmod_poly_mul_KS(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2)
690688

691-
Sets ``res`` to the product of ``poly1`` and ``poly2``
692-
assuming the output coefficients are at most the given number of
693-
bits wide. If ``bits`` is set to `0` an appropriate value
694-
is computed automatically.
689+
Sets ``res`` to the product of ``poly1`` and ``poly2``.
695690

696691
.. function:: void _nmod_poly_mul_KS2(nn_ptr res, nn_srcptr op1, slong n1, nn_srcptr op2, slong n2, nmod_t mod)
697692

@@ -711,14 +706,14 @@ Multiplication
711706

712707
Sets ``res`` to the product of ``poly1`` and ``poly2``.
713708

714-
.. function:: void _nmod_poly_mullow_KS(nn_ptr out, nn_srcptr in1, slong len1, nn_srcptr in2, slong len2, flint_bitcnt_t bits, slong n, nmod_t mod)
709+
.. function:: void _nmod_poly_mullow_KS(nn_ptr out, nn_srcptr in1, slong len1, nn_srcptr in2, slong len2, slong n, nmod_t mod)
715710

716711
Sets ``out`` to the low `n` coefficients of ``in1`` of length
717712
``len1`` times ``in2`` of length ``len2``. The output must have
718713
space for ``n`` coefficients. We assume that ``len1 >= len2 > 0``
719714
and that ``0 < n <= len1 + len2 - 1``.
720715

721-
.. function:: void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, flint_bitcnt_t bits, slong n)
716+
.. function:: void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, slong n)
722717

723718
Set ``res`` to the low `n` coefficients of ``in1`` of length
724719
``len1`` times ``in2`` of length ``len2``.
@@ -746,6 +741,20 @@ Multiplication
746741
Sets ``res`` to the first ``trunc`` coefficients of the
747742
product of ``poly1`` and ``poly2``.
748743

744+
.. function:: void _nmod_poly_mulmid(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
745+
void nmod_poly_mulmid(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
746+
void _nmod_poly_mulmid_classical(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
747+
void nmod_poly_mulmid_classical(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
748+
void _nmod_poly_mulmid_KS(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
749+
void nmod_poly_mulmid_KS(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)
750+
751+
Sets ``res`` to the first ``nhi - nlo`` middle coefficients of the
752+
product of ``poly1`` of length ``len1`` and ``poly2`` of
753+
length ``len2`` starting at offset ``nlo``.
754+
It is assumed that ``0 <= nlo < nhi <= len1 + len2 - 1``.
755+
The function :func:`_nmod_poly_mulmid_classical` does not support
756+
aliasing between inputs and outputs, but all others do.
757+
749758
.. function:: void _nmod_poly_mulhigh(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong n, nmod_t mod)
750759

751760
Sets all but the low `n` coefficients of ``res`` to the
@@ -767,16 +776,17 @@ Multiplication
767776
other multiplication algorithms, given inputs of length *len1* and *len2*
768777
and output truncation to length *n*.
769778

770-
.. function:: int _nmod_poly_mullow_fft_small_repack(nn_ptr z, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong zn, nmod_t mod)
779+
.. function:: int _nmod_poly_mulmid_fft_small_repack(nn_ptr z, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong znlo, slong zn, nmod_t mod)
771780

772781
Internal helper function for :func:`_nmod_poly_mullow_fft_small`: if the
773782
inputs are small enough to perform a repacked convolution of half the
774783
length, multiply and return 1, otherwise do nothing and return 0.
775-
The conditions on the arguments are the same as for :func:`_nmod_poly_mullow`.
784+
The conditions on the arguments are the same as for :func:`_nmod_poly_mulmid_fft_small`.
776785

777-
.. function:: void _nmod_poly_mullow_fft_small(nn_ptr z, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong zn, nmod_t mod)
786+
.. function:: void _nmod_poly_mulmid_fft_small(nn_ptr z, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong znlo, slong zn, nmod_t mod)
787+
void _nmod_poly_mullow_fft_small(nn_ptr z, nn_srcptr a, slong an, nn_srcptr b, slong bn, slong zn, nmod_t mod)
778788

779-
Low multiplication via the *fft_small* module. Throws an error
789+
Multiplication via the *fft_small* module. Throws an error
780790
if *fft_small* is not available. The conditions on the arguments
781791
are the same as for :func:`_nmod_poly_mullow`.
782792

src/acb_poly.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,13 @@ void _acb_poly_mul(acb_ptr C,
333333
void acb_poly_mul(acb_poly_t res, const acb_poly_t poly1,
334334
const acb_poly_t poly2, slong prec);
335335

336+
void _acb_poly_mulmid_transpose(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec);
337+
void acb_poly_mulmid_transpose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec);
338+
void _acb_poly_mulmid_classical(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec);
339+
void acb_poly_mulmid_classical(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec);
340+
void _acb_poly_mulmid(acb_ptr z, acb_srcptr x, slong xlen, acb_srcptr y, slong ylen, slong nlo, slong nhi, slong prec);
341+
void acb_poly_mulmid(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong nlo, slong nhi, slong prec);
342+
336343
ACB_POLY_INLINE void
337344
_acb_poly_mul_monic(acb_ptr res, acb_srcptr poly1, slong len1,
338345
acb_srcptr poly2, slong len2, slong prec)

src/acb_poly/exp_series.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,16 @@ _acb_poly_exp_series_newton(acb_ptr f, acb_ptr g,
4949
slong l = m - 1; /* shifted for derivative */
5050

5151
/* g := exp(-h) + O(x^m) */
52-
_acb_poly_mullow(T, f, m, g, m2, m, prec);
53-
_acb_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, prec);
52+
_acb_poly_mulmid(T, f, m, g, m2, m2, m, prec);
53+
_acb_poly_mullow(g + m2, g, m2, T, m - m2, m - m2, prec);
5454
_acb_vec_neg(g + m2, g + m2, m - m2);
5555

5656
/* U := h' + g (f' - f h') + O(x^(n-1))
5757
Note: should replace h' by h' mod x^(m-1) */
5858
_acb_vec_zero(f + m, n - m);
59-
_acb_poly_mullow(T, f, n, hprime, n, n, prec); /* should be mulmid */
59+
_acb_poly_mulmid(T, f, n, hprime, n, l, n, prec);
6060
_acb_poly_derivative(U, f, n, prec); acb_zero(U + n - 1); /* should skip low terms */
61-
_acb_vec_sub(U + l, U + l, T + l, n - l, prec);
61+
_acb_vec_sub(U + l, U + l, T, n - l, prec);
6262
_acb_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, prec);
6363
_acb_vec_add(U + l, hprime + l, T + l, n - m, prec);
6464

@@ -71,8 +71,8 @@ _acb_poly_exp_series_newton(acb_ptr f, acb_ptr g,
7171
/* not needed if we only want exp(x) */
7272
if (n == len && inverse)
7373
{
74-
_acb_poly_mullow(T, f, n, g, m, n, prec);
75-
_acb_poly_mullow(g + m, g, m, T + m, n - m, n - m, prec);
74+
_acb_poly_mulmid(T, f, n, g, m, m, n, prec);
75+
_acb_poly_mullow(g + m, g, m, T, n - m, n - m, prec);
7676
_acb_vec_neg(g + m, g + m, n - m);
7777
}
7878

src/acb_poly/inv_series.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@
1212
#include "arb_poly.h"
1313
#include "acb_poly.h"
1414

15-
#define MULLOW(z, x, xn, y, yn, nn, prec) \
16-
if ((xn) >= (yn)) \
17-
_acb_poly_mullow(z, x, xn, y, yn, nn, prec); \
18-
else \
19-
_acb_poly_mullow(z, y, yn, x, xn, nn, prec); \
20-
2115
void
2216
_acb_poly_inv_series(acb_ptr Qinv,
2317
acb_srcptr Q, slong Qlen, slong len, slong prec)
@@ -60,22 +54,22 @@ _acb_poly_inv_series(acb_ptr Qinv,
6054
slong Qnlen, Wlen, W2len;
6155
acb_ptr W;
6256

63-
W = _acb_vec_init(len);
57+
W = _acb_vec_init(len / 2);
6458

6559
NEWTON_INIT(blen, len)
6660
NEWTON_LOOP(m, n)
6761

6862
Qnlen = FLINT_MIN(Qlen, n);
6963
Wlen = FLINT_MIN(Qnlen + m - 1, n);
7064
W2len = Wlen - m;
71-
MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec);
72-
MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec);
65+
_acb_poly_mulmid(W, Q, Qnlen, Qinv, m, m, Wlen, prec);
66+
_acb_poly_mullow(Qinv + m, Qinv, m, W, W2len, n - m, prec);
7367
_acb_vec_neg(Qinv + m, Qinv + m, n - m);
7468

7569
NEWTON_END_LOOP
7670
NEWTON_END
7771

78-
_acb_vec_clear(W, len);
72+
_acb_vec_clear(W, len / 2);
7973
}
8074
}
8175
}

src/acb_poly/mullow_transpose.c

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,47 @@
1313
#include "acb_poly.h"
1414

1515
void
16-
_acb_poly_mullow_transpose(acb_ptr res,
16+
_acb_poly_mulmid_transpose(acb_ptr res,
1717
acb_srcptr poly1, slong len1,
18-
acb_srcptr poly2, slong len2, slong n, slong prec)
18+
acb_srcptr poly2, slong len2, slong nlo, slong nhi, slong prec)
1919
{
2020
arb_ptr a, b, c, d, e, f, w;
2121
arb_ptr t;
2222
slong i;
2323

24-
len1 = FLINT_MIN(len1, n);
25-
len2 = FLINT_MIN(len2, n);
24+
len1 = FLINT_MIN(len1, nhi);
25+
len2 = FLINT_MIN(len2, nhi);
26+
27+
slong nlo2 = (len1 + len2 - 1) - nlo;
2628

27-
w = flint_malloc(sizeof(arb_struct) * (2 * (len1 + len2 + n)));
29+
if (len1 > nlo2)
30+
{
31+
slong trunc = len1 - nlo2;
32+
poly1 += trunc;
33+
len1 -= trunc;
34+
nlo -= trunc;
35+
nhi -= trunc;
36+
}
37+
38+
if (len2 > nlo2)
39+
{
40+
slong trunc = len2 - nlo2;
41+
poly2 += trunc;
42+
len2 -= trunc;
43+
nlo -= trunc;
44+
nhi -= trunc;
45+
}
46+
47+
w = flint_malloc(sizeof(arb_struct) * (2 * (len1 + len2 + (nhi - nlo))));
2848
a = w;
2949
b = a + len1;
3050
c = b + len1;
3151
d = c + len2;
3252
e = d + len2;
33-
f = e + n;
53+
f = e + (nhi - nlo);
3454

3555
/* (e+fi) = (a+bi)(c+di) = (ac - bd) + (ad + bc)i */
36-
t = _arb_vec_init(n);
56+
t = _arb_vec_init(nhi - nlo);
3757

3858
for (i = 0; i < len1; i++)
3959
{
@@ -47,38 +67,84 @@ _acb_poly_mullow_transpose(acb_ptr res,
4767
d[i] = *acb_imagref(poly2 + i);
4868
}
4969

50-
for (i = 0; i < n; i++)
70+
for (i = 0; i < nhi - nlo; i++)
5171
{
5272
e[i] = *acb_realref(res + i);
5373
f[i] = *acb_imagref(res + i);
5474
}
5575

56-
_arb_poly_mullow(e, a, len1, c, len2, n, prec);
57-
_arb_poly_mullow(t, b, len1, d, len2, n, prec);
58-
_arb_vec_sub(e, e, t, n, prec);
76+
_arb_poly_mulmid(e, a, len1, c, len2, nlo, nhi, prec);
77+
_arb_poly_mulmid(t, b, len1, d, len2, nlo, nhi, prec);
78+
_arb_vec_sub(e, e, t, nhi - nlo, prec);
5979

60-
_arb_poly_mullow(f, a, len1, d, len2, n, prec);
80+
_arb_poly_mulmid(f, a, len1, d, len2, nlo, nhi, prec);
6181
/* squaring */
6282
if (poly1 == poly2 && len1 == len2)
6383
{
64-
_arb_vec_scalar_mul_2exp_si(f, f, n, 1);
84+
_arb_vec_scalar_mul_2exp_si(f, f, nhi - nlo, 1);
6585
}
6686
else
6787
{
68-
_arb_poly_mullow(t, b, len1, c, len2, n, prec);
69-
_arb_vec_add(f, f, t, n, prec);
88+
_arb_poly_mulmid(t, b, len1, c, len2, nlo, nhi, prec);
89+
_arb_vec_add(f, f, t, nhi - nlo, prec);
7090
}
7191

72-
for (i = 0; i < n; i++)
92+
for (i = 0; i < nhi - nlo; i++)
7393
{
7494
*acb_realref(res + i) = e[i];
7595
*acb_imagref(res + i) = f[i];
7696
}
7797

78-
_arb_vec_clear(t, n);
98+
_arb_vec_clear(t, nhi - nlo);
7999
flint_free(w);
80100
}
81101

102+
void
103+
_acb_poly_mullow_transpose(acb_ptr res,
104+
acb_srcptr poly1, slong len1,
105+
acb_srcptr poly2, slong len2, slong n, slong prec)
106+
{
107+
_acb_poly_mulmid_transpose(res, poly1, len1, poly2, len2, 0, n, prec);
108+
}
109+
110+
void
111+
acb_poly_mulmid_transpose(acb_poly_t res, const acb_poly_t poly1,
112+
const acb_poly_t poly2, slong nlo, slong nhi, slong prec)
113+
{
114+
slong xlen, ylen, zlen;
115+
116+
xlen = poly1->length;
117+
ylen = poly2->length;
118+
119+
if (xlen == 0 || ylen == 0 || nlo >= FLINT_MIN(nhi, xlen + ylen - 1))
120+
{
121+
acb_poly_zero(res);
122+
return;
123+
}
124+
125+
nhi = FLINT_MIN(nhi, xlen + ylen - 1);
126+
zlen = nhi - nlo;
127+
128+
if (res == poly1 || res == poly2)
129+
{
130+
acb_poly_t tmp;
131+
acb_poly_init2(tmp, zlen);
132+
_acb_poly_mulmid_transpose(tmp->coeffs, poly1->coeffs, xlen,
133+
poly2->coeffs, ylen, nlo, nhi, prec);
134+
acb_poly_swap(res, tmp);
135+
acb_poly_clear(tmp);
136+
}
137+
else
138+
{
139+
acb_poly_fit_length(res, zlen);
140+
_acb_poly_mulmid_transpose(res->coeffs, poly1->coeffs, xlen,
141+
poly2->coeffs, ylen, nlo, nhi, prec);
142+
}
143+
144+
_acb_poly_set_length(res, zlen);
145+
_acb_poly_normalise(res);
146+
}
147+
82148
void
83149
acb_poly_mullow_transpose(acb_poly_t res, const acb_poly_t poly1,
84150
const acb_poly_t poly2,

0 commit comments

Comments
 (0)