Skip to content

Overhaul tan-like functions of power series#2672

Merged
fredrik-johansson merged 1 commit into
flintlib:mainfrom
fredrik-johansson:series
May 12, 2026
Merged

Overhaul tan-like functions of power series#2672
fredrik-johansson merged 1 commit into
flintlib:mainfrom
fredrik-johansson:series

Conversation

@fredrik-johansson
Copy link
Copy Markdown
Collaborator

@fredrik-johansson fredrik-johansson commented May 11, 2026

We improve gr_poly_tan_series and add the following variants (with their underscore methods):

  • gr_poly_tanh_series
  • gr_poly_cot_series
  • gr_poly_coth_series
  • gr_poly_tan_pi_series
  • gr_poly_cot_pi_series

We also add wrappers of all these methods for gr_series and gr_series_mod.

Also, arb_poly_tan_series, arb_poly_cot_pi_series acb_poly_tan_series, acb_poly_cot_pi_series, nmod_poly_tan_series and nmod_poly_tanh_series methods are converted to wrappers or simplified in cases where they already partially relied on a gr_poly method. If wanted, one could trivially add more wrappers, e.g. arb_poly_tanh_series.

Algorithm changes:

  • The old basecase algorithm computed the sine and cosine and did a power series division. The new basecase algorithm uses a recurrence
    for the tangent coefficients themselves, which is more efficient.
  • We add gr_tan_series_basecase_sine_cosine as an alternative algorithm to explicitly use the sine/cosine quotient approach.
  • The old Newton algorithm computed the arctangent from scratch each iteration. The new algorithm carries along the Newton iteration for the underlying quotient, extending the precision of the arctangent gradually.
  • There is also a new function gr_tan_series_exponential which uses a quotient of exponentials. For numerical arguments, this attempts to choose the sign of the exponent so that the formula is numerically stable.

Importantly: all six implemented functions (tan, tanh, cot, coth, tan_pi, cot_pi) use the same underlying code with the same heuristic for switching algorithms, the only difference between the functions being some signs and scaling factors. Note that previously acb_poly_cot_pi_series switched between sines, cosines and exponentials depending on the location of the input in the complex plane, but acb_poly_tan_series only used the sine/cosine formula and would lose precision for large imaginary input. Now all functions should have the same numerical stability qualities.

I let Claude write parts of the new code, but I'm not sure if this was faster than doing it entirely by hand as it got stuck long time unsuccessfully trying to debug a sign error in its Newton iteration code. I eventually gave up and fixed that myself.

Timings, tan_series, nmod with 64-bit modulus:

      n           old         new  speedup
      2      2.44e-08    2.34e-08  (1.043)   
      4       1.6e-07    9.55e-08  (1.675)   
      8      3.82e-07     2.7e-07  (1.415)   
     16      9.15e-07    6.89e-07  (1.328)   
     32      2.91e-06    1.68e-06  (1.732)   
     64      7.88e-06    4.31e-06  (1.828)   
    128      2.14e-05    1.18e-05  (1.814)   
    256       6.1e-05    3.62e-05  (1.685)   
    512      0.000143    0.000113  (1.265)   
   1024      0.000318    0.000251  (1.267)   
   2048      0.000752     0.00057  (1.319)   
   4096       0.00169     0.00124  (1.363)   
   8192       0.00368     0.00266  (1.383)   
  16384       0.00789     0.00563  (1.401)   
  32768        0.0167      0.0118  (1.415)   
  65536        0.0353      0.0249  (1.418)   

Again nmod, tanh_series:

      n           old         new  speedup
      1      5.18e-08    1.81e-08  (2.862)   
      2       5.6e-08    2.46e-08  (2.276)   
      4      1.49e-07    9.62e-08  (1.549)   
      8      3.39e-07    2.72e-07  (1.246)   
     16      7.67e-07    6.87e-07  (1.116)   
     32      1.76e-06    1.72e-06  (1.023)   
     64      4.57e-06    4.31e-06  (1.060)   
    128      1.36e-05    1.19e-05  (1.143)   
    256      4.31e-05     3.6e-05  (1.197)   
    512      0.000122    0.000113  (1.080)   
   1024      0.000319    0.000243  (1.313)   
   2048      0.000695    0.000559  (1.243)   
   4096       0.00143     0.00124  (1.153)   
   8192       0.00293     0.00262  (1.118)   
  16384       0.00602     0.00555  (1.085)   
  32768        0.0123      0.0115  (1.070)   
  65536        0.0255      0.0241  (1.058)   
 131072        0.0562      0.0534  (1.052)   
 262144         0.129       0.112  (1.152)   

