LCOV - code coverage report
Current view: top level - src/grpp - grpp_specfunc_dawson.c (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:dc5a454) Lines: 0 114 0.0 %
Date: 2025-06-17 07:40:17 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*----------------------------------------------------------------------------*/
       2             : /*  CP2K: A general program to perform molecular dynamics simulations         */
       3             : /*  Copyright 2000-2025 CP2K developers group <https://cp2k.org>              */
       4             : /*                                                                            */
       5             : /*  SPDX-License-Identifier: MIT                                              */
       6             : /*----------------------------------------------------------------------------*/
       7             : 
       8             : /*
       9             :  *  libgrpp - a library for the evaluation of integrals over
      10             :  *            generalized relativistic pseudopotentials.
      11             :  *
      12             :  *  Copyright (C) 2021-2023 Alexander Oleynichenko
      13             :  */
      14             : 
      15             : #include <float.h> // required for LDBL_EPSILON
      16             : #include <math.h>  // required for fabsl()
      17             : #ifndef M_PI
      18             : #define M_PI 3.1415926535897932384626433
      19             : #endif
      20             : 
      21             : #include "grpp_specfunc.h"
      22             : 
      23             : /*
      24             :  * This code is taken from the website:
      25             :  * http://www.mymathlib.com/functions/dawsons_integral.html
      26             :  */
      27             : 
      28             : ////////////////////////////////////////////////////////////////////////////////
      29             : // File: specfunc_dawson.c                                                    //
      30             : // Routine(s):                                                                //
      31             : //    Dawsons_Integral                                                        //
      32             : //    xDawsons_Integral                                                       //
      33             : ////////////////////////////////////////////////////////////////////////////////
      34             : ////////////////////////////////////////////////////////////////////////////////
      35             : //  Description:                                                              //
      36             : //     Dawson's integral, Daw(x), is the integral from 0 to x of the          //
      37             : //     integrand:                                                             //
      38             : //                          exp(-x^2) exp(t^2) dt.                            //
      39             : //     I.e.                                                                   //
      40             : //                Daw(x) = exp(-x^2) * I[0,x] (exp(t^2)) dt,                  //
      41             : //     where I[0,x] indicates the integral from 0 to x.                       //
      42             : ////////////////////////////////////////////////////////////////////////////////
      43             : #define Asymptotic_Expansion_Cutoff 50
      44             : 
      45             : //                         Externally Defined Routines                        //
      46             : static long double xChebyshev_Tn_Series(long double x, long double a[],
      47             :                                         int degree);
      48             : 
      49             : //                         Internally Defined Routines                        //
      50             : double libgrpp_Dawsons_Integral(double x);
      51             : long double xDawsons_Integral(long double x);
      52             : 
      53             : static long double Dawson_Power_Series(long double x);
      54             : static long double Dawson_Chebyshev_Expansion_1_175(long double x);
      55             : static long double Dawson_Chebyshev_Expansion_175_250(long double x);
      56             : static long double Dawson_Chebyshev_Expansion_250_325(long double x);
      57             : static long double Dawson_Chebyshev_Expansion_325_425(long double x);
      58             : static long double Dawson_Chebyshev_Expansion_425_550(long double x);
      59             : static long double Dawson_Chebyshev_Expansion_550_725(long double x);
      60             : static long double Dawson_Asymptotic_Expansion(long double x);
      61             : 
      62             : ////////////////////////////////////////////////////////////////////////////////
      63             : // double libgrpp_Dawsons_Integral( double x ) //
      64             : //                                                                            //
      65             : //  Description:                                                              //
      66             : //     Dawson's integral, Daw(x), is the integral with integrand              //
      67             : //                          exp(-x^2) exp(t^2) dt                             //
      68             : //     where the integral extends from 0 to x.                                //
      69             : //                                                                            //
      70             : //  Arguments:                                                                //
      71             : //     double  x  The argument of Dawson's integral Daw().                    //
      72             : //                                                                            //
      73             : //  Return Value:                                                             //
      74             : //     The value of Dawson's integral, Daw(), evaluated at x.                 //
      75             : //                                                                            //
      76             : //  Example:                                                                  //
      77             : //     double y, x;                                                           //
      78             : //                                                                            //
      79             : //     ( code to initialize x )                                               //
      80             : //                                                                            //
      81             : //     y = Dawsons_Integral( x );                                             //
      82             : ////////////////////////////////////////////////////////////////////////////////
      83           0 : double libgrpp_Dawsons_Integral(double x) {
      84           0 :   return (double)xDawsons_Integral((long double)x);
      85             : }
      86             : 
      87             : ////////////////////////////////////////////////////////////////////////////////
      88             : // long double xDawsons_Integral( long double x )                             //
      89             : //                                                                            //
      90             : //  Description:                                                              //
      91             : //     Dawson's integral, Daw(x), is the integral with integrand              //
      92             : //                          exp(-x^2) exp(t^2) dt                             //
      93             : //     where the integral extends from 0 to x.                                //
      94             : //                                                                            //
      95             : //  Arguments:                                                                //
      96             : //     long double  x  The argument of Dawson's integral Daw().               //
      97             : //                                                                            //
      98             : //  Return Value:                                                             //
      99             : //     The value of Dawson's integral, Daw(), evaluated at x.                 //
     100             : //                                                                            //
     101             : //  Example:                                                                  //
     102             : //     long double y, x;                                                      //
     103             : //                                                                            //
     104             : //     ( code to initialize x )                                               //
     105             : //                                                                            //
     106             : //     y = xDawsons_Integral( x );                                            //
     107             : ////////////////////////////////////////////////////////////////////////////////
     108             : 
     109           0 : long double xDawsons_Integral(long double x) {
     110           0 :   long double abs_x = fabsl(x);
     111             : 
     112           0 :   if (abs_x <= 1.0L)
     113           0 :     return Dawson_Power_Series(x);
     114           0 :   if (abs_x <= 1.75L)
     115           0 :     return Dawson_Chebyshev_Expansion_1_175(x);
     116           0 :   if (abs_x <= 2.50L)
     117           0 :     return Dawson_Chebyshev_Expansion_175_250(x);
     118           0 :   if (abs_x <= 3.25L)
     119           0 :     return Dawson_Chebyshev_Expansion_250_325(x);
     120           0 :   if (abs_x <= 4.25L)
     121           0 :     return Dawson_Chebyshev_Expansion_325_425(x);
     122           0 :   if (abs_x <= 5.50L)
     123           0 :     return Dawson_Chebyshev_Expansion_425_550(x);
     124           0 :   if (abs_x <= 7.25L)
     125           0 :     return Dawson_Chebyshev_Expansion_550_725(x);
     126           0 :   return Dawson_Asymptotic_Expansion(x);
     127             : }
     128             : 
     129             : ////////////////////////////////////////////////////////////////////////////////
     130             : // static long double Dawson_Power_Series( long double x )                    //
     131             : //                                                                            //
     132             : //  Description:                                                              //
     133             : //     Evaluate Dawsons integral for -1 <= x <= 1 using the power series      //
     134             : //     expansion:                                                             //
     135             : //                  Daw(x) = x Sum [(-2x^2)^j / (2j + 1)!!,                   //
     136             : //     where the sum extends over j = 0, ... .                                //
     137             : //                                                                            //
     138             : //  Arguments:                                                                //
     139             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     140             : //                     where |x| <= 1.                                        //
     141             : //                                                                            //
     142             : //  Return Value:                                                             //
     143             : //     The value of Dawson's integral, Daw(), evaluated at x where |x| <= 1.  //
     144             : //                                                                            //
     145             : //  Example:                                                                  //
     146             : //     long double y, x;                                                      //
     147             : //                                                                            //
     148             : //     ( code to initialize x )                                               //
     149             : //                                                                            //
     150             : //     y = Dawson_Power_Series(x);                                            //
     151             : ////////////////////////////////////////////////////////////////////////////////
     152             : 
     153           0 : static long double Dawson_Power_Series(long double x) {
     154           0 :   long double two_x2 = -2.0L * x * x;
     155           0 :   long double sum = 0.0;
     156           0 :   long double term = 1.0L;
     157           0 :   long double factorial = 1.0L;
     158           0 :   long double xn = 1.0L;
     159           0 :   const long double epsilon = LDBL_EPSILON / 2.0L;
     160           0 :   int y = 0;
     161             : 
     162           0 :   if (x == 0.0L)
     163             :     return 0.0L;
     164           0 :   do {
     165           0 :     sum += term;
     166           0 :     y += 1;
     167           0 :     factorial *= (long double)(y + y + 1);
     168           0 :     xn *= two_x2;
     169           0 :     term = xn / factorial;
     170           0 :   } while (fabsl(term) > epsilon * fabsl(sum));
     171           0 :   return x * sum;
     172             : }
     173             : 
     174             : ////////////////////////////////////////////////////////////////////////////////
     175             : // static long double Dawson_Chebyshev_Expansion_1_175( long double x )       //
     176             : //                                                                            //
     177             : //  Description:                                                              //
     178             : //     Evaluate Dawsons integral for 1 <= |x| <= 1.75 using the Chebyshev     //
     179             : //     expansion of Daw(x) for x in the interval [1,1.75].                    //
     180             : //                                                                            //
     181             : //  Arguments:                                                                //
     182             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     183             : //                     where 1 <= |x| <= 1.75.                                //
     184             : //                                                                            //
     185             : //  Return Value:                                                             //
     186             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     187             : //     1 <= x <= 1.75.                                                        //
     188             : //                                                                            //
     189             : //  Example:                                                                  //
     190             : //     long double y, x;                                                      //
     191             : //                                                                            //
     192             : //     ( code to initialize x )                                               //
     193             : //                                                                            //
     194             : //     y = Dawson_Chebyshev_Expansion_1_175(x);                               //
     195             : ////////////////////////////////////////////////////////////////////////////////
     196             : 
     197           0 : static long double Dawson_Chebyshev_Expansion_1_175(long double x) {
     198           0 :   static long double c[] = {
     199             :       +4.563960711239483142081e-1L,  -9.268566100670767619861e-2L,
     200             :       -7.334392170021420220239e-3L,  +3.379523740404396755124e-3L,
     201             :       -3.085898448678595090813e-4L,  -1.519846724619319512311e-5L,
     202             :       +4.903955822454009397182e-6L,  -2.106910538629224721838e-7L,
     203             :       -2.930676220603996192089e-8L,  +3.326790071774057337673e-9L,
     204             :       +3.335593457695769191326e-11L, -2.279104036721012221982e-11L,
     205             :       +7.877561633156348806091e-13L, +9.173158167107974472228e-14L,
     206             :       -7.341175636102869400671e-15L, -1.763370444125849029511e-16L,
     207             :       +3.792946298506435014290e-17L, -4.251969162435936250171e-19L,
     208             :       -1.358295820818448686821e-19L, +5.268740962820224108235e-21L,
     209             :       +3.414939674304748094484e-22L};
     210             : 
     211           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     212           0 :   static const long double midpoint = (1.75L + 1.0L) / 2.0L;
     213           0 :   static const long double half_length = (1.75L - 1.0L) / 2.0L;
     214           0 :   long double daw =
     215           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     216           0 :   return (x > 0.0L) ? daw : -daw;
     217             : }
     218             : 
     219             : ////////////////////////////////////////////////////////////////////////////////
     220             : // static long double Dawson_Chebyshev_Expansion_175_250( long double x )     //
     221             : //                                                                            //
     222             : //  Description:                                                              //
     223             : //     Evaluate Dawsons integral for 1.75 <= |x| <= 2.50 using the Chebyshev  //
     224             : //     expansion of Daw(x) for x in the interval [1.75,2.50].                 //
     225             : //                                                                            //
     226             : //  Arguments:                                                                //
     227             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     228             : //                     where 1.75 <= |x| <= 2.50.                             //
     229             : //                                                                            //
     230             : //  Return Value:                                                             //
     231             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     232             : //     1.75 <= x <= 2.50.                                                     //
     233             : //                                                                            //
     234             : //  Example:                                                                  //
     235             : //     long double y, x;                                                      //
     236             : //                                                                            //
     237             : //     ( code to initialize x )                                               //
     238             : //                                                                            //
     239             : //     y = Dawson_Chebyshev_Expansion_175_250(x);                             //
     240             : ////////////////////////////////////////////////////////////////////////////////
     241             : 
     242           0 : static long double Dawson_Chebyshev_Expansion_175_250(long double x) {
     243           0 :   static long double c[] = {
     244             :       +2.843711194548592808550e-1L,  -6.791774139166808940530e-2L,
     245             :       +6.955211059379384327814e-3L,  -2.726366582146839486784e-4L,
     246             :       -6.516682485087925163874e-5L,  +1.404387911504935155228e-5L,
     247             :       -1.103288540946056915318e-6L,  -1.422154597293404846081e-8L,
     248             :       +1.102714664312839585330e-8L,  -8.659211557383544255053e-10L,
     249             :       -8.048589443963965285748e-12L, +6.092061709996351761426e-12L,
     250             :       -3.580977611213519234324e-13L, -1.085173558590137965737e-14L,
     251             :       +2.411707924175380740802e-15L, -7.760751294610276598631e-17L,
     252             :       -6.701490147030045891595e-18L, +6.350145841254563572100e-19L,
     253             :       -2.034625734538917052251e-21L, -2.260543651146274653910e-21L,
     254             :       +9.782419961387425633151e-23L};
     255             : 
     256           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     257           0 :   static const long double midpoint = (2.50L + 1.75L) / 2.0L;
     258           0 :   static const long double half_length = (2.50L - 1.75L) / 2.0;
     259           0 :   long double daw =
     260           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     261           0 :   return (x > 0.0L) ? daw : -daw;
     262             : }
     263             : 
     264             : ////////////////////////////////////////////////////////////////////////////////
     265             : // static long double Dawson_Chebyshev_Expansion_250_325( long double x )     //
     266             : //                                                                            //
     267             : //  Description:                                                              //
     268             : //     Evaluate Dawsons integral for 2.5 <= |x| <= 3.25 using the Chebyshev   //
     269             : //     expansion of Daw(x) for x in the interval [2.50,3.25].                 //
     270             : //                                                                            //
     271             : //  Arguments:                                                                //
     272             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     273             : //                     where 2.50 <= |x| <= 3.25.                             //
     274             : //                                                                            //
     275             : //  Return Value:                                                             //
     276             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     277             : //     2.50 <= x <= 3.25.                                                     //
     278             : //                                                                            //
     279             : //  Example:                                                                  //
     280             : //     long double y, x;                                                      //
     281             : //                                                                            //
     282             : //     ( code to initialize x )                                               //
     283             : //                                                                            //
     284             : //     y = Dawson_Chebyshev_Expansion_250_325(x);                             //
     285             : ////////////////////////////////////////////////////////////////////////////////
     286             : 
     287           0 : static long double Dawson_Chebyshev_Expansion_250_325(long double x) {
     288           0 :   static long double c[] = {
     289             :       +1.901351274204578126827e-1L,  -3.000575522193632460118e-2L,
     290             :       +2.672138524890489432579e-3L,  -2.498237548675235150519e-4L,
     291             :       +2.013483163459701593271e-5L,  -8.454663603108548182962e-7L,
     292             :       -8.036589636334016432368e-8L,  +2.055498509671357933537e-8L,
     293             :       -2.052151324060186596995e-9L,  +8.584315967075483822464e-11L,
     294             :       +5.062689357469596748991e-12L, -1.038671167196342609090e-12L,
     295             :       +6.367962851860231236238e-14L, +3.084688422647419767229e-16L,
     296             :       -3.417946142546575188490e-16L, +2.311567730100119302160e-17L,
     297             :       -6.170132546983726244716e-20L, -9.133176920944950460847e-20L,
     298             :       +5.712092431423316128728e-21L, +1.269641078369737220790e-23L,
     299             :       -2.072659711527711312699e-23L};
     300             : 
     301           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     302           0 :   static const long double midpoint = (3.25L + 2.50L) / 2.0L;
     303           0 :   static const long double half_length = (3.25L - 2.50L) / 2.0L;
     304           0 :   long double daw =
     305           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     306           0 :   return (x > 0.0L) ? daw : -daw;
     307             : }
     308             : 
     309             : ////////////////////////////////////////////////////////////////////////////////
     310             : // static long double Dawson_Chebyshev_Expansion_325_425( long double x )     //
     311             : //                                                                            //
     312             : //  Description:                                                              //
     313             : //     Evaluate Dawsons integral for 3.25 <= |x| <= 4.25 using the Chebyshev  //
     314             : //     expansion of Daw(x) for x in the interval [3.25,4.75].                 //
     315             : //                                                                            //
     316             : //  Arguments:                                                                //
     317             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     318             : //                     where 3.25 <= |x| <= 4.25.                             //
     319             : //                                                                            //
     320             : //  Return Value:                                                             //
     321             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     322             : //     3.25 <= x <= 4.25.                                                     //
     323             : //                                                                            //
     324             : //  Example:                                                                  //
     325             : //     long double y, x;                                                      //
     326             : //                                                                            //
     327             : //     ( code to initialize x )                                               //
     328             : //                                                                            //
     329             : //     y = Dawson_Chebyshev_Expansion_325_425(x);                             //
     330             : ////////////////////////////////////////////////////////////////////////////////
     331             : 
     332           0 : static long double Dawson_Chebyshev_Expansion_325_425(long double x) {
     333           0 :   static long double c[] = {
     334             :       +1.402884974484995678749e-1L,  -2.053975371995937033959e-2L,
     335             :       +1.595388628922920119352e-3L,  -1.336894584910985998203e-4L,
     336             :       +1.224903774178156286300e-5L,  -1.206856028658387948773e-6L,
     337             :       +1.187997233269528945503e-7L,  -1.012936061496824448259e-8L,
     338             :       +5.244408240062370605664e-10L, +2.901444759022254846562e-11L,
     339             :       -1.168987502493903926906e-11L, +1.640096995420504465839e-12L,
     340             :       -1.339190668554209618318e-13L, +3.643815972666851044790e-15L,
     341             :       +6.922486581126169160232e-16L, -1.158761251467106749752e-16L,
     342             :       +8.164320395639210093180e-18L, -5.397918405779863087588e-20L,
     343             :       -5.052069908100339242896e-20L, +5.322512674746973445361e-21L,
     344             :       -1.869294542789169825747e-22L};
     345             : 
     346           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     347             :   // static const long double lower_bound = 3.25L;
     348             :   // static const long double upper_bound = 4.25L;
     349           0 :   static const long double midpoint = (4.25L + 3.25L) / 2.0L;
     350           0 :   static const long double half_length = (4.25L - 3.25L) / 2.0L;
     351           0 :   long double daw =
     352           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     353           0 :   return (x > 0.0L) ? daw : -daw;
     354             : }
     355             : 
     356             : ////////////////////////////////////////////////////////////////////////////////
     357             : // static long double Dawson_Chebyshev_Expansion_425_550( long double x )     //
     358             : //                                                                            //
     359             : //  Description:                                                              //
     360             : //     Evaluate Dawsons integral for 4.25 <= |x| <= 5.50 using the Chebyshev  //
     361             : //     expansion of Daw(x) for x in the interval [4.25,5.50].                 //
     362             : //                                                                            //
     363             : //  Arguments:                                                                //
     364             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     365             : //                     where 4.25 <= |x| <= 5.50.                             //
     366             : //                                                                            //
     367             : //  Return Value:                                                             //
     368             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     369             : //     4.25 <= x <= 5.50.                                                     //
     370             : //                                                                            //
     371             : //  Example:                                                                  //
     372             : //     long double y, x;                                                      //
     373             : //                                                                            //
     374             : //     ( code to initialize x )                                               //
     375             : //                                                                            //
     376             : //     y = Dawson_Chebyshev_Expansion_425_550(x);                             //
     377             : ////////////////////////////////////////////////////////////////////////////////
     378             : 
     379           0 : static long double Dawson_Chebyshev_Expansion_425_550(long double x) {
     380           0 :   static long double c[] = {
     381             :       +1.058610209741581514157e-1L,  -1.429297757627935191694e-2L,
     382             :       +9.911301703835545472874e-4L,  -7.079903107876049846509e-5L,
     383             :       +5.229587914675267516134e-6L,  -4.016071345964089296212e-7L,
     384             :       +3.231734714422926453741e-8L,  -2.752870944370338482109e-9L,
     385             :       +2.503059741885009530630e-10L, -2.418699000594890423278e-11L,
     386             :       +2.410158905786160001792e-12L, -2.327254341132174000949e-13L,
     387             :       +1.958284411563056492727e-14L, -1.099893145048991004460e-15L,
     388             :       -2.959085292526991317697e-17L, +1.966366179276295203082e-17L,
     389             :       -3.314408783993662492621e-18L, +3.635520318133814622089e-19L,
     390             :       -2.550826919215104648800e-20L, +3.830090587178262542288e-22L,
     391             :       +1.836693763159216122739e-22L};
     392             : 
     393           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     394           0 :   static const long double midpoint = (5.50L + 4.25L) / 2.0L;
     395           0 :   static const long double half_length = (5.50L - 4.25L) / 2.0L;
     396           0 :   long double daw =
     397           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     398           0 :   return (x > 0.0L) ? daw : -daw;
     399             : }
     400             : 
     401             : ////////////////////////////////////////////////////////////////////////////////
     402             : // static long double Dawson_Chebyshev_Expansion_550_725( long double x )     //
     403             : //                                                                            //
     404             : //  Description:                                                              //
     405             : //     Evaluate Dawsons integral for 5.50 <= |x| <= 7.25 using the Chebyshev  //
     406             : //     expansion of Daw(x) for x in the interval [5.50,7.25].                 //
     407             : //                                                                            //
     408             : //  Arguments:                                                                //
     409             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     410             : //                     where 5.50 <= |x| <= 7.25.                             //
     411             : //                                                                            //
     412             : //  Return Value:                                                             //
     413             : //     The value of Dawson's integral, Daw(), evaluated at x where            //
     414             : //     5.50 <= x <= 7.25.                                                     //
     415             : //                                                                            //
     416             : //  Example:                                                                  //
     417             : //     long double y, x;                                                      //
     418             : //                                                                            //
     419             : //     ( code to initialize x )                                               //
     420             : //                                                                            //
     421             : //     y = Dawson_Chebyshev_Expansion_550_725(x);                             //
     422             : ////////////////////////////////////////////////////////////////////////////////
     423             : 
     424           0 : static long double Dawson_Chebyshev_Expansion_550_725(long double x) {
     425           0 :   static long double c[] = {+8.024637207807814739314e-2L,
     426             :                             -1.136614891549306029413e-2L,
     427             :                             +8.164249750628661856014e-4L,
     428             :                             -5.951964778701328943018e-5L,
     429             :                             +4.407349502747483429390e-6L,
     430             :                             -3.317746826184531133862e-7L,
     431             :                             +2.541483569880571680365e-8L,
     432             :                             -1.983391157250772649001e-9L,
     433             :                             +1.579050614491277335581e-10L,
     434             :                             -1.284592098551537518322e-11L,
     435             :                             +1.070070857004674207604e-12L,
     436             :                             -9.151832297362522251950e-14L,
     437             :                             +8.065447314948125338081e-15L,
     438             :                             -7.360105847607056315915e-16L,
     439             :                             +6.995966000187407197283e-17L,
     440             :                             -6.964349343411584120055e-18L,
     441             :                             +7.268789359189778223225e-19L,
     442             :                             -7.885125241947769024019e-20L,
     443             :                             +8.689022564130615225208e-21L,
     444             :                             -9.353211304381231554634e-22L +
     445             :                                 9.218280404899298404756e-23L};
     446             : 
     447           0 :   static const int degree = sizeof(c) / sizeof(long double) - 1;
     448             :   // static const long double lower_bound = 5.50L;
     449             :   // static const long double upper_bound = 7.25L;
     450           0 :   static const long double midpoint = (7.25L + 5.50L) / 2.0L;
     451           0 :   static const long double half_length = (7.25L - 5.50L) / 2.0L;
     452           0 :   long double daw =
     453           0 :       xChebyshev_Tn_Series((fabsl(x) - midpoint) / half_length, c, degree);
     454           0 :   return (x > 0.0L) ? daw : -daw;
     455             : }
     456             : 
     457             : ////////////////////////////////////////////////////////////////////////////////
     458             : // static long double Dawson_Asymptotic_Expansion( long double x )            //
     459             : //                                                                            //
     460             : //  Description:                                                              //
     461             : //     For a large magnitude of the argument x, Dawson's integral can be      //
     462             : //     expressed as the asymptotic series                                     //
     463             : //     Daw(x) ~ (1/2x) [ 1 + 1 / (2x^2) + ... + (2j - 1)!! / (2x^2)^j + ... ] //
     464             : //                                                                            //
     465             : //  Arguments:                                                                //
     466             : //     long double  x  The argument of Dawson's integral Daw(), where         //
     467             : //                     |x| > 7.                                               //
     468             : //                                                                            //
     469             : //  Return Value:                                                             //
     470             : //     The value of Dawson's integral, Daw(), evaluated at x where |x| > 7.   //
     471             : //                                                                            //
     472             : //  Example:                                                                  //
     473             : //     long double y, x;                                                      //
     474             : //                                                                            //
     475             : //     ( code to initialize x )                                               //
     476             : //                                                                            //
     477             : //     y = Dawson_Asymptotic_Expansion( x );                                  //
     478             : ////////////////////////////////////////////////////////////////////////////////
     479           0 : static long double Dawson_Asymptotic_Expansion(long double x) {
     480           0 :   long double term[Asymptotic_Expansion_Cutoff + 1];
     481           0 :   long double x2 = x * x;
     482           0 :   long double two_x = x + x;
     483           0 :   long double two_x2 = x2 + x2;
     484           0 :   long double xn = two_x2;
     485           0 :   long double Sn = 0.0L;
     486           0 :   long double factorial = 1.0L;
     487           0 :   int n;
     488             : 
     489           0 :   term[0] = 1.0L;
     490           0 :   term[1] = 1.0L / xn;
     491           0 :   for (n = 2; n <= Asymptotic_Expansion_Cutoff; n++) {
     492           0 :     xn *= two_x2;
     493           0 :     factorial *= (long double)(n + n - 1);
     494           0 :     term[n] = factorial / xn;
     495           0 :     if (term[n] < LDBL_EPSILON / 2.0L)
     496             :       break;
     497             :   }
     498             : 
     499           0 :   if (n > Asymptotic_Expansion_Cutoff)
     500             :     n = Asymptotic_Expansion_Cutoff;
     501           0 :   for (; n >= 0; n--)
     502           0 :     Sn += term[n];
     503           0 :   return Sn / two_x;
     504             : }
     505             : 
     506             : ////////////////////////////////////////////////////////////////////////////////
     507             : // File: xchebyshev_Tn_series.c                                               //
     508             : // Routine(s):                                                                //
     509             : //    xChebyshev_Tn_Series                                                    //
     510             : ////////////////////////////////////////////////////////////////////////////////
     511             : ////////////////////////////////////////////////////////////////////////////////
     512             : // long double xChebyshev_Tn_Series(long double x, long double a[],int degree)//
     513             : //                                                                            //
     514             : //  Description:                                                              //
     515             : //     This routine uses Clenshaw's recursion algorithm to evaluate a given   //
     516             : //     polynomial p(x) expressed as a linear combination of Chebyshev         //
     517             : //     polynomials of the first kind, Tn, at a point x,                       //
     518             : //       p(x) = a[0] + a[1]*T[1](x) + a[2]*T[2](x) + ... + a[deg]*T[deg](x).  //
     519             : //                                                                            //
     520             : //     Clenshaw's recursion formula applied to Chebyshev polynomials of the   //
     521             : //     first kind is:                                                         //
     522             : //     Set y[degree + 2] = 0, y[degree + 1] = 0, then for k = degree, ..., 1  //
     523             : //     set y[k] = 2 * x * y[k+1] - y[k+2] + a[k].  Finally                    //
     524             : //     set y[0] = x * y[1] - y[2] + a[0].  Then p(x) = y[0].                  //
     525             : //                                                                            //
     526             : //  Arguments:                                                                //
     527             : //     long double x                                                          //
     528             : //        The point at which to evaluate the polynomial.                      //
     529             : //     long double a[]                                                        //
     530             : //        The coefficients of the expansion in terms of Chebyshev polynomials,//
     531             : //        i.e. a[k] is the coefficient of T[k](x).  Note that in the calling  //
     532             : //        routine a must be defined double a[N] where N >= degree + 1.        //
     533             : //     int    degree                                                          //
     534             : //        The degree of the polynomial p(x).                                  //
     535             : //                                                                            //
     536             : //  Return Value:                                                             //
     537             : //     The value of the polynomial at x.                                      //
     538             : //     If degree is negative, then 0.0 is returned.                           //
     539             : //                                                                            //
     540             : //  Example:                                                                  //
     541             : //     long double x, a[N], p;                                                //
     542             : //     int    deg = N - 1;                                                    //
     543             : //                                                                            //
     544             : //     ( code to initialize x, and a[i] i = 0, ... , a[deg] )                 //
     545             : //                                                                            //
     546             : //     p = xChebyshev_Tn_Series(x, a, deg);                                   //
     547             : ////////////////////////////////////////////////////////////////////////////////
     548             : 
     549           0 : static long double xChebyshev_Tn_Series(long double x, long double a[],
     550             :                                         int degree) {
     551           0 :   long double yp2 = 0.0L;
     552           0 :   long double yp1 = 0.0L;
     553           0 :   long double y = 0.0L;
     554           0 :   long double two_x = x + x;
     555           0 :   int k;
     556             : 
     557             :   // Check that degree >= 0.  If not, then return 0. //
     558             : 
     559           0 :   if (degree < 0)
     560             :     return 0.0L;
     561             : 
     562             :   // Apply Clenshaw's recursion save the last iteration. //
     563             : 
     564           0 :   for (k = degree; k >= 1; k--, yp2 = yp1, yp1 = y)
     565           0 :     y = two_x * yp1 - yp2 + a[k];
     566             : 
     567             :   // Now apply the last iteration and return the result. //
     568             : 
     569           0 :   return x * yp1 - yp2 + a[0];
     570             : }

Generated by: LCOV version 1.15