home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
educ
/
pstat2.zip
/
LILFOR13.PQS
/
lilfor13.pas
Wrap
Pascal/Delphi Source File
|
1987-02-07
|
28KB
|
922 lines
PROGRAM Lilfor ; { Version 1.3 }
{ This program does two things. It prints a graph that can be used to hand
plot a sample CDF to perform the Lilliefors test for normality. It also
reads data from disk or keyboard and performs the Lilliefors test, both
graphically and algebraically. To do the test, there must be between 4
and 255 rows of data. See LILFOR.DOC for more information. }
{ This program is placed in the public domain by Joseph C. Hudson }
{$C-}
CONST Limit = 255;
TYPE
String3 = String[3] ;
String14 = String[14] ;
InSet = Set Of Char ;
Indices = Array [1..15] Of String[3] ;
GridSize = Array [0..719,0..49] Of Byte ;
DataType = Array [1..Limit] Of Real ;
VAR
DataCol, Special, Op1, Op2, N : Integer ;
Key : Char ;
Elite, FormFeed, GraphLine, InitPr, Lpi6, LS872 : String[6] ;
FileName : String[14] ;
Data: DataType ;
Grid : GridSize ;
DCrit, ErrTol, S2Pi, DMax, WMax, XMax : Real ;
Reject, DoneAlready : Boolean ;
Y : Array [1..718] Of Real ;
Digit : Array [ 0..9 , 1..5 ] Of Integer ;
Index : Array [1..15] Of String3 ;
Quantile : Array [1..15] Of Real ;
Procedure DefinePrintVars ;
Begin
Elite := #27#77 ; { elite pitch, 12 char/in. }
FormFeed := #12 ; { formfeed }
GraphLine := #27#76#208#2 ; { set for 8 lines of 720 dots @ 120 per in. }
InitPr := #27#64 ; { Initialize Printer }
Lpi6 := #27#50 ; { Line spacing 6 lines per in. }
LS872 := #27#51#24 ; { Line spacing 8/72 in. }
End ; { DefinePrintVars }
Procedure SetUp ;
Var
I, J, Code : Integer ;
Dig1, Dig2 : String[50] ;
Begin
DataCol := 0 ;
FileName := '' ;
DoneAlready := False ;
N := 0 ; S2Pi := Sqrt(2.0 * Pi) ;
ErrTol := 0.5 * Exp( -4.0 * Ln(10.0)) * S2Pi ;
Dig1 := '06090909061404040604150204091407080608070404150505' ;
Dig2 := '07080701150609070106040404091406090609060608140906' ;
For I := 0 To 4 Do
For J := 1 To 5 Do
Begin
Val(Copy(Dig1,10*I+2*J-1,2),Digit[I,J],Code) ;
Val(Copy(Dig2,10*I+2*J-1,2),Digit[I+5,J],Code) ;
End ; { For J }
End ; { SetUp }
Procedure Exchange (Var X1, X2 : Real) ;
Var Temp : Real ;
Begin
Temp := X1 ;
X1 := X2 ;
X2 := Temp ;
End ; { Exchange }
Procedure Heap(I, N : Integer) ;
Begin
While ( 2 * I + 1 <= N ) And
( ( Data[I] < Data[2*I] ) Or ( Data[I] < Data[2*I+1] ) ) Do
Begin
If Data[2*I] > Data[2*I+1] Then
Begin
Exchange(Data[I],Data[2*I]) ;
I := 2 * I ;
End { Then }
Else Begin
Exchange(Data[I],Data[2*I+1]) ;
I := 2 * I + 1 ;
End ; { Else }
End ; { While }
If ( ( 2 * I = N ) And ( Data[I] < Data[2*I] ) )
Then Exchange(Data[I],Data[2*I]) ;
End ; { Heap }
Procedure SortData ;
Var
I, M : Integer ;
Begin
ClrScr ; GoToXY(30,12) ;
Write(Con,'<<< Sorting Data >>>') ;
I := Trunc ( ( N / 2.0 ) + 0.1 ) ;
While I >= 1 Do
Begin
Heap(I,N) ;
I := I - 1 ;
End ; { While }
M := N ;
While M > 1 Do
Begin
Exchange(Data[1],Data[M]) ;
M := M - 1 ;
Heap(1,M) ;
End ; { While }
ClrScr ;
End ; { SortData }
Function InKey(ValCar: InSet): CHAR;
Var Key : Char ;
Begin
Repeat
Read(Kbd, Key);
Key := UpCase(Key);
Until Key In ValCar ;
IF Key = #8 THEN
Begin
Key := #255 ;
Write(Con, #8#32#8) ;
End ;
InKey := Key;
End ; { InKey }
Procedure InputLn(Var Line : String14 ; Var Count : Integer ;
Max: Integer ; ValCar, Term : InSet ; Var Key : Char ) ;
Begin
Repeat
READ(Kbd, Key);
Key := UPCASE(Key);
IF (Key IN ValCar) AND (Count < Max) THEN
BEGIN
WRITE(Key);
Line := Line + Key;
Count := Count + 1;
END;
IF (Key = #8) AND (Count >= 0) THEN
BEGIN
WRITE(#8#32#8);
Delete(Line,LENGTH(Line),1);
Count := Count - 1;
END;
UNTIL (Key IN Term) OR (Key = #13) OR ((Key = #8) AND (Count = -1));
IF Count = -1 THEN
Key := #255;
END ; { Inputln }
PROCEDURE GetNum(VAR Number: REAL; VAR Key: CHAR);
VAR
Decimal: BOOLEAN;
NumStr: String14;
Size,Count: INTEGER;
BEGIN
GotoXY(32,22); WRITE('X = ');
GotoXY(36,22); NumStr := '';
Decimal := FALSE;
Size := 0; Count := 0;
REPEAT
IF Size > 0 THEN Key := InKey(['0'..'9','.','-',#13,#8,#5,#27])
ELSE Key := InKey(['0'..'9','.','-',#13,#5,#27]);
CASE Key OF
#255: BEGIN
Key := NumStr[LENGTH(NumStr)];
IF Key = '.' THEN Decimal := FALSE
ELSE IF Key IN ['0'..'9'] THEN Count := Count - 1;
Delete(NumStr,LENGTH(NumStr),1);
Size := Size - 1;
Key := '@';
END;
'.': IF NOT Decimal THEN
BEGIN
WRITE(Key);
NumStr := NumStr + Key;
Size := Size + 1;
Decimal := TRUE;
END;
'-': IF Size = 0 THEN
BEGIN
WRITE(Key);
NumStr := NumStr + Key;
Size := Size + 1;
END;
'0'..'9': IF Count < 10 THEN
BEGIN
WRITE(Key);
Size := Size + 1;
NumStr := NumStr + Key;
Count := Count + 1;
END
END; { Case }
UNTIL (Key IN [#5,#27]) OR ((Key = #13) AND (Count > 0));
IF Key = #13 THEN Val(NumStr,Number,Size);
END; { GetNum }
PROCEDURE InputFile(Var Key: Char) ;
LABEL
Jump1,Jump2,Jump3,Jump4;
VAR
I,J,K: INTEGER;
Flag: BOOLEAN;
BEGIN
Jump1: GotoXY(28,10);
WRITE('File name: ');
Key := InKey(['A'..'Z',#27]);
IF Key = #27 THEN
Begin
FileName := '' ;
Exit;
End ; { If }
FileName := Key;
WRITE(FileName);
K := 0;
Jump2: InputLn(FileName,K,7,['0'..'9','A'..'Z'],['.',':',#27],Key);
IF Key = #27 THEN
Begin
FileName := '' ;
Exit ;
End ; { If }
IF Key = #255 THEN Goto Jump1 ;
Flag := FALSE;
IF Key = ':' THEN
BEGIN
WRITE(':');
FileName := FileName + ':';
Jump3: Key := InKey(['A'..'Z',#8,#27]);
IF Key = #27 THEN
Begin
FileName := '' ;
Exit ;
End ; { If Key = #27 }
IF Key = #255 THEN Goto Jump2 ;
WRITE(Key);
FileName := FileName + Key;
I := 0;
Jump4: InputLn(FileName,I,7,['0'..'9','A'..'Z'],['.',#27],Key);
IF Key = #27 THEN
Begin
FileName := '' ;
Exit ;
End ; { If Key = #27 }
If Key = #255 Then Goto Jump3 ;
Flag := TRUE;
End ; { If Key = ':'}
IF Key = '.' THEN
Begin
Write('.') ;
FileName := FileName + '.';
J := 0;
InputLn(FileName,J,3,['0'..'9','A'..'Z'],[#27],Key);
If Key = #27 Then
Begin
FileName := '' ;
Exit;
End ; { If Key = #27 }
IF Key = #255 THEN IF Flag THEN Goto Jump4 ELSE Goto Jump2 ;
End ; { If Key = '.' }
End ; { InputFile }
PROCEDURE InputNumber(VAR Number: INTEGER; VAR Key: CHAR);
LABEL
Back1, Back2, Back3;
VAR
NumStr: String3;
Code: INTEGER;
BEGIN
Back1: NumStr := ' ';
NumStr[1] := InKey(['1'..'9',#27]);
IF NumStr[1] <> #27 THEN
BEGIN
WRITE(NumStr[1]);
Back2: IF NumStr[1] IN ['1'..'3'] THEN NumStr[2] := InKey(['0'..'9',#27,#8])
ELSE NumStr[2] := InKey(['0'..'9',#27,#13,#8]);
CASE NumStr[2] OF
#27: Key := '@';
#255: Goto Back1;
ELSE WRITE(NumStr[2]);
END;
Back3: IF NOT (NumStr[2] IN [#13,#27]) THEN
BEGIN
NumStr[3] := InKey(['0'..'9',#27,#13,#8]);
CASE NumStr[3] OF
#27: Key := '@';
#255: Goto Back2;
ELSE
BEGIN
WRITE(NumStr[3]);
Key := InKey([#13,#27,#8]);
CASE Key OF
#27: Key := '@';
#255: Goto Back3;
END;
END;
END;
END;
END
ELSE
Key := '@';
Val(NumStr,Number,Code)
END;
FUNCTION Up2(Power: INTEGER): BYTE;
VAR
I: INTEGER;
Result: BYTE;
BEGIN
Result := 1;
I := 0;
WHILE Power > I DO
BEGIN
Result := Result * 2;
I := I + 1;
END;
Up2 := Result;
END;
PROCEDURE SaveData(VAR X: DataType; N: INTEGER);
VAR
Key: CHAR;
I: INTEGER;
OutFile: TEXT;
BEGIN
ClrScr;
GotoXY(26,12);
IF N > 0 THEN
BEGIN
InputFile(Key);
IF Key = #27 THEN
Begin
FileName := '' ;
Exit;
End ; { If Key = #27 }
ClrScr;
GotoXY(26,12);
WRITE('<<< Writing Data to Disk >>>');
ASSIGN(OutFile, FileName);
REWRITE(OutFile);
FOR I := 1 TO N DO
WRITELN(OutFile, X[I]:15:8);
CLOSE(OutFile);
END
ELSE
BEGIN
WRITE('<<< Insufficent Data >>>');
Delay(1000);
END;
ClrScr;
END;
FUNCTION ConFrac(X: REAL): REAL;
VAR
X2, Term, Sum, ETol, Beta : REAL;
Kount: INTEGER;
BEGIN
X2 := X * X ;
Etol := ErrTol * X * Exp(X2/2.0) ;
Term := 1.0 ;
Sum := 1.0 ;
Kount := 1;
Beta := 1;
WHILE ABS(Term) > Etol DO
BEGIN
Beta := 1.0 / (1.0 + Kount * Beta / X2);
Term := (Beta - 1) * Term;
Sum := Sum + Term;
Kount := Kount + 1;
END;
ConFrac := 1 - Sum * Exp(-X2/2.0) / ( S2Pi * X );
END ; { Confrac }
FUNCTION MacLauren(X: REAL): REAL;
VAR
X2, Term, Sum : REAL;
Kount: INTEGER;
BEGIN
X2 := X * X;
Term := X ;
Sum := Term;
Kount := 1;
WHILE ABS(Term) > Errtol DO
BEGIN
Term := -Term * X2 * (2 * Kount - 1) / (2 * Kount * (2 * Kount + 1));
Sum := Sum + Term;
Kount := Kount + 1;
END;
MacLauren := 0.5 + Sum / S2Pi ;
END ; { Maclauren }
FUNCTION Convert(St : String3): INTEGER;
VAR
Number, Code: INTEGER;
BEGIN
Val(St, Number, Code);
Convert := Number;
END ; { Convert }
FUNCTION CriticalD(Number: INTEGER): REAL;
VAR
Table: ARRAY[0..5] OF STRING[51];
Result: REAL;
BEGIN
IF Number < 21 THEN
BEGIN
Table[5] := '303289269252239227217208200' +
'193187181176171167163159' ;
Table[4] := '321303281264250238228218210' +
'202196190184179175170166' ;
Table[3] := '346319297280265252241231222' +
'215208201195190185181176' ;
Table[2] := '376343323304288274262251242' +
'234226219213207202197192' ;
Table[1] := '413397371351333317304291281' +
'271262254247240234228223' ;
Table[0] := '433439424402384365352338325' +
'314305296287279273266260' ;
Result := Convert(Copy(Table[Op1],1+3*(Number-4),3))/1000;
End
Else
Case Op1 Of
0 : Result := 1.0 / Sqrt( 1.0194273 - 7.439981E-5 * Sqr(Number)
+ 0.69594400 * Number ) ;
1 : Result := 1.0 / Sqrt( 1.5014504 - 2.688139E-5 * Sqr(Number)
+ 0.92969285 * Number ) ;
2 : Result := 1.0 / Sqrt( 2.4247449 + 4.2778854E-6 * Sqr(Number)
+ 1.2279378 * Number ) ;
3 : Result := 1.0 / Sqrt( 1.6210592 - 1.250862E-4 * Sqr(Number)
+ 1.5283685 * Number ) ;
4 : Result := 1.0 / Sqrt( 3.2539680 + 4.4853635E-6 * Sqr(Number)
+ 1.6358438 * Number ) ;
5 : Result := 1.0 / Sqrt( 2.6080763 - 8.113091E-5 * Sqr(Number)
+ 1.8481843 * Number ) ;
End ; { Case }
CriticalD := Result ;
END ; { CriticalD }
Procedure PlotX(VAR X: DataType; N: INTEGER);
Var
Lv, Lz, Z, V, I, J, K,Correct: INTEGER;
StanDev, Xbar, X2sum, F, D : REAL;
W: DataType;
M: ARRAY[0..719] OF INTEGER;
Begin
Xbar := 0 ; X2sum := 0 ; Lv := 0 ;
For I := 1 To N Do
Begin
Xbar := Xbar + X[I];
X2sum := X2sum + X[I] * X[I];
End ; { For }
Xbar := Xbar / N ;
StanDev := SQRT((X2sum - Xbar * Xbar * N) / (N - 1));
For I := 1 To N Do
IF StanDev = 0 Then W[I] := 0 Else W[I] := (X[I] - Xbar) / StanDev ;
DMax := 0.0 ;
For I := 1 To N Do
Begin
If Abs(W[I])>2.0 Then F:=ConFrac(Abs(W[I])) Else F:=Maclauren(Abs(W[I]));
If W[I] < 0.0 Then F := 1.0 - F ;
D := Abs(F-(I-1)/N) ;
If Abs(F-I/N) > D Then D := Abs(F-I/N) ;
If D > DMax Then
Begin
DMax := D ;
WMax := W[I] ;
XMax := X[I] ;
End ; { If }
End ; { For }
DCrit := CriticalD(N) ;
If DMax > DCrit Then Reject := True Else Reject := False ;
I := 1 ; J := 0 ; K := 0 ;
Repeat
While ((W[I]=W[I+1]) And (I<N)) Do I := I + 1 ;
While (((-3.0+K/120.0)<W[I]) And (K<720)) Do
Begin
M[K] := J ;
K := K + 1 ;
End ; { While }
J := I ; I := I + 1 ;
Until ((I>N) Or (K=720)) ;
If K <= 719 Then For J := K To 719 Do M[J] := N ;
For I := 1 To 718 Do
Begin
V := Trunc(400 * (M[I] / N) + 0.5) ;
Z := 1 ;
For K := 1 To (V Mod 8) Do Z := 2 * Z ;
If V > Lv Then For K := Lv To V Do
Begin
Correct := (K Div 8) Mod 50 ;
If Correct < 0 Then Correct := 0 ;
Grid[I-1,Correct] := Grid[I-1,Correct] OR Up2(K MOD 8);
End ; { For }
Correct := (V Div 8) Mod 50 ;
If Correct < 0 Then Correct := 0 ;
Grid[I,Correct] := Grid[I,Correct] Or Z ;
Lv := V ;
End ; { For I }
End ; { PlotX }
Procedure DataEntry(Var Data : DataType ; Var N : Integer) ;
Label Jmp ;
Var
NextNum : Boolean ;
Key : Char ;
MaxCol, Col, Row, I, J, K : Integer ;
InFile : Text ;
Dummy : Real ;
DataLine : String[255] ;
Begin
FileName := '' ;
Jmp: ClrScr;
GotoXY(35,10); Write('<1> Keyboard');
GotoXY(35,12); Write('<2> Disk');
GotoXY(35,14); Write('Input from: ');
Key := InKey(['1','2',#27]); Write(Key);
If Key = #27 Then Exit ;
ClrScr;
If Key = '2' Then
Begin
InputFile(Key) ;
If Key = #27 Then
Begin
FileName := '' ;
Goto Jmp ;
End ; { If Key = #27 }
Assign(InFile,FileName) ;
{$I-} Reset(InFile) {$I+} ;
If IOResult <> 0 Then
Begin
GotoXY(28-Length(FileName) DIV 2,12) ;
Writeln(#7+'File ',FileName,' Can Not Be Located') ;
Delay(4000) ; FileName := '' ;
Exit ;
End ; { If IOResult <> 0 }
Col := 0 ; Row := 1 ;
Repeat
{ $I-} Read(InFile,Dummy) {$I+} ;
Col := Col + 1 ;
Dummy := IOResult ;
Until Eoln(InFile) ;
GotoXY(28,12) ; Writeln('File contains ',Col,' column(s)');
Repeat
DataLine := '' ;
Readln(InFile, DataLine) ;
J := 47 ;
Repeat
J := J + 1 ;
Until ( ( Pos(Chr(J),DataLine) > 0 ) Or ( J = 58 ) ) ;
If J < 58 Then Row := Row + 1 ;
Until Eof(InFile) ;
GoToXY(28,14) ; Writeln('File contains ',Row,' row(s)') ;
If Row > Limit Then
Begin
GoToXY(10,16) ;
Write(Con,'This program can only handle data files with ') ;
Write(Con,Limit,' or fewer rows.') ;
FileName := '' ;
GoToXY(10,18) ; Write(Con,'Press any key to continue.') ;
Repeat Until KeyPressed ;
GoTo Jmp ;
End ; { If Row > Limit }
If Col > 1 Then
Begin
MaxCol := Col ;
Repeat
GoToXY(56,16) ; Write(Con,' ':24) ;
GotoXY(28,16) ; Write(Con,'Enter column containing X: ') ;
{ $I-} Readln(Col) {$I+} ;
Until ((IOResult=0) And ((Col > 0) And (Col <= MaxCol))) ;
End { If Col > 1 }
Else Col := 1 ;
ClrScr ;
Reset(InFile) ;
For J := 1 To Row Do
Begin
GotoXY(32,22); WRITE(' ');
GotoXY(32,22); WRITE('X = ');
If Col > 1 Then For I := 1 To Col - 1 Do
Begin
{$I-} Read(InFile, Data[J]) {$I+} ;
If IOResult <> 0 Then
Begin
GoToXY(10,24) ;
Write(Con,' Error in data file in row ',J,' .') ;
GoToXY(10,25) ; Write(Con,'Press any key to continue.') ;
Repeat Until KeyPressed ;
GoTo Jmp ;
End ; { If IOResult <> 0 }
End ; { For I }
{$I-} Readln(InFile, Data[J]) {$I+} ;
If IOResult <> 0 Then
Begin
GoToXY(10,24) ;
Write(Con,' Error in data file in row ',J,' .') ;
GoToXY(10,25) ; Write(Con,'Press any key to continue.') ;
Repeat Until KeyPressed ;
GoTo Jmp ;
End ; { If IOResult <> 0 }
Writeln(Data[J]:-8:4);
GotoXY(4+25*(((J - 1) Div 20) Mod 3),1 + (J - 1) Mod 20);
Write(J:3,'. ',Data[J]:16:4);
End ; { For J }
Close(InFile);
DataCol := Col ;
N := Row ;
End { If Key = '2' }
Else
Begin
N := 0;
GotoXY(30,24); WRITE('Type Ctrl-E to Exit');
Repeat
N := N + 1;
GetNum(Data[N], Key);
GotoXY(4+25*(((N - 1) DIV 20) MOD 3),1 + (N - 1) MOD 20);
WRITE(N:3,'. ',Data[N]:16:4);
Until ( Key IN [#5,#27] ) Or ( N = Limit ) ;
N := N - 1;
End ; { Else }
IF N > (Limit - 1) THEN
Begin
GotoXY(25,22); WRITE('Maximum Amount of Data Entered');
Delay(2000);
End ; { If }
If N < 4 Then
Begin
N := 0 ;
ClrScr ;
GoToXY(10,4) ;
Write(Con,'Sample size is less than 4. Test cannot be run.') ;
GoToXY(10,6) ;
Write(Con,'Only graphs for hand plotting can be printed.') ;
GoToXY(10,8) ; Write(Con,'Press any key to continue.') ;
Repeat Until KeyPressed ;
End ; { If N < 4 }
End ; { DataEntry }
PROCEDURE MiniMenu(VAR Op1,Op2: INTEGER);
LABEL
Bran1, Bran2;
BEGIN
Bran1: ClrScr;
GoToXY(36,6) ; Write('<0> 99.9%') ;
GotoXY(37,8) ; Write('<1> 99%') ;
GotoXY(37,10) ; Write('<2> 95%') ;
GotoXY(37,12) ; Write('<3> 90%') ;
GotoXY(37,14) ; Write('<4> 85%') ;
GoToXY(37,16) ; Write('<5> 80%') ;
GotoXY(30,18); Write('Select confidence level: ');
Key := InKey(['0'..'5',#27]);
IF Key = #27 Then Exit ;
Writeln(Key);
Op1 := Ord(Key) - Ord('0');
Bran2: IF N > 3 THEN
BEGIN
ClrScr;
GotoXY(26,10); WRITE('<1> 5, 10, 15, 20, 30, 50, 100');
GotoXY(26,12); WRITE('<2> ',N);
GotoXY(25,14); WRITE('Plot confidence bound curve(s): ');
Key := InKey(['1','2',#27]); WRITELN(Key);
If Key = #27 Then GoTo Bran1 ;
Op2 := ORD(Key) - ORD('1');
Key := '@';
END
ELSE
BEGIN
ClrScr;
GotoXY(26,10); WRITE('<1> 5, 10, 15, 20, 30, 50, 100');
GotoXY(26,12); WRITE('<2> N');
GotoXY(25,14); WRITE('Plot confidence bound curve(s): ');
Key := InKey(['1','2',#27]); WRITELN(Key);
IF Key = #27 THEN
Goto Bran1;
IF Key = '2' THEN
BEGIN
GotoXY(25,16); WRITE('Enter N value: ');
InputNumber(Special,Key);
IF Key = '@' THEN
Goto Bran2;
END;
Op2 := ORD(Key) - ORD('1');
Key := '@';
END;
END;
PROCEDURE ScreenMenu;
BEGIN
ClrScr;
GotoXY(24,4) ; WRITE('LILLIEFORS TEST FOR NORMALITY');
GotoXY(29,8) ; WRITE('<E> Enter data');
GotoXY(29,10) ; WRITE('<S> Save data to disk');
GotoXY(29,12) ; WRITE('<P> Print graph');
GotoXY(29,14) ; WRITE('<X> Exit program');
GotoXY(29,16) ; WRITE('Selection: ');
Key := InKey(['E','S','P','X']) ; WRITELN(Key) ;
CASE Key OF
'E': Begin DataEntry(Data, N); SortData ; End ;
'S': SaveData(Data, N);
'P': IF (N = 0) OR (N > 3) Then MiniMenu(Op1,Op2)
Else
Begin
ClrScr;
GotoXY(30,12);
WRITE('Insufficent Data to Plot');
Delay(2000);
Key := 'S';
End ; { Else }
End ; { Case }
End ; { ScreenMenu }
PROCEDURE FillIndex ;
VAR
I: INTEGER;
BEGIN
IF Op2 = 0 THEN
BEGIN
Index[01] := '5'; Index[02] := '10';
Index[03] := '15'; Index[04] := '20';
Index[05] := '30'; Index[06] := '50';
Index[07] := '100';
END
ELSE
BEGIN
FOR I := 1 TO 6 DO Index[I] := '';
IF N > 3 THEN Str(N,Index[7]) ELSE Str(Special,Index[7]) ;
END;
FOR I := 1 TO 7 DO Index[16 - I] := Index[I];
END ; { FillIndex }
PROCEDURE PlotGrid ;
VAR
I,X,Y: INTEGER;
BEGIN
FOR Y := 0 TO 49 DO Grid[0,Y] := 0;
FOR X := 1 TO 719 DO Grid[X] := Grid[0];
FOR Y := 0 TO 49 DO
BEGIN
Grid[0,Y] := 255;
Grid[719,Y] := 255;
END ;
FOR I := 1 TO 11 DO FOR Y := 0 TO 49 DO Grid[I*60,Y] := 17 ;
FOR X := 0 TO 719 DO
BEGIN
Grid[X,49] := Grid [X,49] OR 128;
Grid[X,0] := Grid[X,0] OR 1;
END;
FOR Y := 1 TO 9 DO FOR X := 0 TO 143 DO Grid[X*5,Y*5] := Grid[X*5,Y*5] OR 1;
END ; { PlotGrid }
Procedure PlotPoint(I,U : Integer ; Var V : Integer) ;
Var
J, W, Z, Z2 : Integer ;
PlotY : Real ;
Begin
PlotY := Y[U] + Quantile[I];
If ((PlotY > 0.0) AND (PlotY < 1.0)) Then
BEGIN
V := TRUNC(400.0 * PlotY + 0.5);
W := (V DIV 8) MOD 50;
Z := 1;
Z2 := V MOD 8;
FOR J := 1 TO Z2 DO Z := Z * 2;
Grid[U,W] := Grid[U,W] OR Z;
End ; { If }
End ; { PlotPoint }
Procedure WriteLabel(I, U, V, Len : Integer) ;
Var
Col, J, K, L, Row, Test, Test2, W, Z, Z2, Z3 : Integer ;
Begin
Col := U + 3 ; Row := V - 2 ;
For J := 1 To Len DO
Begin
For K := Row To Row + 4 Do
Begin
W := ( K Div 8 ) Mod 50 ;
Z2 := K Mod 8 ; Z := 1 ;
For L := 1 To Z2 Do Z := Z * 2 ; Test := 1 ;
For L := Col To Col + 3 Do
Begin
If L > Col Then Test := Test * 2 ;
Test2 := Test And Digit[Integer(Copy(Index[I],J,1))-48,K+1-Row];
If Test2 = 0 Then Z3 := 0 Else Z3 := Z ;
Grid[L,W] := Grid[L,W] Or Z3 ;
End ; { For L }
End ; { For K }
Col := Col + 5 ;
End ; { For J }
End ; { WriteLabel }
PROCEDURE PlotCurves ;
VAR
EndLabelCol, I, LabelCol, Len, LenLabel, U, V : INTEGER;
PlotY,X: REAL;
Table: ARRAY[1..5] OF STRING[21];
BEGIN
FOR I := 1 TO 7 DO
IF Index[I] <> '' THEN
BEGIN
Quantile[I] := CriticalD(Convert(Index[I]));
Quantile[16 - I] := 0 - Quantile[I];
END;
Quantile[8] := 0; Index[8] := ' ';
If Not DoneAlready Then FOR U := 1 TO 718 DO
BEGIN
X := -3.0 + 6.0 * U / 720;
IF ABS(X) < 2.25 THEN Y[U] := MacLauren(ABS(X))
ELSE Y[U] := ConFrac(ABS(X));
IF (X < 0.0) THEN Y[U] := 1.0 - Y[U] ;
End ; { If }
DoneAlready := True ;
FOR I := 1 TO 15 DO
Begin
IF Index[I] <> '' THEN
BEGIN
Len := Length(Index[I]) ;
LenLabel := 5 * Len + 1 ;
If I < 8 Then LabelCol := 8 Else LabelCol := 708 - LenLabel ;
EndLabelCol := LenLabel + LabelCol + 1 ;
If I = 8 Then EndLabelCol := 0 ;
If I <> 8 Then For U := 1 To LabelCol Do PlotPoint(I,U,V) ;
If I <> 8 Then WriteLabel(I,LabelCol,V,Len) ;
For U := EndLabelCol + 3 To 718 Do PlotPoint(I,U,V) ;
End ; { If }
End ; { For }
End ; { PlotCurves }
Procedure GraphTitle(Option: INTEGER ; Var Sig : Real);
Var I : Integer ;
Begin
For I := 0 TO 7 Do Writeln(Lst);
Case Option OF
0 : Sig := 99.9 ;
1 : Sig := 99 ;
2 : Sig := 95 ;
3 : Sig := 90 ;
4 : Sig := 85 ;
5 : Sig := 80 ;
End ;
If Option > 0 Then Write(Lst,Sig:30:0) Else Write(Lst,Sig:29:1) ;
Writeln(Lst, '% Lilliefors Bounds for Normal Samples') ;
For I := 1 TO 5 Do Writeln(Lst) ;
End ; { GraphTitle }
Procedure InitPrinter;
Begin
Writeln(Lst, InitPr, LS872, Elite) ;
End ; { InitPrinter }
Procedure PrintGraph ;
Var
A, I, J : Integer ;
Sig : Real ;
Begin
{$U+}
GraphTitle(Op1,Sig);
For I := 49 DownTo 0 Do
Begin
If (I > 10) And (I < 40) Then
Write(Lst, Copy('CUMULATIVE RELATIVE FREQUENCY',30-(I-10),1):6)
Else Write(Lst, ' ':6) ;
IF I = 49 Then Write(Lst, '1.0 ':6)
Else
If (I Mod 5) = 0 Then Write(Lst, ' .':4, I Div 5, ' ')
Else Write(Lst, ' ':6) ;
Write(Lst, GraphLine) ;
For J := 0 To 719 Do Write(Lst, Chr(Grid[J,I])) ;
Writeln(Lst) ;
End ; { For }
Writeln(Lst,Elite) ;
Writeln(Lst,-3:13,-2:12,-1:12,0:12,1:12,2:12,3:12) ;
Writeln(Lst) ; Writeln(Lst) ;
Writeln(Lst, 'STANDARDIZED SAMPLE VALUE':60) ;
If N > 4 Then
Begin
Writeln(Lst,Lpi6, Elite) ;
Writeln(Lst) ; Writeln(Lst) ;
If FileName <> '' Then
Begin
Write(Lst,' ':9,'The data is column ',DataCol:2) ;
Writeln(Lst,' of file ',FileName,'.') ;
End ; { If FileName <> '' }
Write(Lst,' ':9,'The maximum distance between ') ;
Writeln(Lst,'the Normal and sample CDFs is ',DMax:5:4,'.');
Write(Lst,' ':9,'This maximum occurs at z = ',WMax:6:4,', x = ') ;
Writeln(Lst,XMax,'.') ;
Write(Lst,' ':9,'The hypothesis of normality is ') ;
If Reject = True
Then Write(Lst,'rejected at the ',100-Sig:4:1)
Else Write(Lst,'not rejected at the ',100-Sig:4:1) ;
Writeln(Lst,'% significance level.') ;
Writeln(Lst,' ':9,'The critical distance is ',DCrit:5:3,'.') ;
End ; { If }
Write(Lst, FormFeed, InitPr) ;
End ; { PrintGraph }
Begin { Main }
DefinePrintVars ;
SetUp ;
Repeat
Special := 0;
ScreenMenu;
IF Key = '@' Then
Begin
ClrScr;
FillIndex ;
PlotGrid ;
GotoXY(27,11); Write('<<< Generating Graph >>>') ;
PlotCurves ;
If N > 4 Then PlotX(Data,N) ;
ClrScr;
GotoXY(30,12); Write('<<< Printing Graph >>>') ;
GotoXY(40,14) ;
InitPrinter ;
PrintGraph ;
End ; { If }
Until Key = 'X';
ClrScr;
End .