Timings for tan_series with fmpq coefficients, input series $h = \exp(x) - 1$:

      n           old         new  speedup
      1      1.89e-08    1.75e-08  (1.080)   
      2      3.78e-08    3.52e-08  (1.074)   
      4       5.4e-07    2.66e-07  (2.030)   
      8      1.95e-06       1e-06  (1.950)   
     16      8.67e-06    5.03e-06  (1.724)   
     32      3.04e-05    2.45e-05  (1.241)   
     64      0.000175    0.000161  (1.087)   
    128       0.00111     0.00104  (1.067)   
    256       0.00507      0.0048  (1.056)   
    512        0.0231       0.022  (1.050)   
   1024         0.123       0.113  (1.088)   
   2048          0.69       0.653  (1.057)   
   4096         4.277       4.161  (1.028)   

Results for tan_series with arb coefficients, prec = 1024, input $h = \exp(x)$:

      n           old         new  speedup   [x^(n-1)]  (old)        [x^(n-1)]  (new)
      1      3.88e-06    3.87e-06  (1.003)   1.56 +/- 1.2784e-308    1.56 +/- 1.2784e-308    
      2      4.11e-06    4.17e-06  (0.986)   3.43 +/- 6.2070e-308    3.43 +/- 6.2070e-308    
      4      7.07e-06    5.52e-06  (1.281)   15.4 +/- 1.9933e-306    15.4 +/- 1.0019e-306    
      8       1.6e-05    1.04e-05  (1.538)   3.68e+2 +/- 1.0012e-304    3.68e+2 +/- 5.7167e-305    
     16      5.82e-05    2.97e-05  (1.960)   2.13e+5 +/- 1.2436e-301    2.13e+5 +/- 7.0273e-302    
     32      0.000232    0.000106  (2.189)   7.12e+10 +/- 2.7211e-289    7.12e+10 +/- 5.0842e-296    
     64      0.000733    0.000397  (1.846)   7.96e+21 +/- 7.5761e-273    7.96e+21 +/- 1.1392e-284    
    128       0.00198     0.00159  (1.245)   9.94e+43 +/- 1.0671e-243    9.94e+43 +/- 5.5862e-248    
    256       0.00496     0.00405  (1.225)   1.55e+88 +/- 1.0796e-190    1.55e+88 +/- 1.9360e-194    
    512        0.0119      0.0102  (1.167)   3.79e+176 +/- 1.0617e-91    3.79e+176 +/- 6.2144e-95    
   1024        0.0286      0.0256  (1.117)   2.25e+353 +/- 1.6206e+98    2.25e+353 +/- 3.1210e+95    
   2048        0.0696      0.0621  (1.121)   7.98e+706 +/- 9.4123e+465    7.98e+706 +/- 5.9868e+463    
   4096         0.194       0.164  (1.183)   1.00e+1414 +/- 1.2387e+1189    1.00e+1414 +/- 2.6066e+1187    
   8192         0.502       0.413  (1.215)   1.57e+2828 +/- 1.3078e+2621    1.57e+2828 +/- 9.1110e+2619    
  16384          1.29        1.12  (1.152)   3.87e+5656 +/- 1.3878e+5469    3.87e+5656 +/- 3.2024e+5468    
  32768          3.95       3.449  (1.145)   2.36e+11313 +/- 2.3249e+11147    2.36e+11313 +/- 1.7771e+11147    
  65536        12.118      11.836  (1.024)   8.71e+22626 +/- 1.5161e+22484    8.71e+22626 +/- 3.8391e+22484    

