*! version 1.0.0 07jul2005 program prho version 9 syntax varlist(min=2 max=2) [if] [in] marksample touse spearman `varlist' if `touse' mata: my_prho(`r(N)', `=abs(r(rho))') di as txt " New test = " as res %12.4f 2*(1-r(p2)) end mata: version 9 mata set matastrict on void my_prho(real scalar n, real scalar r) { st_numscalar("r(p2)", scalar_prho(n, r)) } real scalar scalar_prho(real scalar n, real scalar r) { real scalar ifault real scalar res res = sl89_prho(n, (n^3-n)*(1-r)/6, ifault) if (ifault) res = . return(res) } real scalar sl89_prho(real scalar n, real scalar is, real scalar ifault) { /* double precision function prho(n, is, ifault) c c Algorithm AS 89 Appl. Statist. (1975) Vol.24, No. 3, P377. c c To evaluate the probability of obtaining a value greater than or c equal to is, where is=(n**3-n)*(1-r)/6, r=Spearman's rho and n c must be greater than 1 c c Auxiliary function required: ALNORM = algorithm AS66 c */ real vector l /*(16)*/ real scalar b, x, y, u real scalar c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12 real scalar prho real scalar js, nfac, i, ifr, m, ise, n1, mt, nn c1 = 0.2274d0 c2 = 0.2531d0 c3 = 0.1745d0 c4 = 0.0758d0 c5 = 0.1033d0 c6 = 0.3932d0 c7 = 0.0879d0 c8 = 0.0151d0 c9 = 0.0072d0 c10 = 0.0831d0 c11 = 0.0131d0 c12 = 0.00046d0 /* c c Test admissibility of arguments and initialize c */ l = J(1,16,.) prho = 1 ifault = 1 if (n < 1) return(prho) ifault = 0 if (is < 0) return(prho) prho = 0 if (is > n * (n * n -1) / 3) return(prho) js = is if (js != 2 * (js / 2)) js++ if (n > 6) goto L6 /* c c Exact evaluation of probability c */ nfac = 1 for (i=1; i<=n; i++) { nfac = nfac * i l[i] = i } prho = 1 / nfac if (js == n * (n * n -1) / 3) return(prho) ifr = 0 for (m=1; m<=nfac; m++) { ise = 0 for (i=1; i<=n; i++) { ise = ise + (i - l[i]) ** 2 L2: } if (js < ise) ifr = ifr++ n1 = n L3: mt = l[1] nn = n1 - 1 for (i=1; i<=nn; i++) { l[i] = l[i + 1] } l[n1] = mt if (l[n1]!=n1 | n1== 2) goto L5 n1-- if (m != nfac) goto L3 L5: } prho = ifr / nfac return(prho) /* c c Evaluation by Edgeworth series expansion c */ L6: b = 1 / n x = (6 * (js - 1) * b / (1 / (b * b) -1) - 1) * sqrt(1 / b - 1) y = x * x u = x * b * (c1 + b * (c2 + c3 * b) + y * (-c4 + b * (c5 + c6 * b) - y * b * (c7 + c8 * b - y * (c9 - c10 * b + y * b * (c11 - c12 * y))))) /* c c Call to algorithm AS 66 Original line was prho = u / exp(y / 2) + alnorm(x, /* .true.*/ 1) alnorm() says area from x to infinity if .true. Thus alnorm(x, .true.) <=> normal(-x) c */ prho = u / exp(y / 2) + normal(-x) if (prho < 0) prho = 0 else if (prho > 1) prho = 1 return(prho) } scalar_prho(20, .2) end