Exponential and logarithm
#include <flint/padic.h>int padic_exp(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceint padic_exp_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceint padic_exp_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceReturn whether the exponential series converges at op, that is, whether op is zero or has valuation at least 1 (odd ) or 2 (), and if so set rop to , reduced. Otherwise rop is not changed. The rectangular version evaluates the series by rectangular splitting, the balanced version by the -adic analogue of the bit-burst method with binary splitting, which is quasi-linear in for fixed .
int padic_log(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceint padic_log_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceint padic_log_satoh(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceint padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx)sourceReturn whether the logarithm series converges at op, that is, whether , and if so set rop to , reduced. Otherwise rop is not changed. The condition is the same for every , including . The rectangular version evaluates the series by rectangular splitting, the Satoh version first raises op to the power with , and the balanced version writes op as a product of factors whose logarithms are summed by binary splitting.
The -adic exponential and logarithm are defined by their power series
which converge for and for , respectively. For this means ( if ) for the exponential and for the logarithm. On these domains they are inverse isomorphisms between (or ) and (or ). The functions return 0 and leave the output unchanged when the series diverges, and otherwise return 1 and set the output to the value reduced modulo . Since the result of the exponential is a unit and that of the logarithm has valuation at least that of , the precision of the output is also, up to the valuation, its number of correct digits.
AlgorithmThe p-adic exponential and logarithmConvergence and truncation bounds for the p-adic exponential and logarithm series, their evaluation by rectangular splitting with deferred denominators, the balanced (bit-burst) method with binary splitting, and the Satoh–Skjernaa–Taguchi reduction of the logarithm, as implemented in padic, qadic and padic_radix.Algorithms#
Both series are truncated after the first term whose valuation, and that of every later term, is at least (_padic_exp_bound and _padic_log_bound). The tail bounds use and ; for an argument of valuation this gives about terms for the exponential and about for the logarithm.
- Rectangular splitting evaluates the truncated series with about multiplications of full-size integers modulo , the extra digits absorbing the powers of in the denominators or . It is used by
padic_expfor and bypadic_logfor , where is the bit length of . - The balanced algorithms split the argument into pieces with having valuation at least and digits, and use , respectively for a matching factorisation . Each short series is summed exactly by binary splitting. This is the -adic analogue of Brent's bit-burst method and costs , quasi-linear in .
- Satoh's method (
padic_log_satoh) uses : since has valuation at least , the series for the right-hand side has about terms, and with the power (about squarings) and the shorter series together cost multiplications [SST2003]. It is never selected automatically, and for it falls back to rectangular splitting.
Example#
With and precision 20, the logarithm inverts the exponential at , by each of the three algorithms. Neither series converges at the unit 3.
#include <flint/flint.h>
#include <flint/padic.h>
int main(void)
{
fmpz_t p;
padic_ctx_t ctx;
padic_t x, y, z;
int ok;
fmpz_init_set_ui(p, 5);
padic_ctx_init(ctx, p, 0, 20, PADIC_TERSE);
padic_init2(x, 20);
padic_init2(y, 20);
padic_init2(z, 20);
padic_set_ui(x, 15, ctx); /* x = 3 * 5, valuation 1 */
ok = padic_exp(y, x, ctx);
flint_printf("exp(15) converges: %d\ny = ", ok);
padic_print(y, ctx); flint_printf("\n");
ok = padic_log(z, y, ctx);
flint_printf("log(y) converges: %d, log(y) == 15: %d\n",
ok, padic_equal(z, x));
padic_log_balanced(z, y, ctx);
flint_printf("balanced agrees: %d\n", padic_equal(z, x));
padic_log_satoh(z, y, ctx);
flint_printf("Satoh agrees: %d\n", padic_equal(z, x));
padic_set_ui(x, 3, ctx); /* a unit, not 1 mod 5 */
flint_printf("exp(3) converges: %d, log(3) converges: %d\n",
padic_exp(y, x, ctx), padic_log(z, x, ctx));
padic_clear(x); padic_clear(y); padic_clear(z);
padic_ctx_clear(ctx);
fmpz_clear(p);
return 0;
}exp(15) converges: 1 y = 87481552191941 log(y) converges: 1, log(y) == 15: 1 balanced agrees: 1 Satoh agrees: 1 exp(3) converges: 0, log(3) converges: 0
The value printed is the representative of modulo . Applying the logarithm to it recovers 15 exactly, because on the domain of convergence and both functions are computed to the full precision of the output.
References#
- [SST2003] T. Satoh, B. Skjernaa and Y. Taguchi. Fast computation of canonical lifts of elliptic curves and its application to point counting. Finite Fields and Their Applications 9 (2003), 89–101. https://doi.org/10.1016/S1071-5797(02)00013-8
The FLINT team, “Exponential and logarithm (padic.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/padic/exp-log.html (generated 2026-11-02).
@misc{flint-doc-padic-exp-log,
author = {{The FLINT team}},
title = {{Exponential and logarithm (padic.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/padic/exp-log.html},
note = {Generated 2026-11-02}
}