LCOV - code coverage report
Current view: top level - ld80 - e_tgammal.c (source / functions) Coverage Total Hit
Test: app.info Lines: 0.0 % 77 0
Test Date: 2024-01-11 15:52:50 Functions: 0.0 % 2 0
Branches: 0.0 % 40 0

             Branch data     Line data    Source code
       1                 :             : /*      $OpenBSD: e_tgammal.c,v 1.4 2013/11/12 20:35:19 martynas Exp $  */
       2                 :             : 
       3                 :             : /*
       4                 :             :  * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
       5                 :             :  *
       6                 :             :  * Permission to use, copy, modify, and distribute this software for any
       7                 :             :  * purpose with or without fee is hereby granted, provided that the above
       8                 :             :  * copyright notice and this permission notice appear in all copies.
       9                 :             :  *
      10                 :             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11                 :             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12                 :             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13                 :             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14                 :             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15                 :             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16                 :             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17                 :             :  */
      18                 :             : 
      19                 :             : /*                                                      tgammal.c
      20                 :             :  *
      21                 :             :  *      Gamma function
      22                 :             :  *
      23                 :             :  *
      24                 :             :  *
      25                 :             :  * SYNOPSIS:
      26                 :             :  *
      27                 :             :  * long double x, y, tgammal();
      28                 :             :  *
      29                 :             :  * y = tgammal( x );
      30                 :             :  *
      31                 :             :  *
      32                 :             :  *
      33                 :             :  * DESCRIPTION:
      34                 :             :  *
      35                 :             :  * Returns gamma function of the argument.  The result is correctly
      36                 :             :  * signed.  This variable is also filled in by the logarithmic gamma
      37                 :             :  * function lgamma().
      38                 :             :  *
      39                 :             :  * Arguments |x| <= 13 are reduced by recurrence and the function
      40                 :             :  * approximated by a rational function of degree 7/8 in the
      41                 :             :  * interval (2,3).  Large arguments are handled by Stirling's
      42                 :             :  * formula. Large negative arguments are made positive using
      43                 :             :  * a reflection formula.
      44                 :             :  *
      45                 :             :  *
      46                 :             :  * ACCURACY:
      47                 :             :  *
      48                 :             :  *                      Relative error:
      49                 :             :  * arithmetic   domain     # trials      peak         rms
      50                 :             :  *    IEEE     -40,+40      10000       3.6e-19     7.9e-20
      51                 :             :  *    IEEE    -1755,+1755   10000       4.8e-18     6.5e-19
      52                 :             :  *
      53                 :             :  * Accuracy for large arguments is dominated by error in powl().
      54                 :             :  *
      55                 :             :  */
      56                 :             : 
      57                 :             : #include <float.h>
      58                 :             : #include <openlibm_math.h>
      59                 :             : 
      60                 :             : #include "math_private.h"
      61                 :             : 
      62                 :             : /*
      63                 :             : tgamma(x+2)  = tgamma(x+2) P(x)/Q(x)
      64                 :             : 0 <= x <= 1
      65                 :             : Relative error
      66                 :             : n=7, d=8
      67                 :             : Peak error =  1.83e-20
      68                 :             : Relative error spread =  8.4e-23
      69                 :             : */
      70                 :             : 
      71                 :             : static long double P[8] = {
      72                 :             :  4.212760487471622013093E-5L,
      73                 :             :  4.542931960608009155600E-4L,
      74                 :             :  4.092666828394035500949E-3L,
      75                 :             :  2.385363243461108252554E-2L,
      76                 :             :  1.113062816019361559013E-1L,
      77                 :             :  3.629515436640239168939E-1L,
      78                 :             :  8.378004301573126728826E-1L,
      79                 :             :  1.000000000000000000009E0L,
      80                 :             : };
      81                 :             : static long double Q[9] = {
      82                 :             : -1.397148517476170440917E-5L,
      83                 :             :  2.346584059160635244282E-4L,
      84                 :             : -1.237799246653152231188E-3L,
      85                 :             : -7.955933682494738320586E-4L,
      86                 :             :  2.773706565840072979165E-2L,
      87                 :             : -4.633887671244534213831E-2L,
      88                 :             : -2.243510905670329164562E-1L,
      89                 :             :  4.150160950588455434583E-1L,
      90                 :             :  9.999999999999999999908E-1L,
      91                 :             : };
      92                 :             : 
      93                 :             : /*
      94                 :             : static long double P[] = {
      95                 :             : -3.01525602666895735709e0L,
      96                 :             : -3.25157411956062339893e1L,
      97                 :             : -2.92929976820724030353e2L,
      98                 :             : -1.70730828800510297666e3L,
      99                 :             : -7.96667499622741999770e3L,
     100                 :             : -2.59780216007146401957e4L,
     101                 :             : -5.99650230220855581642e4L,
     102                 :             : -7.15743521530849602425e4L
     103                 :             : };
     104                 :             : static long double Q[] = {
     105                 :             :  1.00000000000000000000e0L,
     106                 :             : -1.67955233807178858919e1L,
     107                 :             :  8.85946791747759881659e1L,
     108                 :             :  5.69440799097468430177e1L,
     109                 :             : -1.98526250512761318471e3L,
     110                 :             :  3.31667508019495079814e3L,
     111                 :             :  1.60577839621734713377e4L,
     112                 :             : -2.97045081369399940529e4L,
     113                 :             : -7.15743521530849602412e4L
     114                 :             : };
     115                 :             : */
     116                 :             : #define MAXGAML 1755.455L
     117                 :             : /*static const long double LOGPI = 1.14472988584940017414L;*/
     118                 :             : 
     119                 :             : /* Stirling's formula for the gamma function
     120                 :             : tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
     121                 :             : z(x) = x
     122                 :             : 13 <= x <= 1024
     123                 :             : Relative error
     124                 :             : n=8, d=0
     125                 :             : Peak error =  9.44e-21
     126                 :             : Relative error spread =  8.8e-4
     127                 :             : */
     128                 :             : 
     129                 :             : static long double STIR[9] = {
     130                 :             :  7.147391378143610789273E-4L,
     131                 :             : -2.363848809501759061727E-5L,
     132                 :             : -5.950237554056330156018E-4L,
     133                 :             :  6.989332260623193171870E-5L,
     134                 :             :  7.840334842744753003862E-4L,
     135                 :             : -2.294719747873185405699E-4L,
     136                 :             : -2.681327161876304418288E-3L,
     137                 :             :  3.472222222230075327854E-3L,
     138                 :             :  8.333333333333331800504E-2L,
     139                 :             : };
     140                 :             : 
     141                 :             : #define MAXSTIR 1024.0L
     142                 :             : static const long double SQTPI = 2.50662827463100050242E0L;
     143                 :             : 
     144                 :             : /* 1/tgamma(x) = z P(z)
     145                 :             :  * z(x) = 1/x
     146                 :             :  * 0 < x < 0.03125
     147                 :             :  * Peak relative error 4.2e-23
     148                 :             :  */
     149                 :             : 
     150                 :             : static long double S[9] = {
     151                 :             : -1.193945051381510095614E-3L,
     152                 :             :  7.220599478036909672331E-3L,
     153                 :             : -9.622023360406271645744E-3L,
     154                 :             : -4.219773360705915470089E-2L,
     155                 :             :  1.665386113720805206758E-1L,
     156                 :             : -4.200263503403344054473E-2L,
     157                 :             : -6.558780715202540684668E-1L,
     158                 :             :  5.772156649015328608253E-1L,
     159                 :             :  1.000000000000000000000E0L,
     160                 :             : };
     161                 :             : 
     162                 :             : /* 1/tgamma(-x) = z P(z)
     163                 :             :  * z(x) = 1/x
     164                 :             :  * 0 < x < 0.03125
     165                 :             :  * Peak relative error 5.16e-23
     166                 :             :  * Relative error spread =  2.5e-24
     167                 :             :  */
     168                 :             : 
     169                 :             : static long double SN[9] = {
     170                 :             :  1.133374167243894382010E-3L,
     171                 :             :  7.220837261893170325704E-3L,
     172                 :             :  9.621911155035976733706E-3L,
     173                 :             : -4.219773343731191721664E-2L,
     174                 :             : -1.665386113944413519335E-1L,
     175                 :             : -4.200263503402112910504E-2L,
     176                 :             :  6.558780715202536547116E-1L,
     177                 :             :  5.772156649015328608727E-1L,
     178                 :             : -1.000000000000000000000E0L,
     179                 :             : };
     180                 :             : 
     181                 :             : static const long double PIL = 3.1415926535897932384626L;
     182                 :             : 
     183                 :             : static long double stirf ( long double );
     184                 :             : 
     185                 :             : /* Gamma function computed by Stirling's formula.
     186                 :             :  */
     187                 :           0 : static long double stirf(long double x)
     188                 :             : {
     189                 :             : long double y, w, v;
     190                 :             : 
     191                 :           0 : w = 1.0L/x;
     192                 :             : /* For large x, use rational coefficients from the analytical expansion.  */
     193         [ #  # ]:           0 : if( x > 1024.0L )
     194                 :           0 :         w = (((((6.97281375836585777429E-5L * w
     195                 :           0 :                 + 7.84039221720066627474E-4L) * w
     196                 :           0 :                 - 2.29472093621399176955E-4L) * w
     197                 :           0 :                 - 2.68132716049382716049E-3L) * w
     198                 :           0 :                 + 3.47222222222222222222E-3L) * w
     199                 :           0 :                 + 8.33333333333333333333E-2L) * w
     200                 :             :                 + 1.0L;
     201                 :             : else
     202                 :           0 :         w = 1.0L + w * __polevll( w, STIR, 8 );
     203                 :           0 : y = expl(x);
     204         [ #  # ]:           0 : if( x > MAXSTIR )
     205                 :             :         { /* Avoid overflow in pow() */
     206                 :           0 :         v = powl( x, 0.5L * x - 0.25L );
     207                 :           0 :         y = v * (v / y);
     208                 :             :         }
     209                 :             : else
     210                 :             :         {
     211                 :           0 :         y = powl( x, x - 0.5L ) / y;
     212                 :             :         }
     213                 :           0 : y = SQTPI * y * w;
     214                 :           0 : return( y );
     215                 :             : }
     216                 :             : 
     217                 :             : long double
     218                 :           0 : tgammal(long double x)
     219                 :             : {
     220                 :             : long double p, q, z;
     221                 :             : int i;
     222                 :             : 
     223         [ #  # ]:           0 : if( isnan(x) )
     224                 :           0 :         return(NAN);
     225         [ #  # ]:           0 : if(x == INFINITY)
     226                 :           0 :         return(INFINITY);
     227         [ #  # ]:           0 : if(x == -INFINITY)
     228                 :           0 :         return(x - x);
     229         [ #  # ]:           0 : if( x == 0.0L )
     230                 :           0 :         return( 1.0L / x );
     231                 :           0 : q = fabsl(x);
     232                 :             : 
     233         [ #  # ]:           0 : if( q > 13.0L )
     234                 :             :         {
     235                 :           0 :         int sign = 1;
     236         [ #  # ]:           0 :         if( q > MAXGAML )
     237                 :           0 :                 goto goverf;
     238         [ #  # ]:           0 :         if( x < 0.0L )
     239                 :             :                 {
     240                 :           0 :                 p = floorl(q);
     241         [ #  # ]:           0 :                 if( p == q )
     242                 :           0 :                         return (x - x) / (x - x);
     243                 :           0 :                 i = p;
     244         [ #  # ]:           0 :                 if( (i & 1) == 0 )
     245                 :           0 :                         sign = -1;
     246                 :           0 :                 z = q - p;
     247         [ #  # ]:           0 :                 if( z > 0.5L )
     248                 :             :                         {
     249                 :           0 :                         p += 1.0L;
     250                 :           0 :                         z = q - p;
     251                 :             :                         }
     252                 :           0 :                 z = q * sinl( PIL * z );
     253                 :           0 :                 z = fabsl(z) * stirf(q);
     254         [ #  # ]:           0 :                 if( z <= PIL/LDBL_MAX )
     255                 :             :                         {
     256                 :           0 : goverf:
     257                 :           0 :                         return( sign * INFINITY);
     258                 :             :                         }
     259                 :           0 :                 z = PIL/z;
     260                 :             :                 }
     261                 :             :         else
     262                 :             :                 {
     263                 :           0 :                 z = stirf(x);
     264                 :             :                 }
     265                 :           0 :         return( sign * z );
     266                 :             :         }
     267                 :             : 
     268                 :           0 : z = 1.0L;
     269         [ #  # ]:           0 : while( x >= 3.0L )
     270                 :             :         {
     271                 :           0 :         x -= 1.0L;
     272                 :           0 :         z *= x;
     273                 :             :         }
     274                 :             : 
     275         [ #  # ]:           0 : while( x < -0.03125L )
     276                 :             :         {
     277                 :           0 :         z /= x;
     278                 :           0 :         x += 1.0L;
     279                 :             :         }
     280                 :             : 
     281         [ #  # ]:           0 : if( x <= 0.03125L )
     282                 :           0 :         goto small;
     283                 :             : 
     284         [ #  # ]:           0 : while( x < 2.0L )
     285                 :             :         {
     286                 :           0 :         z /= x;
     287                 :           0 :         x += 1.0L;
     288                 :             :         }
     289                 :             : 
     290         [ #  # ]:           0 : if( x == 2.0L )
     291                 :           0 :         return(z);
     292                 :             : 
     293                 :           0 : x -= 2.0L;
     294                 :           0 : p = __polevll( x, P, 7 );
     295                 :           0 : q = __polevll( x, Q, 8 );
     296                 :           0 : z = z * p / q;
     297                 :           0 : return z;
     298                 :             : 
     299                 :           0 : small:
     300         [ #  # ]:           0 : if( x == 0.0L )
     301                 :           0 :         return (x - x) / (x - x);
     302                 :             : else
     303                 :             :         {
     304         [ #  # ]:           0 :         if( x < 0.0L )
     305                 :             :                 {
     306                 :           0 :                 x = -x;
     307                 :           0 :                 q = z / (x * __polevll( x, SN, 8 ));
     308                 :             :                 }
     309                 :             :         else
     310                 :           0 :                 q = z / (x * __polevll( x, S, 8 ));
     311                 :             :         }
     312                 :           0 : return q;
     313                 :             : }
        

Generated by: LCOV version 2.0-115.g950771e