Results for cot_pi_series with acb coefficients, prec = 1024, input $h = \exp(x)-1 + (1/3 + 50i)$:

      n           old         new  speedup   Re [x^(n-1)]  (old)          Re [x^(n-1)]  (new)
      1      8.55e-06    8.56e-06  (0.999)   6.32e-137 +/- 1.6992e-443    6.32e-137 +/- 1.6992e-443    
      2      1.08e-05    1.12e-05  (0.964)   -2.29e-136 +/- 9.4334e-442    -2.29e-136 +/- 9.4813e-442    
      4      1.59e-05    1.56e-05  (1.019)   2.23e-136 +/- 1.1353e-440    2.23e-136 +/- 1.1356e-440    
      8      3.18e-05    3.19e-05  (0.997)   -1.60e-134 +/- 1.4904e-439    -1.60e-134 +/- 1.4931e-439    
     16      0.000127    0.000108  (1.176)   -1.81e-134 +/- 6.8318e-439    -1.81e-134 +/- 6.8378e-439    
     32      0.000715    0.000695  (1.029)   -8.94e-137 +/- 5.3519e-440    -8.94e-137 +/- 1.8512e-426    
     64       0.00222     0.00276  (0.804)   -1.59e-144 +/- 2.8404e-446    -1.59e-144 +/- 1.1798e-420    
    128       0.00617     0.00723  (0.853)   -2.27e-166 +/- 1.0308e-465    -2.27e-166 +/- 6.1312e-419    
    256        0.0157      0.0176  (0.892)   -5.53e-221 +/- 1.9875e-516    -5.53e-221 +/- 5.9431e-433    
    512        0.0448      0.0413  (1.085)   1.40e-349 +/- 6.5023e-506    1.40e-349 +/- 7.5330e-491    
   1024          0.12       0.104  (1.154)   8.65e-640 +/- 3.5126e-673    8.65e-640 +/- 5.7738e-658    
   2048         0.318       0.282  (1.128)   -1.23e-1255 +/- 8.0644e-1097    6.53e-1244 +/- 1.3258e-1081    
   4096         0.947       0.834  (1.135)   -2.67e-2344 +/- 5.4565e-1934    3.16e-2326 +/- 2.0150e-1903    
   8192          3.19       2.802  (1.138)   1.47e-4475 +/- 1.0786e-3606    -5.41e-4446 +/- 2.0091e-3545    
  16384        11.411      10.389  (1.098)   3.48e-8679 +/- 1.0274e-6949    3.92e-8619 +/- 4.8672e-6827    

There is actually some more precision loss in the new code for large n, but I think this is due to differences in acb_poly_exp_series vs gr_poly_exp_series that want independent fixing.

Results for tan_series with acb coefficients, prec = 1024, input $h = \exp(x)-1 + (1/3 + 12345.6i)$:

      n           old         new  speedup   Re [x^(n-1)]  (old)          Re [x^(n-1)]  (new)
      1      8.03e-06    8.03e-06  (1.000)   6.92e-10724 +/- 1.2623e-11027    6.92e-10724 +/- 1.2623e-11027    
      2      8.59e-06    1.02e-05  (0.842)   1.11e-308 +/- 1.6688e-308    1.76e-10723 +/- 3.2097e-11027    
      4      1.45e-05     1.3e-05  (1.115)   -6.14e-310 +/- 2.5883e-303    -2.26e-10723 +/- 5.2008e-11027    
      8      2.89e-05    2.27e-05  (1.273)   -1.13e-310 +/- 7.7381e-302    8.90e-10724 +/- 4.0374e-11027    
     16      0.000118    6.33e-05  (1.864)   -7.61e-311 +/- 7.2597e-302    -7.36e-10727 +/- 2.1157e-11028    
     32      0.000139    0.000823  (0.169)   nan +/- +inf    1.31e-10730 +/- 2.3150e-11022    
     64      0.000485     0.00561  (0.086)   nan +/- +inf    -2.56e-10743 +/- 3.9816e-11025    
    128      0.000848      0.0197  (0.043)   nan +/- +inf    -6.52e-10774 +/- 7.9221e-11038    
    256       0.00141      0.0504  (0.028)   nan +/- +inf    3.03e-10844 +/- 3.1241e-11076    
    512       0.00234       0.115  (0.020)   nan +/- +inf    -2.17e-10999 +/- 1.0624e-11175    
   1024       0.00437       0.269  (0.016)   nan +/- +inf    3.28e-11338 +/- 9.5528e-11415    
   2048        0.0104       0.601  (0.017)   nan +/- +inf    2.06e-12067 +/- 2.3717e-11964    
   4096        0.0292        1.58  (0.018)   nan +/- +inf    -1.24e-13421 +/- 9.6019e-13107    
   8192           0.1       4.184  (0.024)   nan +/- +inf    -5.18e-16086 +/- 6.1636e-15390    

@fredrik-johansson fredrik-johansson merged commit 290bd1b into flintlib:main May 12, 2026
13 checks passed
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