runs(3f) - [M_datapac:ANALYSIS] perform a runs test
SUBROUTINE RUNS(X,N)
REAL(kind=wp),intent(in) :: X(:)
INTEGER,intent(in) :: N
RUNS(3f) performs a runs analysis of the data in the input vector x.
This runs analysis is a useful distribution-free test of the randomness
of a data set.
The analysis consists of first determining the observed number of
runs from the data, and then computing the expected number of runs,
the standard deviation of the number of runs, and the resulting
standardized statistic for the number of runs for runs of various
lengths.
This is done for runs up, runs down, and runs up and down.
X The precision vector of (unsorted or sorted) observations.
N The integer number of observations in the vector x.
restrictions-- The maximum allowable value of n for this subroutine
is 15000.
4 pages of automatic printout consisting of the observed number,
expected number, standard deviation and resulting standardized
statistic for runs of various lengths, and the cumulative frequency.
Sample program:
program demo_runs
use M_datapac, only : runs
implicit none
! call runs(x,y)
end program demo_runs
Results:
The original DATAPAC library was written by James Filliben of the Statistical
Engineering Division, National Institute of Standards and Technology.
John Urban, 2022.05.31
CC0-1.0
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | X(:) | |||
integer, | intent(in) | :: | N |
Type | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|
real | :: | WS(15000) |
SUBROUTINE RUNS(X,N) REAL(kind=wp),intent(in) :: X(:) INTEGER,intent(in) :: N REAL(kind=wp) :: ai, an, anrdl, anrdlg, anrtl, anrtlg, anrul, anrulg REAL(kind=wp) :: c1, c2, c3, c4, den, enrtl, enrtlg, enrul, enrulg, hold, snrtl, snrtlg REAL(kind=wp) :: snrul, snrulg, stat, WS, Y, znrdl, znrdlg, znrtl, znrtlg, znrul, znrulg INTEGER :: i, imax, ip1, iupper, j, jp1, lendn, lenup, maxlnd, maxlnt, maxlnu, nm1, nneg, npos, nrdl, nrdlg, nrtl, nrtlg INTEGER :: nrul, nrulg, nzer DIMENSION Y(15000) DIMENSION nrul(16) , nrdl(16) , nrtl(16) , nrulg(16) , nrdlg(16) DIMENSION nrtlg(16) DIMENSION enrul(16) , enrtl(16) , enrulg(16) , enrtlg(16) DIMENSION snrul(16) , snrtl(16) , snrulg(16) , snrtlg(16) DIMENSION znrul(16) , znrdl(16) , znrtl(16) , znrulg(16) , znrdlg(16) DIMENSION znrtlg(16) DIMENSION c1(15) , c2(15) , c3(15) , c4(15) DIMENSION anrul(16) , anrdl(16) , anrtl(16) DIMENSION anrulg(16) , anrdlg(16) , anrtlg(16) COMMON /BLOCK2_real64/ WS(15000) EQUIVALENCE (Y(1),WS(1)) DATA c1(1) , c1(2) , c1(3) , c1(4) , c1(5) , c1(6) , c1(7) , & & c1(8) , c1(9) , c1(10) , c1(11) , c1(12) , c1(13) , c1(14) , & & c1(15)/0.4236111111E+00_wp , .1126675485E+00_wp , .4191688713E-01_wp , & & .1076912487E-01_wp , .2003959238E-02_wp , .3023235799E-03_wp , & & .3911555473E-04_wp , .4459038843E-05_wp , .4551105210E-06_wp , & & .4207466837E-07_wp , .3555930927E-08_wp , .2768273257E-09_wp , & & .1997821524E-10_wp , .1343876568E-11_wp , .8465610177E-13_wp/ DATA c2(1) , c2(2) , c2(3) , c2(4) , c2(5) , c2(6) , c2(7) , & & c2(8) , c2(9) , c2(10) , c2(11) , c2(12) , c2(13) , c2(14) , & & c2(15)/ - .4819444444E+00_wp , -.1628284832E+00_wp , & & -.9690696649E-01_wp , -.3778106786E-01_wp , -.9289228716E-02_wp , & & -.1724429252E-02_wp , -.2638557888E-03_wp , -.3466965096E-04_wp , & & -.4004129153E-05_wp , -.4130382587E-06_wp , -.3851876069E-07_wp , & & -.3279103786E-08_wp , -.2568491117E-09_wp , -.1863433868E-10_wp , & & -.1259220466E-11_wp/ DATA c3(1) , c3(2) , c3(3) , c3(4) , c3(5) , c3(6) , c3(7) , & & c3(8) , c3(9) , c3(10) , c3(11) , c3(12) , c3(13) , c3(14) , & & c3(15)/.1777777778E+00_wp , .7916666667E-01_wp , .4738977072E-01_wp , & & .1274801587E-01_wp , .2338606059E-02_wp , .3461358734E-03_wp , & & .4407121770E-04_wp , .4960020603E-05_wp , .5010387575E-06_wp , & & .4592883352E-07_wp , .3854170274E-08_wp , .2982393839E-09_wp , & & .2141205844E-10_wp , .1433843200E-11_wp , .8996663214E-13_wp/ DATA c4(1) , c4(2) , c4(3) , c4(4) , c4(5) , c4(6) , c4(7) , & & c4(8) , c4(9) , c4(10) , c4(11) , c4(12) , c4(13) , c4(14) , & & c4(15)/ - .3222222222E+00_wp , -.5972222222E-01_wp , & & -.1130268959E+00_wp , -.4696428571E-01_wp , -.1123273065E-01_wp , & & -.2025170849E-02_wp , -.3029410411E-03_wp , -.3912824548E-04_wp , & & -.4459234519E-05_wp , -.4551128785E-06_wp , -.4207469124E-07_wp , & & -.3555931110E-08_wp , -.2768273269E-09_wp , -.1997821525E-10_wp , & & -.1343876568E-11_wp/ ! iupper = 15000 ! ! CHECK THE INPUT ARGUMENTS FOR ERRORS ! IF ( N<1 .OR. N>iupper ) THEN WRITE (G_IO,99001) iupper 99001 FORMAT (' ***** FATAL ERROR--THE SECOND INPUT ARGUMENT TO RUNS(3f) IS OUTSIDE THE ALLOWABLE (1,',I0,') INTERVAL *****') WRITE (G_IO,99002) N 99002 FORMAT (' ','***** THE VALUE OF THE ARGUMENT IS ',I0,' *****') RETURN ELSEIF ( N==1 ) THEN WRITE (G_IO,99003) 99003 FORMAT (' ***** FATAL ERROR-- THE SECOND INPUT ARGUMENT TO THE RUNS SUBROUTINE HAS THE VALUE 1 *****') RETURN ELSE hold = X(1) DO i = 2 , N IF ( X(i)/=hold ) GOTO 50 ENDDO WRITE (G_IO,99004) hold 99004 FORMAT (' ***** NON-FATAL DIAGNOSTIC--THE FIRST INPUT ARGUMENT (A VECTOR) TO RUNS(3f) HAS ALL ELEMENTS = ',E15.8,' *****') ! !-----START POINT----------------------------------------------------- ! 50 an = N ! ! FORM THE SEQUENTIAL DIFFERENCE TABLE ! nm1 = N - 1 DO i = 1 , nm1 ip1 = i + 1 Y(i) = X(ip1) - X(i) ENDDO ! ! ZERO-OUT THE 6 'NUMBER OF RUNS' VECTORS ! DO i = 1 , 16 nrul(i) = 0 nrdl(i) = 0 nrtl(i) = 0 nrulg(i) = 0 nrdlg(i) = 0 nrtlg(i) = 0 ENDDO ! ! DETERMINE THE NUMBER OF RUNS UP OF LENGTH EXACTLY I ! AND THE NUMBER OF RUNS DOWN OF LENGTH EXACTLY I ! DETERMINE THE LENGTH OF THE LONGEST RUN UP ! AND THE LENGTH OF THE LONGEST RUN DOWN ! lenup = 0 lendn = 0 maxlnu = 0 maxlnd = 0 DO i = 1 , nm1 IF ( Y(i)==0.0_wp .AND. lenup>=1 ) lenup = lenup + 1 IF ( Y(i)==0.0_wp .AND. lendn>=1 ) lendn = lendn + 1 IF ( Y(i)==0.0_wp .AND. lenup==0 .AND. lendn==0 ) lenup = lenup + 1 IF ( Y(i)>0.0_wp .AND. lendn>=1 .AND. lendn<=15 ) nrdl(lendn) = nrdl(lendn) + 1 IF ( Y(i)>0.0_wp .AND. lendn>=1 .AND. lendn>=16 ) nrdl(16) = nrdl(16) + 1 IF ( Y(i)>0.0_wp ) lendn = 0 IF ( Y(i)>0.0_wp ) lenup = lenup + 1 IF ( Y(i)<0.0_wp .AND. lenup>=1 .AND. lenup<=15 ) nrul(lenup) = nrul(lenup) + 1 IF ( Y(i)<0.0 .AND. lenup>=1 .AND. lenup>=16 ) nrul(16) = nrul(16) + 1 IF ( Y(i)<0.0 ) lenup = 0 IF ( Y(i)<0.0 ) lendn = lendn + 1 IF ( i==nm1 .AND. lendn>=1 .AND. lendn<=15 ) nrdl(lendn) = nrdl(lendn) + 1 IF ( i==nm1 .AND. lendn>=1 .AND. lendn>=16 ) nrdl(16) = nrdl(16) + 1 IF ( i==nm1 .AND. lenup>=1 .AND. lenup<=15 ) nrul(lenup) = nrul(lenup) + 1 IF ( i==nm1 .AND. lenup>=1 .AND. lenup>=16 ) nrul(16) = nrul(16) + 1 IF ( lenup>maxlnu ) maxlnu = lenup IF ( lendn>maxlnd ) maxlnd = lendn ENDDO ! ! DETERMINE THE NUMBER OF RUNS TOTAL OF LENGTH EXACTLY I ! AND THE LENGTH OF THE LONGEST RUN UP OR DOWN ! DO i = 1 , 16 nrtl(i) = nrul(i) + nrdl(i) ENDDO maxlnt = maxlnu IF ( maxlnd>maxlnu ) maxlnt = maxlnd ! ! DETERMINE THE NUMBER OF RUNS UP OF LENGTH I OR MORE ! AND THE NUMBER OF RUNS DOWN OF LENGTH I OR MORE ! AND THE NUMBER OF RUNS TOTAL OF LENGTH I OR MORE ! nrulg(16) = nrul(16) nrdlg(16) = nrdl(16) nrtlg(16) = nrtl(16) DO i = 1 , 15 j = 16 - i jp1 = j + 1 nrulg(j) = nrulg(jp1) + nrul(j) nrdlg(j) = nrdlg(jp1) + nrdl(j) nrtlg(j) = nrtlg(jp1) + nrtl(j) ENDDO ! ! DETERMINE THE NUMBER OF POSITIVE, ZERO, AND NEGATIVE ENTRIES ! IN THE DIFFERENCE TABLE. IF RANDOM, THE NUMBER OF POSITIVE SHOULD BE ! APPROXIMATELY EQUAL TO THE NUMBER OF NEGATIVE ! nneg = 0 nzer = 0 npos = 0 DO i = 1 , nm1 IF ( Y(i)<0.0_wp ) nneg = nneg + 1 IF ( Y(i)==0.0_wp ) nzer = nzer + 1 IF ( Y(i)>0.0_wp ) npos = npos + 1 ENDDO ! ! COMPUTE THE EXPECTED NUMBER OF RUNS UP OF LENGTH EXACTLY I = ! THE EXPECTED NUMBER OF RUNS DOWN OF LENGTH EXACTLY I = ! ONE HALF THE EXPECTED NUMBER OF RUNS TOTAL OF LENGTH EXACTLY I ! den = 6.0_wp DO i = 1 , 15 ai = i enrul(i) = an*(ai*ai+3.0_wp*ai+1.0_wp) - (ai*ai*ai+3.0_wp*ai*ai-ai-4.0_wp) den = den*(ai+3.0_wp) enrul(i) = enrul(i)/den enrtl(i) = 2.0_wp*enrul(i) ENDDO ! ! COMPUTE THE EXPECTED NUMBER OF RUNS UP OF LENGTH I OR MORE = ! THE EXPECTED NUMBER OF RUNS DOWN OF LENGTH I OR MORE = ! ONE HALF THE EXPECTED NUMBER OF RUNS TOTAL OF LENGTH I OR MORE ! den = 2.0_wp DO i = 1 , 15 ai = i enrulg(i) = an*(ai+1.0_wp) - (ai*ai+ai-1.0_wp) den = den*(ai+2.0_wp) enrulg(i) = enrulg(i)/den enrtlg(i) = 2.0_wp*enrulg(i) ENDDO ! ! COMPUTE THE STANDARD DEV. OF THE NUMBER OF RUNS UP OF LENGTH EXACTLY I = ! THE STANDARD DEV. OF THE NUMBER OF RUNS DOWN OF LENGTH EXACTLY I = ! SQRT(0.5)* THE STAND. DEV. OF THE NUMBER OF RUNS TOTAL OF LENGTH EXACTLY I ! DO i = 1 , 15 snrtl(i) = SQRT(c1(i)*an+c2(i)) snrul(i) = SQRT(0.5_wp)*snrtl(i) ENDDO ! ! COMPUTE THE STAND. DEV. OF THE NUMBER OF RUNS UP OF LENGTH I OR MORE = ! THE STAND. DEV. OF THE NUMBER OF RUNS DOWN OF LENGTH I OR MORE = ! SQRT(0.5)* THE STAND. DEV. OF THE NUMBER OF RUNS TOTAL OF LENGTH I OR MORE ! DO i = 1 , 15 snrtlg(i) = SQRT(c3(i)*an+c4(i)) snrulg(i) = SQRT(0.5_wp)*snrtlg(i) ENDDO ! ! FORM Z STATISTICS ! DO i = 1 , 15 stat = nrul(i) znrul(i) = (stat-enrul(i))/snrul(i) stat = nrdl(i) znrdl(i) = (stat-enrul(i))/snrul(i) stat = nrtl(i) znrtl(i) = (stat-enrtl(i))/snrtl(i) stat = nrulg(i) znrulg(i) = (stat-enrulg(i))/snrulg(i) stat = nrdlg(i) znrdlg(i) = (stat-enrulg(i))/snrulg(i) stat = nrtlg(i) znrtlg(i) = (stat-enrtlg(i))/snrtlg(i) ENDDO ! DO i = 1 , 15 anrul(i) = nrul(i) anrdl(i) = nrdl(i) anrtl(i) = nrtl(i) anrulg(i) = nrulg(i) anrdlg(i) = nrdlg(i) anrtlg(i) = nrtlg(i) ENDDO ! ! WRITE EVERYTHING OUT ! imax = 15 WRITE (G_IO,99024) WRITE (G_IO,99005) 99005 FORMAT (' ',48X,'RUNS UP') WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99006) 99006 FORMAT (' ',27X, 'STATISTIC = NUMBER OF RUNS UP OF LENGTH EXACTLY I') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrul(i) , enrul(i) , snrul(i) , znrul(i) ENDDO WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99007) 99007 FORMAT (' ',27X, 'STATISTIC = NUMBER OF RUNS UP OF LENGTH I OR MORE') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrulg(i) , enrulg(i) , snrulg(i) , znrulg(i) ENDDO WRITE (G_IO,99024) WRITE (G_IO,99008) 99008 FORMAT (' ',48X,'RUNS DOWN') WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99009) 99009 FORMAT (' ',27X, 'STATISTIC = NUMBER OF RUNS DOWN OF LENGTH EXACTLY I') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrdl(i) , enrul(i) , snrul(i) , znrdl(i) ENDDO WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99010) 99010 FORMAT (' ',27X, 'STATISTIC = NUMBER OF RUNS DOWN OF LENGTH I OR MORE') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrdlg(i) , enrulg(i) , snrulg(i) , znrdlg(i) ENDDO WRITE (G_IO,99024) WRITE (G_IO,99011) 99011 FORMAT (' ',40X,'RUNS TOTAL = RUNS UP + RUNS DOWN') WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99012) 99012 FORMAT (' ',27X, 'STATISTIC = NUMBER OF RUNS TOTAL OF LENGTH EXACTLY I') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrtl(i) , enrtl(i) , snrtl(i) , znrtl(i) ENDDO WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99013) 99013 FORMAT (' ',27X,'STATISTIC = NUMBER OF RUNS TOTAL OF LENGTH I OR MORE') WRITE (6,99025) WRITE (6,99025) WRITE (G_IO,99022) WRITE (G_IO,99025) DO i = 1 , imax WRITE (G_IO,99023) i , anrtlg(i) , enrtlg(i) , snrtlg(i) , znrtlg(i) ENDDO WRITE (G_IO,99024) WRITE (G_IO,99014) maxlnu 99014 FORMAT (' ','LENGTH OF THE LONGEST RUN UP = ',I0) WRITE (G_IO,99015) maxlnd 99015 FORMAT (' ','LENGTH OF THE LONGEST RUN DOWN = ',I0) WRITE (G_IO,99016) maxlnt 99016 FORMAT (' ','LENGTH OF THE LONGEST RUN UP OR DOWN = ',I0) WRITE (G_IO,99025) WRITE (G_IO,99017) npos 99017 FORMAT (' ','NUMBER OF POSITIVE DIFFERENCES = ',I0) WRITE (G_IO,99018) nneg 99018 FORMAT (' ','NUMBER OF NEGATIVE DIFFERENCES = ',I0) WRITE (G_IO,99019) nzer 99019 FORMAT (' ','NUMBER OF ZERO DIFFERENCES = ',I0) 99020 FORMAT (' ',2(I4,2X,F7.1,2X,F8.4,2X,F8.4,2X,F8.2,8X)) 99021 FORMAT (' ',I0,2X,I0,2X,I0) ENDIF 99022 FORMAT (' ', 'I = LENGTH OF RUN VALUE OF STAT EXP(STAT) SD(STAT) (STAT-EXP(STAT))/SD(STAT)') 99023 FORMAT (' ',4X,I4,13X,6X,F7.1,13X,F8.4,12X,F8.4,11X,F8.2) 99024 FORMAT ('1') 99025 FORMAT (' ') END SUBROUTINE RUNS