statistics.f

     1  ! @section Synopsis
     2  !
     3  ! Statistical functions for VIF.
     4  !
     5  ! @author J. Marcel van der Veer
     6  !
     7  ! @section copyright
     8  !
     9  ! This file is part of VIF - vintage fortran compiler.
    10  ! Copyright 2020-2025 J. Marcel van der Veer <algol68g@xs4all.nl>.
    11  !
    12  ! @section license
    13  !
    14  ! This program is free software; you can redistribute it and/or modify it 
    15  ! under the terms of the gnu general public license as published by the 
    16  ! free software foundation; either version 3 of the license, or 
    17  ! (at your option) any later version.
    18  !
    19  ! This program is distributed in the hope that it will be useful, but 
    20  ! without any warranty; without even the implied warranty of merchantability 
    21  ! or fitness for a particular purpose. See the GNU general public license for 
    22  ! more details. You should have received a copy of the GNU general public 
    23  ! license along with this program. If not, see <http://www.gnu.org/licenses/>.
    24  !
    25  
    26        REAL*8 FUNCTION dlnorm (x, upper)
    27  !
    28  ! DLNORM computes the cumulative density of the standard normal distribution.
    29  !
    30  ! Modified:
    31  !
    32  !   28 March 1999
    33  !
    34  ! Author:
    35  !
    36  !   David Hill
    37  !   Modifications by John Burkardt
    38  !
    39  ! Reference:
    40  !
    41  !   David Hill,
    42  !   Algorithm AS 66:
    43  !   The Normal Integral,
    44  !   Applied Statistics,
    45  !   Volume 22, Number 3, 1973, pages 424-427.
    46  !
    47  ! Parameters:
    48  !
    49  !   Input, real*8 X, is one endpoint of the semi-infinite interval
    50  !   over which the integration takes place.
    51  !
    52  !   Input, logical UPPER, determines whether the upper or lower
    53  !   interval is to be integrated:
    54  !   .TRUE.  => integrate from X to + Infinity;
    55  !   .FALSE. => integrate from - Infinity to X.
    56  !
    57  !   Output, real*8 ALNORM, the integral of the standard normal
    58  !   distribution over the desired interval.
    59  !
    60        IMPLICIT none
    61  
    62        REAL*8 a1
    63        PARAMETER (a1 = 5.75885480458d+00)
    64        REAL*8 a2
    65        PARAMETER (a2 = 2.62433121679d+00)
    66        REAL*8 a3
    67        PARAMETER (a3 = 5.92885724438d+00)
    68        REAL*8 b1
    69        PARAMETER (b1 = -29.8213557807d+00)
    70        REAL*8 b2
    71        PARAMETER (b2 = 48.6959930692d+00)
    72        REAL*8 c1
    73        PARAMETER (c1 = -0.000000038052d+00)
    74        REAL*8 c2
    75        PARAMETER (c2 = 0.000398064794d+00)
    76        REAL*8 c3
    77        PARAMETER (c3 = -0.151679116635d+00)
    78        REAL*8 c4
    79        PARAMETER (c4 = 4.8385912808d+00)
    80        REAL*8 c5
    81        PARAMETER (c5 = 0.742380924027d+00)
    82        REAL*8 c6
    83        PARAMETER (c6 = 3.99019417011d+00)
    84        REAL*8 con
    85        PARAMETER (con = 1.28d+00)
    86        REAL*8 d1
    87        PARAMETER (d1 = 1.00000615302d+00)
    88        REAL*8 d2
    89        PARAMETER (d2 = 1.98615381364d+00)
    90        REAL*8 d3
    91        PARAMETER (d3 = 5.29330324926d+00)
    92        REAL*8 d4
    93        PARAMETER (d4 = -15.1508972451d+00)
    94        REAL*8 d5
    95        PARAMETER (d5 = 30.789933034d+00)
    96        REAL*8 ltone
    97        PARAMETER (ltone = 7.0d+00)
    98        REAL*8 p
    99        PARAMETER (p = 0.398942280444d+00)
   100        REAL*8 q
   101        PARAMETER (q = 0.39990348504d+00)
   102        REAL*8 r
   103        PARAMETER (r = 0.398942280385d+00)
   104        LOGICAL up
   105        LOGICAL upper
   106        REAL*8 utzero
   107        PARAMETER (utzero = 18.66d+00)
   108        REAL*8 x
   109        REAL*8 y
   110        REAL*8 z
   111  
   112        up = upper
   113        z = x
   114  
   115        IF (z .lt. 0.0d+00) THEN
   116          up = .not. up
   117          z = - z
   118        END IF
   119  
   120        IF (ltone .lt. z .and. 
   121       &  ((.not. up) .or. utzero .lt. z)) THEN
   122  
   123          IF (up) THEN
   124            dlnorm = 0.0d+00
   125          ELSE
   126            dlnorm = 1.0d+00
   127          END IF
   128  
   129          RETURN
   130  
   131        END IF
   132  
   133        y = 0.5d+00 * z * z
   134  
   135        IF (z .le. con) THEN
   136  
   137          dlnorm = 0.5d+00 - z * (p - q * y
   138       &    / (y + a1 + b1 
   139       &    / (y + a2 + b2 
   140       &    / (y + a3))))
   141  
   142        ELSE
   143  
   144          dlnorm = r * dexp (- y)
   145       &    / (z + c1 + d1
   146       &    / (z + c2 + d2
   147       &    / (z + c3 + d3
   148       &    / (z + c4 + d4
   149       &    / (z + c5 + d5
   150       &    / (z + c6))))))
   151  
   152        END IF
   153  
   154        IF (.not. up) THEN
   155          dlnorm = 1.0d+00 - dlnorm
   156        END IF
   157  
   158        RETURN
   159        END
   160  
   161        REAL*8 FUNCTION prncst (st, idf, d, ifault)
   162  
   163  !
   164  ! PRNCST computes the lower tail of noncentral T distribution.
   165  !
   166  ! Modified:
   167  !
   168  !   06 January 2008
   169  !
   170  ! Author:
   171  !
   172  !   BE Cooper
   173  !   Modifications by John Burkardt
   174  !
   175  ! Reference:
   176  !
   177  !   BE Cooper,
   178  !   Algorithm AS 5: 
   179  !   The Integral of the Non-Central T-Distribution,
   180  !   Applied Statistics,
   181  !   Volume 17, Number 2, 1968, page 193.
   182  !
   183  ! Parameters:
   184  !
   185  !   Input, real*8 ST, the argument.
   186  !
   187  !   Input, integer IDF, the number of degrees of freedom.
   188  !
   189  !   Input, real*8 D, the noncentrality parameter.
   190  !
   191  !   Output, integer IFAULT, error flag.
   192  !   0, no error occurred.
   193  !   nonzero, an error occurred.
   194  !
   195  !   Output, real*8 PRNCST, the value of the lower tail of
   196  !   the noncentral T distribution.
   197  !
   198  ! Local Parameters:
   199  !
   200  !   Local, real*8 G1, 1.0 / sqrt(2.0 * pi)
   201  !
   202  !   Local, real*8 G2, 1.0 / (2.0 * pi)
   203  !
   204  !   Local, real*8 G3, sqrt(2.0 * pi)
   205  !
   206        IMPLICIT none
   207  
   208        REAL*8 a
   209        REAL*8 ak
   210        REAL*8 dlnorm
   211        REAL*8 b
   212        REAL*8 d
   213        REAL*8 da
   214        REAL*8 drb
   215        REAL*8 emin
   216        PARAMETER (emin = 12.5d+00)
   217        REAL*8 f
   218        REAL*8 fk
   219        REAL*8 fkm1
   220        REAL*8 fmkm1
   221        REAL*8 fmkm2
   222        REAL*8 g1
   223        PARAMETER (g1 = 0.3989422804d+00)
   224        REAL*8 g2
   225        PARAMETER (g2 = 0.1591549431d+00)
   226        REAL*8 g3
   227        PARAMETER (g3 = 2.5066282746d+00)
   228        INTEGER idf
   229        INTEGER ifault
   230        INTEGER ioe
   231        INTEGER k
   232        REAL*8 rb
   233        REAL*8 st
   234        REAL*8 sum
   235        REAL*8 tfn
   236  
   237        f = dble (idf)
   238  !
   239  ! For very large IDF, use the normal approximation.
   240  !
   241        IF (100 .lt. idf) THEN
   242  
   243          ifault = 1
   244  
   245          a = dsqrt (0.5d+00 * f) 
   246       &  * dexp (dlngam (0.5d+00 * (f - 1.0d+00))
   247       &  - dlngam (0.5d+00 * f)) * d
   248  
   249          prncst = dlnorm ((st - a) / dsqrt (f * (1.0d+00 + d * d)
   250       &  / (f - 2.0d+00) - a * a), .false.)
   251  
   252          RETURN
   253        END IF
   254  
   255        ifault = 0
   256        ioe = mod (idf, 2)
   257        a = st / dsqrt (f)
   258        b = f / (f + st * st)
   259        rb = dsqrt (b)
   260        da = d * a
   261        drb = d * rb
   262  
   263        IF (idf .eq. 1) THEN
   264          prncst = dlnorm (drb, .true.) + 2.0d+00 * tfn (drb, a)
   265          RETURN
   266        END IF
   267  
   268        sum = 0.0d+00
   269  
   270        IF (dabs (drb) .lt. emin) THEN
   271          fmkm2 = a * rb * dexp (- 0.5d+00 * drb * drb)
   272       &  * dlnorm (a * drb, .false.) * g1
   273        ELSE
   274          fmkm2 = 0.0d+00
   275        END IF
   276  
   277        fmkm1 = b * da * fmkm2
   278  
   279        IF (dabs (d)  .lt. emin) THEN
   280          fmkm1 = fmkm1 + b * a * g2 * dexp (- 0.5d+00 * d * d)
   281        END IF
   282  
   283        IF (ioe .eq. 0) THEN
   284          sum = fmkm2
   285        ELSE
   286          sum = fmkm1
   287        END IF
   288  
   289        ak = 1.0d+00
   290        fk = 2.0d+00
   291  
   292        DO k = 2, idf - 2, 2
   293  
   294          fkm1 = fk - 1.0d+00
   295          fmkm2 = b * (da * ak * fmkm1 + fmkm2) * fkm1 / fk
   296          ak = 1.0d+00 / (ak * fkm1)
   297          fmkm1 = b * (da * ak * fmkm2 + fmkm1) * fk / (fk + 1.0d+00)
   298  
   299          IF (ioe .eq. 0) THEN
   300            sum = sum + fmkm2
   301          ELSE
   302            sum = sum + fmkm1
   303          END IF
   304  
   305          ak = 1.0d+00 / (ak * fk)
   306          fk = fk + 2.0d+00
   307  
   308        END DO
   309  
   310        IF (ioe .eq. 0) THEN
   311          prncst = dlnorm (d, .true.) + sum * g3
   312        ELSE
   313          prncst = dlnorm (drb, .true.) 
   314       &  + 2.0d+00 * (sum + tfn (drb, a))
   315        END IF
   316  
   317        RETURN
   318        END
   319  
   320        SUBROUTINE student_noncentral_cdf_values (n_data, df, lambda, 
   321       &  x, fx)
   322  
   323  !
   324  ! STUDENT_NONCENTRAL_CDF_VALUES returns values of the noncentral Student CDF.
   325  !
   326  ! Discussion:
   327  !
   328  !   In Mathematica, the function can be evaluated by:
   329  !
   330  !     Needs["Statistics`ContinuousDistributions`"]
   331  !     dist = NoncentralStudentTDistribution [ df, lambda ]
   332  !     CDF [ dist, x ]
   333  !
   334  !   Mathematica seems to have some difficulty computing this function
   335  !   to the desired number of digits.
   336  !
   337  ! Modified:
   338  !
   339  !   25 March 2007
   340  !
   341  ! Author:
   342  !
   343  !   John Burkardt
   344  !
   345  ! Reference:
   346  !
   347  !   Milton Abramowitz, Irene Stegun,
   348  !   Handbook of Mathematical Functions,
   349  !   National Bureau of Standards, 1964,
   350  !   ISBN: 0-486-61272-4,
   351  !   LC: QA47.A34.
   352  !
   353  !   Stephen Wolfram,
   354  !   The Mathematica Book,
   355  !   Fourth Edition,
   356  !   Cambridge University Press, 1999,
   357  !   ISBN: 0-521-64314-7,
   358  !   LC: QA76.95.W65.
   359  !
   360  ! Parameters:
   361  !
   362  !   Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
   363  !   first call.  On each call, the routine increments N_DATA by 1, and
   364  !   returns the corresponding data; when there is no more data, the
   365  !   output value of N_DATA will be 0 again.
   366  !
   367  !   Output, integer DF, real*8 LAMBDA, the parameters of the
   368  !   function.
   369  !
   370  !   Output, real*8 X, the argument of the function.
   371  !
   372  !   Output, real*8 FX, the value of the function.
   373  !
   374        IMPLICIT none
   375  
   376        INTEGER n_max
   377        PARAMETER (n_max = 30)
   378  
   379        INTEGER df
   380        INTEGER df_vec(n_max) 
   381        REAL*8 fx
   382        REAL*8 fx_vec(n_max) 
   383        REAL*8 lambda
   384        REAL*8 lambda_vec(n_max) 
   385        INTEGER n_data
   386        REAL*8 x
   387        REAL*8 x_vec(n_max) 
   388  
   389        SAVE df_vec
   390        SAVE fx_vec
   391        SAVE lambda_vec
   392        SAVE x_vec
   393  
   394        DATA df_vec /
   395       &   1,  2,  3, 
   396       &   1,  2,  3, 
   397       &   1,  2,  3, 
   398       &   1,  2,  3, 
   399       &   1,  2,  3, 
   400       &  15, 20, 25, 
   401       &   1,  2,  3, 
   402       &  10, 10, 10, 
   403       &  10, 10, 10, 
   404       &  10, 10, 10 /
   405        DATA fx_vec /
   406       &  0.8975836176504333d+00, 
   407       &  0.9522670169d+00, 
   408       &  0.9711655571887813d+00, 
   409       &  0.8231218864d+00, 
   410       &  0.9049021510d+00, 
   411       &  0.9363471834d+00, 
   412       &  0.7301025986d+00, 
   413       &  0.8335594263d+00, 
   414       &  0.8774010255d+00, 
   415       &  0.5248571617d+00, 
   416       &  0.6293856597d+00, 
   417       &  0.6800271741d+00, 
   418       &  0.20590131975d+00, 
   419       &  0.2112148916d+00, 
   420       &  0.2074730718d+00, 
   421       &  0.9981130072d+00, 
   422       &  0.9994873850d+00, 
   423       &  0.9998391562d+00, 
   424       &  0.168610566972d+00, 
   425       &  0.16967950985d+00, 
   426       &  0.1701041003d+00, 
   427       &  0.9247683363d+00, 
   428       &  0.7483139269d+00, 
   429       &  0.4659802096d+00, 
   430       &  0.9761872541d+00, 
   431       &  0.8979689357d+00, 
   432       &  0.7181904627d+00, 
   433       &  0.9923658945d+00, 
   434       &  0.9610341649d+00, 
   435       &  0.8688007350d+00 /
   436        DATA lambda_vec /
   437       &  0.0d+00, 
   438       &  0.0d+00, 
   439       &  0.0d+00, 
   440       &  0.5d+00, 
   441       &  0.5d+00, 
   442       &  0.5d+00, 
   443       &  1.0d+00, 
   444       &  1.0d+00, 
   445       &  1.0d+00, 
   446       &  2.0d+00, 
   447       &  2.0d+00, 
   448       &  2.0d+00, 
   449       &  4.0d+00, 
   450       &  4.0d+00, 
   451       &  4.0d+00, 
   452       &  7.0d+00, 
   453       &  7.0d+00, 
   454       &  7.0d+00, 
   455       &  1.0d+00, 
   456       &  1.0d+00, 
   457       &  1.0d+00, 
   458       &  2.0d+00, 
   459       &  3.0d+00, 
   460       &  4.0d+00, 
   461       &  2.0d+00, 
   462       &  3.0d+00, 
   463       &  4.0d+00, 
   464       &  2.0d+00, 
   465       &  3.0d+00, 
   466       &  4.0d+00 /
   467        DATA x_vec /
   468       &   3.00d+00, 
   469       &   3.00d+00, 
   470       &   3.00d+00, 
   471       &   3.00d+00, 
   472       &   3.00d+00, 
   473       &   3.00d+00, 
   474       &   3.00d+00, 
   475       &   3.00d+00, 
   476       &   3.00d+00, 
   477       &   3.00d+00, 
   478       &   3.00d+00, 
   479       &   3.00d+00, 
   480       &   3.00d+00, 
   481       &   3.00d+00, 
   482       &   3.00d+00, 
   483       &  15.00d+00, 
   484       &  15.00d+00, 
   485       &  15.00d+00, 
   486       &   0.05d+00, 
   487       &   0.05d+00, 
   488       &   0.05d+00, 
   489       &   4.00d+00, 
   490       &   4.00d+00, 
   491       &   4.00d+00, 
   492       &   5.00d+00, 
   493       &   5.00d+00, 
   494       &   5.00d+00, 
   495       &   6.00d+00, 
   496       &   6.00d+00, 
   497       &   6.00d+00 /
   498  
   499        IF (n_data .lt. 0) THEN
   500          n_data = 0
   501        END IF
   502  
   503        n_data = n_data + 1
   504  
   505        IF (n_max .lt. n_data) THEN
   506          n_data = 0
   507          df = 0
   508          lambda = 0.0d+00
   509          x = 0.0d+00
   510          fx = 0.0d+00
   511        ELSE
   512          df = df_vec(n_data)
   513          lambda = lambda_vec(n_data)
   514          x = x_vec(n_data)
   515          fx = fx_vec(n_data)
   516        END IF
   517  
   518        RETURN
   519        END
   520  
   521        REAL*8 FUNCTION tfn (x, fx)
   522  !
   523  ! TFN calculates the T-function of Owen.
   524  !
   525  ! Modified:
   526  !
   527  !   06 January 2008
   528  !
   529  ! Author:
   530  !
   531  !   JC Young, Christoph Minder
   532  !   Modifications by John Burkardt
   533  !
   534  ! Reference:
   535  !
   536  !   MA Porter, DJ Winstanley,
   537  !   Remark AS R30:
   538  !   A Remark on Algorithm AS76:
   539  !   An Integral Useful in Calculating Noncentral T and Bivariate
   540  !   Normal Probabilities,
   541  !   Applied Statistics,
   542  !   Volume 28, Number 1, 1979, page 113.
   543  !
   544  !   JC Young, Christoph Minder,
   545  !   Algorithm AS 76: 
   546  !   An Algorithm Useful in Calculating Non-Central T and 
   547  !   Bivariate Normal Distributions,
   548  !   Applied Statistics,
   549  !   Volume 23, Number 3, 1974, pages 455-457.
   550  !
   551  ! Parameters:
   552  !
   553  !   Input, real*8 X, FX, the parameters of the function.
   554  !
   555  !   Output, real*8 TFN, the value of the T-function.
   556  !
   557        IMPLICIT none
   558  
   559        INTEGER ng
   560        PARAMETER (ng = 5)
   561  
   562        REAL*8 fx
   563        REAL*8 fxs
   564        INTEGER i
   565        REAL*8 r(ng)
   566        REAL*8 r1
   567        REAL*8 r2
   568        REAL*8 rt
   569        REAL*8 tp
   570        PARAMETER (tp = 0.159155d+00)
   571        REAL*8 tv1
   572        PARAMETER (tv1 = 1.0d-35)
   573        REAL*8 tv2
   574        PARAMETER (tv2 = 15.0d+00)
   575        REAL*8 tv3
   576        PARAMETER (tv3 = 15.0d+00)
   577        REAL*8 tv4
   578        PARAMETER (tv4 = 1.0d-05)
   579        REAL*8 u(ng)
   580        REAL*8 x
   581        REAL*8 x1
   582        REAL*8 x2
   583        REAL*8 xs
   584  
   585        DATA u / 
   586       &  0.0744372d+00, 
   587       &  0.2166977d+00, 
   588       &  0.3397048d+00, 
   589       &  0.4325317d+00, 
   590       &  0.4869533d+00 /
   591  
   592        DATA r /
   593       &  0.1477621d+00, 
   594       &  0.1346334d+00, 
   595       &  0.1095432d+00, 
   596       &  0.0747257d+00, 
   597       &  0.0333357d+00 /
   598  !
   599  ! Test for X near zero.
   600  !
   601        IF (dabs (x) .lt. tv1) THEN
   602          tfn = tp * atan (fx)
   603          RETURN
   604        END IF
   605  !
   606  ! Test for large values of abs(X).
   607  !
   608        IF (tv2 .lt. dabs (x)) THEN
   609          tfn = 0.0d+00
   610          RETURN
   611        END IF
   612  !
   613  ! Test for FX near zero.
   614  !
   615        IF (dabs (fx) .lt. tv1) THEN
   616          tfn = 0.0d+00
   617          RETURN
   618        END IF
   619  !
   620  ! Test whether abs (FX) is so large that it must be truncated.
   621  !
   622        xs = - 0.5d+00 * x * x
   623        x2 = fx
   624        fxs = fx * fx
   625  
   626        IF (dlog (1.0d+00 + fxs) - xs * fxs .lt. tv3) THEN
   627          GO TO 2 
   628        END IF
   629  !
   630  ! Computation of truncation point by Newton iteration.
   631  !
   632        x1 = 0.5d+00 * fx
   633        fxs = 0.25d+00 * fxs
   634  
   635      1 CONTINUE
   636  
   637          rt = fxs + 1.0d+00
   638  
   639          x2 = x1 + (xs * fxs + tv3 - dlog (rt)) 
   640       &  / (2.0d+00 * x1 * (1.0d+00 / rt - xs))
   641  
   642          fxs = x2 * x2
   643  
   644          IF (dabs (x2 - x1) .lt. tv4) THEN
   645            GO TO 2
   646          END IF
   647  
   648          x1 = x2
   649  
   650        GO TO 1
   651  !
   652  ! Gaussian quadrature.
   653  !
   654      2 CONTINUE
   655  
   656        rt = 0.0d+00
   657  
   658        DO i = 1, ng
   659  
   660          r1 = 1.0d+00 + fxs * (0.5d+00 + u(i))**2
   661          r2 = 1.0d+00 + fxs * (0.5d+00 - u(i))**2
   662  
   663          rt = rt + r(i) * (dexp (xs * r1) / r1 
   664       &  + dexp (xs * r2) / r2)
   665  
   666        END DO
   667  
   668        tfn = rt * x2 * tp
   669  
   670        RETURN
   671        END


© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)