static __inline__ long _zeta_function(const fmpz_t p, long a, long n, long d) { const long b = gmc_basis_size(n, d); long i, N; fmpz_t f, g, max; fmpz_init(f); fmpz_init(g); fmpz_init(max); if (n == 3 && fmpz_cmp_ui(p, 2) != 0) { fmpz_bin_uiui(f, d-1, 3); fmpz_bin_uiui(g, b, b / 2); fmpz_mul_ui(g, g, 2); N = a * (*f) + fmpz_clog(g, p); } else if (n % 2L == 0) /* n even implies b even */ { fmpz_bin_uiui(f, b, b / 2); fmpz_pow_ui(g, p, (a * (b / 2) * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); N = fmpz_flog(f, p) + 1; } else { for (i = b / 2; i <= b; i++) { fmpz_bin_uiui(f, b, i); fmpz_pow_ui(g, p, (a * i * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); if (fmpz_cmp(max, f) < 0) fmpz_swap(max, f); } N = fmpz_flog(max, p) + 1; } fmpz_clear(f); fmpz_clear(g); fmpz_clear(max); return N; }
char * _padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx) { const fmpz * u = padic_unit(op); const long v = padic_val(op); if (fmpz_is_zero(u)) { if (!str) { str = flint_malloc(2); } str[0] = '0'; str[1] = '\0'; return str; } if (ctx->mode == PADIC_TERSE) { if (v == 0) { str = fmpz_get_str(str, 10, u); } else if (v > 0) { fmpz_t t; fmpz_init(t); fmpz_pow_ui(t, ctx->p, v); fmpz_mul(t, t, u); str = fmpz_get_str(str, 10, t); fmpz_clear(t); } else /* v < 0 */ { fmpz_t t; fmpz_init(t); fmpz_pow_ui(t, ctx->p, -v); str = _fmpq_get_str(str, 10, u, t); fmpz_clear(t); } } else if (ctx->mode == PADIC_SERIES) { char *s; fmpz_t x; fmpz_t d; long j, N; if (fmpz_sgn(u) < 0) { printf("ERROR (_padic_get_str). u < 0 in SERIES mode.\n"); abort(); } N = fmpz_clog(u, ctx->p) + v; if (!str) { long b = (N - v) * (2 * fmpz_sizeinbase(ctx->p, 10) + z_sizeinbase(FLINT_MAX(FLINT_ABS(v), FLINT_ABS(N)), 10) + 5) + 1; str = flint_malloc(b); if (!str) { printf("ERROR (_padic_get_str). Memory allocation failed.\n"); abort(); } } s = str; fmpz_init(d); fmpz_init(x); fmpz_set(x, u); /* Unroll first step */ j = 0; { fmpz_mod(d, x, ctx->p); /* d = u mod p^{j+1} */ fmpz_sub(x, x, d); /* x = x - d */ fmpz_divexact(x, x, ctx->p); /* x = x / p */ if (!fmpz_is_zero(d)) { if (j + v != 0) { fmpz_get_str(s, 10, d); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", j + v); while (*++s != '\0') ; } else { fmpz_get_str(s, 10, d); while (*++s != '\0') ; } } j++; } for ( ; !fmpz_is_zero(x); j++) { fmpz_mod(d, x, ctx->p); /* d = u mod p^{j+1} */ fmpz_sub(x, x, d); /* x = x - d */ fmpz_divexact(x, x, ctx->p); /* x = x / p */ if (!fmpz_is_zero(d)) { if (j + v != 0) { *s++ = ' '; *s++ = '+'; *s++ = ' '; fmpz_get_str(s, 10, d); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", j + v); while (*++s != '\0') ; } else { *s++ = ' '; *s++ = '+'; *s++ = ' '; fmpz_get_str(s, 10, d); while (*++s != '\0') ; } } } fmpz_clear(x); fmpz_clear(d); } else /* ctx->mode == PADIC_VAL_UNIT */ { if (!str) { long b = fmpz_sizeinbase(u, 10) + fmpz_sizeinbase(ctx->p, 10) + z_sizeinbase(v, 10) + 4; str = flint_malloc(b); if (!str) { printf("ERROR (_padic_get_str). Memory allocation failed.\n"); abort(); } } if (v == 0) { str = fmpz_get_str(str, 10, u); } else if (v == 1) { char *s = str; fmpz_get_str(s, 10, u); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); } else { char *s = str; fmpz_get_str(s, 10, u); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", v); } } return str; }