Skip to content

Helpers, mullow and modular inverse for radix integers#2561

Merged
fredrik-johansson merged 6 commits intoflintlib:mainfrom
fredrik-johansson:radix2
Jan 21, 2026
Merged

Helpers, mullow and modular inverse for radix integers#2561
fredrik-johansson merged 6 commits intoflintlib:mainfrom
fredrik-johansson:radix2

Conversation

@fredrik-johansson
Copy link
Collaborator

We add more essential functionality for radix integers:

  • Setting/getting/shifting/counting limbs
  • Reduction mod $B^n$, both to $[0, B^n)$ and to $(\pm B^n / 2)$
  • Multiplication and inverse mod $B^n$.

This is now starting to get usable for p-adics.

Check out these timings @thofma @fieker.

Multiplication mod $B^n$ where $B = 7^{22}$ (padic_mul, fmpz_mod_mul, mpn_mod_mul, radix_integer_mullow_limbs):

       n      padic   fmpz_mod    mpn_mod   radix_integer    speedup/padic  speedup/fmpz_mod
       1   6.99e-08   5.45e-09          -   9.40e-09         7.44x          0.58x
       2   9.26e-08   9.27e-09   8.02e-09   1.54e-08         6.01x          0.60x
       4   1.33e-07   7.00e-08   3.43e-08   3.37e-08         3.95x          2.08x
       8   2.11e-07   1.34e-07   7.03e-08   7.02e-08         3.01x          1.91x
      16   4.42e-07   3.37e-07   2.19e-07   2.35e-07         1.88x          1.43x
      32   1.16e-06   8.27e-07          -   6.03e-07         1.92x          1.37x
      64   3.43e-06   2.55e-06          -   1.87e-06         1.83x          1.36x
     128   1.05e-05   7.77e-06          -   5.88e-06         1.79x          1.32x
     256   3.27e-05   2.73e-05          -   9.73e-06         3.36x          2.81x
     512   9.30e-05   6.92e-05          -   2.03e-05         4.58x          3.41x
    1024   2.54e-04   1.46e-04          -   4.32e-05         5.88x          3.38x
    2048   5.96e-04   2.87e-04          -   8.93e-05         6.67x          3.21x
    4096   1.33e-03   6.73e-04          -   1.87e-04         7.11x          3.60x
    8192   2.75e-03   1.31e-03          -   3.99e-04         6.89x          3.28x
   16384   5.70e-03   2.74e-03          -   8.30e-04         6.87x          3.30x
   32768   1.21e-02   5.62e-03          -   1.72e-03         7.03x          3.27x
   65536   2.48e-02   1.16e-02          -   3.58e-03         6.93x          3.24x
  131072   5.28e-02   2.55e-02          -   7.62e-03         6.93x          3.35x
  262144   1.29e-01   5.53e-02          -   1.67e-02         7.72x          3.31x
  524288   2.71e-01   1.21e-01          -   3.77e-02         7.19x          3.21x
 1048576   5.79e-01   2.64e-01          -   8.43e-02         6.87x          3.13x
 2097152   1.26e+00   5.88e-01          -   1.82e-01         6.91x          3.23x
 4194304   2.77e+00   1.24e+00          -   3.93e-01         7.05x          3.16x
 8388608   6.15e+00   2.67e+00          -   8.19e-01         7.51x          3.26x

There will be a little less overhead for small $n$ if one uses the mpn-like interface instead of the mpz-like radix_integer.

Inversion of a unit mod $B^n$ where $B = 7^{22}$:

       n      padic   fmpz_mod    mpn_mod   radix_integer    speedup/padic  speedup/fmpz_mod
       1   2.10e-07   4.79e-08          -   3.09e-08         6.80x          1.55x
       2   3.57e-07   3.16e-07   2.59e-07   5.19e-08         6.88x          6.09x
       4   6.01e-07   6.35e-07   5.76e-07   1.12e-07         5.37x          5.67x
       8   8.83e-07   1.40e-06   1.33e-06   2.36e-07         3.74x          5.93x
      16   1.45e-06   2.89e-06   2.84e-06   5.75e-07         2.52x          5.03x
      32   3.00e-06   6.35e-06          -   1.56e-06         1.92x          4.07x
      64   7.70e-06   1.59e-05          -   4.26e-06         1.81x          3.73x
     128   2.23e-05   4.64e-05          -   1.28e-05         1.74x          3.63x
     256   6.61e-05   1.40e-04          -   2.84e-05         2.33x          4.93x
     512   1.92e-04   4.67e-04          -   5.97e-05         3.22x          7.82x
    1024   5.41e-04   1.39e-03          -   1.25e-04         4.33x          11.12x
    2048   1.47e-03   4.06e-03          -   2.66e-04         5.53x          15.26x
    4096   3.41e-03   1.13e-02          -   5.61e-04         6.08x          20.14x
    8192   7.21e-03   3.09e-02          -   1.17e-03         6.16x          26.41x
   16384   1.48e-02   8.85e-02          -   2.46e-03         6.02x          35.98x
   32768   3.02e-02   2.09e-01          -   5.08e-03         5.94x          41.14x
   65536   6.19e-02   5.10e-01          -   1.04e-02         5.95x          49.04x
  131072   1.38e-01   1.23e+00          -   2.21e-02         6.24x          55.43x
  262144   2.86e-01   2.90e+00          -   4.69e-02         6.10x          61.77x
  524288   6.04e-01   6.84e+00          -   1.02e-01         5.92x          67.03x
 1048576   1.28e+00   1.59e+01          -   2.23e-01         5.73x          71.22x
 2097152   2.73e+00   3.74e+01          -   4.80e-01         5.69x          77.89x
 4194304   5.85e+00   8.72e+01          -   1.06e+00         5.52x          82.20x
 8388608   1.29e+01   2.01e+02          -   2.22e+00         5.79x          90.59x

It remains to implement functions that accept a digit count rather than a limb count. These are more fiddly and will inevitably have some more overhead. In practice, the most efficient way to implement $\mathbb{Z} / p^e \mathbb{Z}$ for specific $e$ (or $\mathbb{Q}_p$ with digit-granular precision) will probably be to actually use whole limbs internally and reduce modulo a fractional limb only when strictly needed, e.g. when doing a comparison.

@fredrik-johansson fredrik-johansson merged commit f01a637 into flintlib:main Jan 21, 2026
13 checks passed
@fredrik-johansson fredrik-johansson deleted the radix2 branch January 21, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant