Skip to content

Scalar Toom multiplication for fmpz_poly - #2813

Merged
fredrik-johansson merged 2 commits into
flintlib:mainfrom
fredrik-johansson:toom
Aug 28, 2026
Merged

Scalar Toom multiplication for fmpz_poly#2813
fredrik-johansson merged 2 commits into
flintlib:mainfrom
fredrik-johansson:toom

Conversation

@fredrik-johansson

Copy link
Copy Markdown
Collaborator

Adds fmpz_poly_mul_toom_scalar and fmpz_poly_mulmid_toom_scalar, "scalar" meaning Toom evaluation/interpolation done on the scalar level rather than recursively on polynomials. Supports full products of length up to 20, limited by 64-bit precomputed lookup tables. Pure middle products use transposed Newton interpolation; general truncated products internally pad to a full product or a pure middle product, whichever is shorter.

Developed using Claude Opus 5.

Nice feature of the algorithm: full products write the output in-place with zero scratch space, so this is extremely memory-efficient.

Performance comparison below of fmpz_poly_mulmid_toom_scalar alongside fmpz_poly_mulmid_classical_fft_small. The numbers show the speedup compared to the current fmpz_poly_mul/fmpz_poly_mullow/fmpz_poly_mulmid, i.e. >1.000 means winning over the current default algorithm.

"mul" is n x n -> 2n-1, "mullow" is n x n -> n, "mulmid" is 2n x n -> 2n

                     mul              mullow          mulmid
      bits  n    toom   fft       toom   fft       toom   fft

      1000  2    1.203  0.061     0.849  0.056     0.787  0.068
      1000  3    1.052  0.107     0.656  0.108     0.659  0.127
      1000  4    0.983  0.129     0.589  0.110     0.718  0.168
      1000  5    0.941  0.156     0.583  0.127     0.784  0.188
      1000  6    0.954  0.183     0.587  0.152     0.797  0.235
      1000  7    1.982  0.427     0.587  0.176     2.466  0.778
      1000  8    1.669  0.384     0.590  0.204     1.712  0.589
      1000  9    1.333  0.333     1.399  0.489     1.542  0.589
      1000 10    1.134  0.318     1.223  0.498     1.338  0.523

     10000  2    1.331  1.105     0.966  1.029     1.242  1.124
     10000  3    1.659  0.968     1.088  0.979     1.456  1.287
     10000  4    1.967  1.212     1.196  1.042     1.778  1.353
     10000  5    1.364  0.881     1.370  1.407     1.490  1.421
     10000  6    1.248  0.837     1.474  1.706     1.350  1.150
     10000  7    1.176  0.810     1.596  1.750     1.424  1.422
     10000  8    1.095  0.747     1.716  1.750     1.336  1.312
     10000  9    1.129  0.819     1.034  1.139     1.250  1.360
     10000 10    1.069  0.790     0.993  1.280     1.205  1.270

    100000  2    1.327  1.403     1.009  1.322     1.276  1.465
    100000  3    1.684  1.558     1.122  1.679     1.632  2.149
    100000  4    2.079  2.192     1.285  2.069     1.948  2.190
    100000  5    1.042  1.022     1.475  2.400     1.330  1.768
    100000  6    0.984  0.998     1.613  2.465     1.265  1.552
    100000  7    1.041  1.058     1.790  3.013     1.266  1.695
    100000  8    0.993  1.058     1.930  3.139     1.264  1.670
    100000  9    0.964  1.025     0.908  1.498     1.169  1.643
    100000 10    0.899  0.932     0.856  1.270     1.107  1.534

   1000000  2    1.313  0.919     0.988  0.793     1.300  1.553
   1000000  3    1.710  1.840     1.136  1.650     1.628  2.011
   1000000  4    2.084  2.071     1.293  1.815     2.003  2.351
   1000000  5    1.397  1.449     1.472  2.345     1.593  2.086
   1000000  6    1.352  1.364     1.645  2.493     1.500  1.944
   1000000  7    1.290  1.300     1.845  2.857     1.522  1.962
   1000000  8    1.231  1.231     1.935  2.830     1.491  1.890
   1000000  9    1.146  1.134     1.034  1.573     1.455  1.878
   1000000 10    1.220  1.232     1.064  1.674     1.381  1.701

  10000000  2    1.311  1.337     1.000  1.254     1.265  1.207
  10000000  3    1.792  1.938     1.128  1.147     1.606  2.133
  10000000  4    2.083  2.372     1.291  1.509     1.981  2.673
  10000000  5    1.893  1.958     1.455  1.760     2.071  2.435
  10000000  6    1.248  1.146     1.610  2.485     1.886  2.292
  10000000  7    1.091  1.074     1.809  2.606     1.960  2.536
  10000000  8    1.108  1.206     1.959  3.080     1.418  1.611
  10000000  9    1.117  1.171     0.972  1.479     1.902  2.239
  10000000 10    1.188  1.126     1.031  1.408     1.853  2.189

 100000000  2    1.336  0.989     1.012  0.910     1.302  1.057
 100000000  3    1.705  1.358     1.118  1.241     1.543  1.608
 100000000  4    2.024  1.792     1.295  1.521     1.842  2.002
 100000000  5    1.594  1.360     1.429  1.724     1.984  2.161
 100000000  6    1.225  1.031     1.596  1.968     1.989  2.175
 100000000  7    1.282  1.144     1.740  2.225     1.974  2.153

This shows that Toom generally beats or matches FFT caching for full products, while FFT caching generally wins for low products; for middle products the winner varies with the bit size.

Either way, there is now a lot to gain in fmpz_poly_mul and variants by switching to these algorithms for short polynomials with large coefficients. However, this will have to wait until there is better Karatsuba and maybe recursive Toom to compare with.

@fredrik-johansson
fredrik-johansson merged commit 7c8c3c8 into flintlib:main Aug 28, 2026
21 of 22 checks passed
@fredrik-johansson
fredrik-johansson deleted the toom branch August 28, 2026 12: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