LCOV - code coverage report
Current view: top level - Modules - _statisticsmodule.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 63 70 90.0 %
Date: 2022-07-20 13:12:14 Functions: 2 2 100.0 %
Branches: 15 22 68.2 %

           Branch data     Line data    Source code
       1                 :            : /* statistics accelerator C extension: _statistics module. */
       2                 :            : 
       3                 :            : #include "Python.h"
       4                 :            : #include "clinic/_statisticsmodule.c.h"
       5                 :            : 
       6                 :            : /*[clinic input]
       7                 :            : module _statistics
       8                 :            : 
       9                 :            : [clinic start generated code]*/
      10                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=864a6f59b76123b2]*/
      11                 :            : 
      12                 :            : /*
      13                 :            :  * There is no closed-form solution to the inverse CDF for the normal
      14                 :            :  * distribution, so we use a rational approximation instead:
      15                 :            :  * Wichura, M.J. (1988). "Algorithm AS241: The Percentage Points of the
      16                 :            :  * Normal Distribution".  Applied Statistics. Blackwell Publishing. 37
      17                 :            :  * (3): 477–484. doi:10.2307/2347330. JSTOR 2347330.
      18                 :            :  */
      19                 :            : 
      20                 :            : /*[clinic input]
      21                 :            : _statistics._normal_dist_inv_cdf -> double
      22                 :            :    p: double
      23                 :            :    mu: double
      24                 :            :    sigma: double
      25                 :            :    /
      26                 :            : [clinic start generated code]*/
      27                 :            : 
      28                 :            : static double
      29                 :    1048944 : _statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu,
      30                 :            :                                       double sigma)
      31                 :            : /*[clinic end generated code: output=02fd19ddaab36602 input=24715a74be15296a]*/
      32                 :            : {
      33                 :            :     double q, num, den, r, x;
      34   [ +  -  +  -  :    1048944 :     if (p <= 0.0 || p >= 1.0 || sigma <= 0.0) {
                   -  + ]
      35                 :          0 :         goto error;
      36                 :            :     }
      37                 :            : 
      38                 :    1048944 :     q = p - 0.5;
      39         [ +  + ]:    1048944 :     if(fabs(q) <= 0.425) {
      40                 :     891352 :         r = 0.180625 - q * q;
      41                 :            :         // Hash sum-55.8831928806149014439
      42                 :     891352 :         num = (((((((2.5090809287301226727e+3 * r +
      43                 :     891352 :                      3.3430575583588128105e+4) * r +
      44                 :     891352 :                      6.7265770927008700853e+4) * r +
      45                 :     891352 :                      4.5921953931549871457e+4) * r +
      46                 :     891352 :                      1.3731693765509461125e+4) * r +
      47                 :     891352 :                      1.9715909503065514427e+3) * r +
      48                 :     891352 :                      1.3314166789178437745e+2) * r +
      49                 :            :                      3.3871328727963666080e+0) * q;
      50                 :     891352 :         den = (((((((5.2264952788528545610e+3 * r +
      51                 :     891352 :                      2.8729085735721942674e+4) * r +
      52                 :     891352 :                      3.9307895800092710610e+4) * r +
      53                 :     891352 :                      2.1213794301586595867e+4) * r +
      54                 :     891352 :                      5.3941960214247511077e+3) * r +
      55                 :     891352 :                      6.8718700749205790830e+2) * r +
      56                 :     891352 :                      4.2313330701600911252e+1) * r +
      57                 :            :                      1.0);
      58         [ -  + ]:     891352 :         if (den == 0.0) {
      59                 :          0 :             goto error;
      60                 :            :         }
      61                 :     891352 :         x = num / den;
      62                 :     891352 :         return mu + (x * sigma);
      63                 :            :     }
      64         [ +  + ]:     157592 :     r = (q <= 0.0) ? p : (1.0 - p);
      65   [ +  -  -  + ]:     157592 :     if (r <= 0.0 || r >= 1.0) {
      66                 :          0 :         goto error;
      67                 :            :     }
      68                 :     157592 :     r = sqrt(-log(r));
      69         [ +  + ]:     157592 :     if (r <= 5.0) {
      70                 :     157562 :         r = r - 1.6;
      71                 :            :         // Hash sum-49.33206503301610289036
      72                 :     157562 :         num = (((((((7.74545014278341407640e-4 * r +
      73                 :     157562 :                      2.27238449892691845833e-2) * r +
      74                 :     157562 :                      2.41780725177450611770e-1) * r +
      75                 :     157562 :                      1.27045825245236838258e+0) * r +
      76                 :     157562 :                      3.64784832476320460504e+0) * r +
      77                 :     157562 :                      5.76949722146069140550e+0) * r +
      78                 :     157562 :                      4.63033784615654529590e+0) * r +
      79                 :            :                      1.42343711074968357734e+0);
      80                 :     157562 :         den = (((((((1.05075007164441684324e-9 * r +
      81                 :     157562 :                      5.47593808499534494600e-4) * r +
      82                 :     157562 :                      1.51986665636164571966e-2) * r +
      83                 :     157562 :                      1.48103976427480074590e-1) * r +
      84                 :     157562 :                      6.89767334985100004550e-1) * r +
      85                 :     157562 :                      1.67638483018380384940e+0) * r +
      86                 :     157562 :                      2.05319162663775882187e+0) * r +
      87                 :            :                      1.0);
      88                 :            :     } else {
      89                 :         30 :         r -= 5.0;
      90                 :            :         // Hash sum-47.52583317549289671629
      91                 :         30 :         num = (((((((2.01033439929228813265e-7 * r +
      92                 :         30 :                      2.71155556874348757815e-5) * r +
      93                 :         30 :                      1.24266094738807843860e-3) * r +
      94                 :         30 :                      2.65321895265761230930e-2) * r +
      95                 :         30 :                      2.96560571828504891230e-1) * r +
      96                 :         30 :                      1.78482653991729133580e+0) * r +
      97                 :         30 :                      5.46378491116411436990e+0) * r +
      98                 :            :                      6.65790464350110377720e+0);
      99                 :         30 :         den = (((((((2.04426310338993978564e-15 * r +
     100                 :         30 :                      1.42151175831644588870e-7) * r +
     101                 :         30 :                      1.84631831751005468180e-5) * r +
     102                 :         30 :                      7.86869131145613259100e-4) * r +
     103                 :         30 :                      1.48753612908506148525e-2) * r +
     104                 :         30 :                      1.36929880922735805310e-1) * r +
     105                 :         30 :                      5.99832206555887937690e-1) * r +
     106                 :            :                      1.0);
     107                 :            :     }
     108         [ -  + ]:     157592 :     if (den == 0.0) {
     109                 :          0 :         goto error;
     110                 :            :     }
     111                 :     157592 :     x = num / den;
     112         [ +  + ]:     157592 :     if (q < 0.0) {
     113                 :      78796 :         x = -x;
     114                 :            :     }
     115                 :     157592 :     return mu + (x * sigma);
     116                 :            : 
     117                 :          0 :   error:
     118                 :          0 :     PyErr_SetString(PyExc_ValueError, "inv_cdf undefined for these parameters");
     119                 :          0 :     return -1.0;
     120                 :            : }
     121                 :            : 
     122                 :            : 
     123                 :            : static PyMethodDef statistics_methods[] = {
     124                 :            :     _STATISTICS__NORMAL_DIST_INV_CDF_METHODDEF
     125                 :            :     {NULL, NULL, 0, NULL}
     126                 :            : };
     127                 :            : 
     128                 :            : PyDoc_STRVAR(statistics_doc,
     129                 :            : "Accelerators for the statistics module.\n");
     130                 :            : 
     131                 :            : static struct PyModuleDef_Slot _statisticsmodule_slots[] = {
     132                 :            :     {0, NULL}
     133                 :            : };
     134                 :            : 
     135                 :            : static struct PyModuleDef statisticsmodule = {
     136                 :            :         PyModuleDef_HEAD_INIT,
     137                 :            :         "_statistics",
     138                 :            :         statistics_doc,
     139                 :            :         0,
     140                 :            :         statistics_methods,
     141                 :            :         _statisticsmodule_slots,
     142                 :            :         NULL,
     143                 :            :         NULL,
     144                 :            :         NULL
     145                 :            : };
     146                 :            : 
     147                 :            : PyMODINIT_FUNC
     148                 :          6 : PyInit__statistics(void)
     149                 :            : {
     150                 :          6 :     return PyModuleDef_Init(&statisticsmodule);
     151                 :            : }

Generated by: LCOV version 1.14