1 /*
2 Copyright (C) 2012 Sebastian Pancratz
3
4 This file is part of FLINT.
5
6 FLINT is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version. See <http://www.gnu.org/licenses/>.
10 */
11
12 #include "qadic.h"
13
14 /*
15 Forms the product of (op1,len1) and (op2,len2) modulo (a,j,lena) and pN.
16 Assumes that len1 >= len2 > 0. Requires rop to be of size at least
17 len1 + len2 - 1.
18 */
19
20 static
_qadic_mul(fmpz * rop,const fmpz * op1,slong len1,const fmpz * op2,slong len2,const fmpz * a,const slong * j,slong lena,const fmpz_t pN)21 void _qadic_mul(fmpz *rop,
22 const fmpz *op1, slong len1, const fmpz *op2, slong len2,
23 const fmpz *a, const slong *j, slong lena, const fmpz_t pN)
24 {
25 _fmpz_poly_mul(rop, op1, len1, op2, len2);
26 _fmpz_mod_poly_reduce(rop, len1 + len2 - 1, a, j, lena, pN);
27 }
28
qadic_mul(qadic_t x,const qadic_t y,const qadic_t z,const qadic_ctx_t ctx)29 void qadic_mul(qadic_t x, const qadic_t y, const qadic_t z,
30 const qadic_ctx_t ctx)
31 {
32 const slong leny = y->length;
33 const slong lenz = z->length;
34 const slong lenx = leny + lenz - 1;
35 const slong N = qadic_prec(x);
36 const slong d = qadic_ctx_degree(ctx);
37
38 if (leny == 0 || lenz == 0 || y->val + z->val >= N)
39 {
40 qadic_zero(x);
41 }
42 else
43 {
44 fmpz *t;
45 fmpz_t pN;
46 int alloc;
47
48 x->val = y->val + z->val;
49
50 alloc = _padic_ctx_pow_ui(pN, N - x->val, &ctx->pctx);
51
52 if (x == y || x == z)
53 {
54 t = _fmpz_vec_init(lenx);
55 }
56 else
57 {
58 padic_poly_fit_length(x, lenx);
59 t = x->coeffs;
60 }
61
62 if (leny >= lenz)
63 _qadic_mul(t, y->coeffs, leny,
64 z->coeffs, lenz, ctx->a, ctx->j, ctx->len, pN);
65 else
66 _qadic_mul(t, z->coeffs, lenz,
67 y->coeffs, leny, ctx->a, ctx->j, ctx->len, pN);
68
69 if (x == y || x == z)
70 {
71 _fmpz_vec_clear(x->coeffs, x->alloc);
72 x->coeffs = t;
73 x->alloc = lenx;
74 }
75
76 _padic_poly_set_length(x, FLINT_MIN(lenx, d));
77 _padic_poly_normalise(x);
78
79 if (alloc)
80 fmpz_clear(pN);
81 }
82 }
83
84