int qadic_exp_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) { const slong N = qadic_prec(rop); const slong v = op->val; const fmpz *p = (&ctx->pctx)->p; if (padic_poly_is_zero(op)) { padic_poly_one(rop); return 1; } if ((*p == WORD(2) && v <= 1) || (v <= 0)) { return 0; } else { if (v < N) { const slong d = qadic_ctx_degree(ctx); fmpz_t pN; int alloc; alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); padic_poly_fit_length(rop, d); _qadic_exp_balanced(rop->coeffs, op->coeffs, v, op->length, ctx->a, ctx->j, ctx->len, p, N, pN); rop->val = 0; _padic_poly_set_length(rop, d); _padic_poly_normalise(rop); if (alloc) fmpz_clear(pN); } else { padic_poly_one(rop); } return 1; } }
static void fmpz_poly_evaluate_qadic(qadic_t rop, const fmpz_poly_t op1, const qadic_t op2, const qadic_ctx_t ctx) { const long N = qadic_prec(rop); const long d = qadic_ctx_degree(ctx); if (N <= 0 || op2->val != 0 || rop == op2) { printf("Exception (fmpz_poly_evaluate_qadic):\n"); printf("Currently assumes that N > 0 and op2->val == 0, \n"); printf("and does not support aliasing.\n"); abort(); } if (fmpz_poly_is_zero(op1)) { qadic_zero(rop); } else if (qadic_is_zero(op2)) { padic_poly_set_fmpz(rop, op1->coeffs + 0, &ctx->pctx); } else { fmpz_t pN; fmpz_init(pN); fmpz_pow_ui(pN, (&ctx->pctx)->p, N); padic_poly_fit_length(rop, d); _fmpz_mod_poly_compose_smod(rop->coeffs, op1->coeffs, op1->length, op2->coeffs, op2->length, ctx->a, ctx->j, ctx->len, pN); _padic_poly_set_length(rop, d); qadic_reduce(rop, ctx); fmpz_clear(pN); } }
int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) { const slong N = qadic_prec(rop); const slong v = op->val; const fmpz *p = (&ctx->pctx)->p; if (padic_poly_is_zero(op)) { padic_poly_one(rop); return 1; } if ((*p == WORD(2) && v <= 1) || (v <= 0)) { return 0; } else { if (v < N) { const slong d = qadic_ctx_degree(ctx); fmpz *t; fmpz_t pN; int alloc; alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); if (rop == op) { t = _fmpz_vec_init(2 * d - 1); } else { padic_poly_fit_length(rop, 2 * d - 1); t = rop->coeffs; } _qadic_exp(t, op->coeffs, v, op->length, ctx->a, ctx->j, ctx->len, p, N, pN); rop->val = 0; if (rop == op) { _fmpz_vec_clear(rop->coeffs, rop->alloc); rop->coeffs = t; rop->alloc = 2 * d - 1; rop->length = d; } _padic_poly_set_length(rop, d); _padic_poly_normalise(rop); if (alloc) fmpz_clear(pN); } else { padic_poly_one(rop); } return 1; } }