/* Appendix 1: Calculating P-Values for Fisher's Kappa */ /* Calculate p-values for various sample */ /* sizes and values of Fisher's Kappa. */ data one; TOOBIG=1e50; /* Machine upper limit on floating point */ TOOSMALL=1e-50; /* Machine lower limit on floating point */ MAXFACT=41; /* Maximum factorial for GAMMA function */ retain sum; /* n is the series length */ do n=25,50,100,200,500,1000,3000; m=floor(n/2); /* 1-based indexing uses n */ /* rather than n-1 */ /* r is the rank of the periodogram ordinate */ do r=1 to 4; /* z represents a possible value of Fisher's */ /* Kappa. Modify this loop to include values */ /* of interest. */ do z=0.05 to 0.95 by 0.05; b=floor(1/z); if b<(1/z) then a=b; else a=b-1; gprob=0; top=min(a,m); /* Largest index for rank in */ /* summation */ sum=1.0; do j=r to top; if j=r then do; /* Initialize for first step */ dflag=0; /* Use GAMMA function rather than */ /* multiplication if possible. */ if r<MAXFACT then do; denom=gamma(r)*r; prob=m/denom; end; else do; /* dflag=1 implies that we must now keep */ /* track of denominator. */ dflag=1; denom1=max(r-1,1); denom=r*denom1; prob=m; end; nmult=m-1; amult=1-r*z; bot1=m-r; /* Lower limit of mult. */ curexp=m-1; /* Current exponent value */ do while(nmult>bot1); bot2=TOOBIG/nmult; /* Loop until overflow avoided */ do while(prob>bot2); /* If it is impossible to avoid */ /* overflow, set prob to missing. */ /* Use -1 for now as a flag, */ /* since comparisons using */ /* missing values can be risky. */ if curexp=0 and dflag=0 then prob=-1; /* Instead of raising to a power, */ /* multiply one term at a time */ /* and anticipate using a */ /* multiplication or division to */ /* prevent overflow or underflow. */ else if curexp>0 then do; prob=prob*amult; /* Cannot */ /* overflow */ curexp=curexp-1; end; else if dflag=1 and prob>denom*TOOSMALL then do; prob=prob/denom; /* Cannot */ /* underflow */ if denom1>1 then denom1=denom1-1; if denom1=1 then dflag=0; denom=denom1; end; end; /* Failure */ if prob=-1 then do; prob=.; nmult=0; dflag=0; end; else do; /* Cannot overflow */ prob=prob*nmult; nmult=nmult-1; end; end; /* Now it is okay to exponentiate */ if curexp>0 then prob=prob*(amult**curexp); if dflag=1 then do while(dflag=1); prob=prob/denom; if denom1>1 then denom1=denom1-1; if denom1=1 then dflag=0; denom=denom1; end; sum=prob; end; else do; /* Subsequent steps in sum for j>r */ /* using recursion. We are less */ /* careful because overflow is */ /* unlikely and underflow is well */ /* approximated by zero. */ f1=(1-j*z)/(1-(j-1)*z); f2=(j-1)*(m-j+1)/(j*(j-r)); prob=f2*(f1**(m-1)); sum=-sum*prob; end; gprob=gprob+sum; end; /* End j loop */ output; end; /* End z loop */ end; /* End r loop */ end; /* End n loop */ keep z n m r gprob; run; proc print data=one; run; /**********************************************************************/ /* Appendix 2: Calculating P-Values for Fisher's Kappa */ /* from PROC SPECTRA Output */ /* Data from SAS/ETS Sample Library: SPECTRA1 */ data sunspot; input year wolfer @@; cards; 1749 809 1750 834 1751 477 1752 478 1753 307 1754 122 1755 96 1756 102 1757 324 1758 476 1759 540 1760 629 1761 859 1762 612 1763 451 1764 364 1765 209 1766 114 1767 378 1768 698 1769 1061 1770 1008 1771 816 1772 665 1773 348 1774 306 1775 70 1776 198 1777 925 1778 1544 1779 1259 1780 848 1781 681 1782 385 1783 228 1784 102 1785 241 1786 829 1787 1320 1788 1309 1789 1181 1790 899 1791 666 1792 600 1793 469 1794 410 1795 213 1796 160 1797 64 1798 41 1799 68 1800 145 1801 340 1802 450 1803 431 1804 475 1805 422 1806 281 1807 101 1808 81 1809 25 1810 0 1811 14 1812 50 1813 122 1814 139 1815 354 1816 458 1817 411 1818 304 1819 239 1820 157 1821 66 1822 40 1823 18 1824 85 1825 166 1826 363 1827 497 1828 625 1829 670 1830 710 1831 478 1832 275 1833 85 1834 132 1835 569 1836 1215 1837 1383 1838 1032 1839 858 1840 632 1841 368 1842 242 1843 107 1844 150 1845 401 1846 615 1847 985 1848 1243 1849 959 1850 665 1851 645 1852 542 1853 390 1854 206 1855 67 1856 43 1857 228 1858 548 1859 938 1860 957 1861 772 1862 591 1863 440 1864 470 1865 305 1866 163 1867 73 1868 373 1869 739 1870 1391 1871 1112 1872 1017 1873 663 1874 447 1875 171 1876 113 1877 123 1878 34 1879 60 1880 323 1881 543 1882 597 1883 637 1884 635 1885 522 1886 254 1887 131 1888 68 1889 63 1890 71 1891 356 1892 730 1893 849 1894 780 1895 640 1896 418 1897 262 1898 267 1899 121 1900 95 1901 27 1902 50 1903 244 1904 420 1905 635 1906 538 1907 620 1908 485 1909 439 1910 186 1911 57 1912 36 1913 14 1914 96 1915 474 1916 571 1917 1039 1918 806 1919 636 1920 376 1921 261 1922 142 1923 58 1924 167 ; proc spectra data=sunspot p out=a whitetest; var wolfer; run; data a; set a; retain n; if period=. then delete; if period=2.0 then delete; if _n_=2 then n=period; run; proc means data=a sum noprint; var p_01; id n; output out=b sum=psum; run; proc sort data=a; by descending p_01; run; data c; merge a b; by n; drop _type_ _freq_; run; data _null_; set c; TOOBIG=1e50; /* Machine upper limit on floating point */ TOOSMALL=1e-50; /* Machine lower limit on floating point */ MAXFACT=41; /* Maximum Factorial */ m=floor((n-1)/2); r=_n_; if r>12 then delete; /* Upper limit on r */ z=p_01/psum; b=floor(1/z); if b<(1/z) then a=b; else a=b-1; gprob=0; top=min(a,m); do j=r to top; if j=r then do; /* Initialize for first step */ dflag=0; /* Use GAMMA function rather than multiplication */ /* if possible. */ if r<MAXFACT then do; denom=gamma(r)*r; prob=m/denom; end; else do; /* dflag=1 implies that we must now keep */ /* track of denominator. */ dflag=1; denom1=max(r-1,1); denom=r*denom1; prob=m; end; nmult=m-1; amult=1-r*z; bot1=m-r; /* Lower limit of mult. */ curexp=m-1; /* Current exponent value */ do while(nmult>bot1); bot2=TOOBIG/nmult; /* Loop until overflow avoided */ do while(prob>bot2); /* If it is impossible to avoid overflow, */ /* set prob to missing. Use -1 for now as */ /* a flag, since comparisons using missing */ /* values can be risky. */ if curexp=0 and dflag=0 then prob=-1; /* Instead of raising to a power, multiply */ /* one term at a time and anticipate using */ /* a multiplication or division to prevent */ /* overflow or underflow. */ else if curexp>0 then do; /* Cannot overflow */ prob=prob*amult; curexp=curexp-1; end; else if dflag=1 and prob>denom*TOOSMALL then do; /* Cannot underflow */ prob=prob/denom; if denom1>1 then denom1=denom1-1; if denom1=1 then dflag=0; denom=denom1; end; end; if prob=-1 then do; /* Failure */ prob=.; nmult=0; dflag=0; end; else do; /* Cannot overflow */ prob=prob*nmult; nmult=nmult-1; end; end; /* Now it is okay to exponentiate */ if curexp>0 then prob=prob*(amult**curexp); if dflag=1 then do while(dflag=1); prob=prob/denom; if denom1>1 then denom1=denom1-1; if denom1=1 then dflag=0; denom=denom1; end; sum=prob; end; else do; /* Subsequent steps in sum for j>r using */ /* recursion. We are less careful because */ /* overflow is unlikely, and underflow is */ /* well approximated by zero. */ f1=(1-j*z)/(1-(j-1)*z); f2=(j-1)*(m-j+1)/(j*(j-r)); prob=f2*(f1**(m-1)); sum=-sum*prob; end; gprob=gprob+sum; end; /* End j loop */ /* Flag floating-point error */ if gprob>1 then gprob=2.0; /* Flag floating-point error */ if gprob<0 then gprob=-1.0; mz=z*m; if _n_=1 then put @1 'PERIOD R Z KAPPA P-Value'; put @1 period 6.3 @8 r 3.0 @12 z 10.5 @24 mz 10.5 @36 gprob 8.5; run;