function bivprb ( h, k, r ) !*****************************************************************************80 ! !! BIVPRB computes a bivariate normal CDF for correlated X and Y. ! ! Discussion: ! ! This routine computes P( H < X, K < Y ) for X and Y standard normal ! variables with correlation R. ! ! Modified: ! ! 02 February 2008 ! ! Author: ! ! Original version by Mike Patefield, David Tandy. ! FORTRAN90 version by John Burkardt. ! ! Reference: ! ! Mike Patefield, David Tandy, ! Fast and Accurate Calculation of Owen's T Function, ! Journal of Statistical Software, ! Volume 5, Number 5, 2000, pages 1-25. ! ! Parameters: ! ! Input, real ( kind = 8 ) H, K, the lower limits for X and Y. ! 0 <= H, 0 <= K. ! ! Input, real ( kind = 8 ) R, the correlation between X and Y. ! ! Output, real ( kind = 8 ) BIVPRB, the requested probability. ! implicit none real ( kind = 8 ) bivprb real ( kind = 8 ) h integer ( kind = 4 ) ifail real ( kind = 8 ) k real ( kind = 8 ) q real ( kind = 8 ) r real ( kind = 8 ) ri real ( kind = 8 ) rr real ( kind = 8 ), parameter :: rroot2 = 0.70710678118654752440D+00 real ( kind = 8 ), parameter :: rtwopi = 0.15915494309189533577D+00 real ( kind = 8 ) znorm2 if ( r == 0.0D+00 ) then bivprb = znorm2 ( h ) * znorm2 ( k ) else rr = 1.0D+00 - r * r if ( 0.0D+00 < rr ) then ri = 1.0D+00 / sqrt ( rr ) if ( 0.0D+00 < h .and. 0.0D+00 < k ) then bivprb = q ( h, ( k / h - r ) * ri ) & + q ( k, ( h / k - r ) * ri ) else if ( 0.0D+00 < h ) then bivprb = q ( h, - r * ri ) else if ( 0.0D+00 < k ) then bivprb = q ( k, - r * ri ) else bivprb = 0.25D+00 + rtwopi * asin ( r ) end if else if ( 1.0D+00 <= r ) then if ( k <= h ) then bivprb = znorm2 ( h ) else bivprb = znorm2 ( k ) end if else bivprb = 0.0D+00 end if end if return end subroutine normp ( z, p, q, pdf ) !*****************************************************************************80 ! !! NORMP computes the cumulative density of the standard normal distribution. ! ! Discussion: ! ! This is algorithm 5666 from Hart, et al. ! ! Modified: ! ! 02 February 2008 ! ! Author: ! ! Alan Miller ! FORTRAN90 version by John Burkardt ! ! Reference: ! ! John Hart, Ward Cheney, Charles Lawson, Hans Maehly, ! Charles Mesztenyi, John Rice, Henry Thacher, ! Christoph Witzgall, ! Computer Approximations, ! Wiley, 1968, ! LC: QA297.C64. ! ! Parameters: ! ! Input, real ( kind = 8 ) Z, divides the real line into two semi-infinite ! intervals, over each of which the standard normal distribution ! is to be integrated. ! ! Output, real ( kind = 8 ) P, Q, the integrals of the standard normal ! distribution over the intervals ( - Infinity, Z] and ! [Z, + Infinity ), respectively. ! ! Output, real ( kind = 8 ) PDF, the value of the standard normal ! distribution at Z. ! implicit none real ( kind = 8 ), parameter :: cutoff = 7.071D+00 real ( kind = 8 ) expntl real ( kind = 8 ) p real ( kind = 8 ), parameter :: p0 = 220.2068679123761D+00 real ( kind = 8 ), parameter :: p1 = 221.2135961699311D+00 real ( kind = 8 ), parameter :: p2 = 112.0792914978709D+00 real ( kind = 8 ), parameter :: p3 = 33.91286607838300D+00 real ( kind = 8 ), parameter :: p4 = 6.373962203531650D+00 real ( kind = 8 ), parameter :: p5 = 0.7003830644436881D+00 real ( kind = 8 ), parameter :: p6 = 0.03526249659989109D+00 real ( kind = 8 ) pdf real ( kind = 8 ) q real ( kind = 8 ), parameter :: q0 = 440.4137358247522D+00 real ( kind = 8 ), parameter :: q1 = 793.8265125199484D+00 real ( kind = 8 ), parameter :: q2 = 637.3336333788311D+00 real ( kind = 8 ), parameter :: q3 = 296.5642487796737D+00 real ( kind = 8 ), parameter :: q4 = 86.78073220294608D+00 real ( kind = 8 ), parameter :: q5 = 16.06417757920695D+00 real ( kind = 8 ), parameter :: q6 = 1.755667163182642D+00 real ( kind = 8 ), parameter :: q7 = 0.08838834764831844D+00 real ( kind = 8 ), parameter :: root2pi = 2.506628274631001D+00 real ( kind = 8 ) z real ( kind = 8 ) zabs zabs = abs ( z ) ! ! 37 < |Z|. ! if ( 37.0D+00 < zabs ) then pdf = 0.0D+00 p = 0.0D+00 ! ! |Z| <= 37. ! else expntl = exp ( - 0.5D+00 * zabs * zabs ) pdf = expntl / root2pi ! ! |Z| < CUTOFF = 10 / sqrt(2). ! if ( zabs < cutoff ) then p = expntl * (((((( & p6 * zabs & + p5 ) * zabs & + p4 ) * zabs & + p3 ) * zabs & + p2 ) * zabs & + p1 ) * zabs & + p0 ) / ((((((( & q7 * zabs & + q6 ) * zabs & + q5 ) * zabs & + q4 ) * zabs & + q3 ) * zabs & + q2 ) * zabs & + q1 ) * zabs & + q0 ) ! ! CUTOF <= |Z|. ! else p = pdf / ( & zabs + 1.0D+00 / ( & zabs + 2.0D+00 / ( & zabs + 3.0D+00 / ( & zabs + 4.0D+00 / ( & zabs + 0.65D+00 ))))) end if end if if ( z < 0.0D+00 ) then q = 1.0D+00 - p else q = p p = 1.0D+00 - q end if return end subroutine owen_values ( n_data, h, a, t ) !*****************************************************************************80 ! !! OWEN_VALUES returns some values of Owen's T function. ! ! Discussion: ! ! Owen's T function is useful for computation of the bivariate normal ! distribution and the distribution of a skewed normal distribution. ! ! Although it was originally formulated in terms of the bivariate ! normal function, the function can be defined more directly as ! ! T(H,A) = 1 / ( 2 * pi ) * ! Integral ( 0 <= X <= A ) e^(-H^2*(1+X^2)/2) / (1+X^2) dX ! ! In Mathematica, the function can be evaluated by: ! ! fx = 1/(2*Pi) * Integrate [ E^(-h^2*(1+x^2)/2)/(1+x^2), {x,0,a} ] ! ! Modified: ! ! 10 December 2004 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Stephen Wolfram, ! The Mathematica Book, ! Fourth Edition, ! Cambridge University Press, 1999, ! ISBN: 0-521-64314-7, ! LC: QA76.95.W65. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) N_DATA. The user sets N_DATA to 0 ! before the first call. On each call, the routine increments N_DATA by 1, ! and returns the corresponding data; when there is no more data, the ! output value of N_DATA will be 0 again. ! ! Output, real ( kind = 8 ) H, a parameter. ! ! Output, real ( kind = 8 ) A, the upper limit of the integral. ! ! Output, real ( kind = 8 ) T, the value of the function. ! implicit none integer ( kind = 4 ), parameter :: n_max = 22 real ( kind = 8 ) a real ( kind = 8 ), save, dimension ( n_max ) :: a_vec = (/ & 0.5000000000000000D+00, & 0.1000000000000000D+01, & 0.2000000000000000D+01, & 0.3000000000000000D+01, & 0.5000000000000000D+00, & 0.1000000000000000D+01, & 0.2000000000000000D+01, & 0.3000000000000000D+01, & 0.5000000000000000D+00, & 0.1000000000000000D+01, & 0.2000000000000000D+01, & 0.3000000000000000D+01, & 0.5000000000000000D+00, & 0.1000000000000000D+01, & 0.2000000000000000D+01, & 0.3000000000000000D+01, & 0.5000000000000000D+00, & 0.1000000000000000D+01, & 0.2000000000000000D+01, & 0.3000000000000000D+01, & 0.1000000000000000D+02, & 0.1000000000000000D+03 /) real ( kind = 8 ) h real ( kind = 8 ), save, dimension ( n_max ) :: h_vec = (/ & 0.1000000000000000D+01, & 0.1000000000000000D+01, & 0.1000000000000000D+01, & 0.1000000000000000D+01, & 0.5000000000000000D+00, & 0.5000000000000000D+00, & 0.5000000000000000D+00, & 0.5000000000000000D+00, & 0.2500000000000000D+00, & 0.2500000000000000D+00, & 0.2500000000000000D+00, & 0.2500000000000000D+00, & 0.1250000000000000D+00, & 0.1250000000000000D+00, & 0.1250000000000000D+00, & 0.1250000000000000D+00, & 0.7812500000000000D-02, & 0.7812500000000000D-02, & 0.7812500000000000D-02, & 0.7812500000000000D-02, & 0.7812500000000000D-02, & 0.7812500000000000D-02 /) integer ( kind = 4 ) n_data real ( kind = 8 ) t real ( kind = 8 ), save, dimension ( n_max ) :: t_vec = (/ & 0.4306469112078537D-01, & 0.6674188216570097D-01, & 0.7846818699308410D-01, & 0.7929950474887259D-01, & 0.6448860284750376D-01, & 0.1066710629614485D+00, & 0.1415806036539784D+00, & 0.1510840430760184D+00, & 0.7134663382271778D-01, & 0.1201285306350883D+00, & 0.1666128410939293D+00, & 0.1847501847929859D+00, & 0.7317273327500385D-01, & 0.1237630544953746D+00, & 0.1737438887583106D+00, & 0.1951190307092811D+00, & 0.7378938035365546D-01, & 0.1249951430754052D+00, & 0.1761984774738108D+00, & 0.1987772386442824D+00, & 0.2340886964802671D+00, & 0.2479460829231492D+00 /) if ( n_data < 0 ) then n_data = 0 end if n_data = n_data + 1 if ( n_max < n_data ) then n_data = 0 h = 0.0D+00 a = 0.0D+00 t = 0.0D+00 else h = h_vec(n_data) a = a_vec(n_data) t = t_vec(n_data) end if return end function q ( h, ah ) !*****************************************************************************80 ! !! Q computes (1/2) * p(H