home *** CD-ROM | disk | FTP | other *** search
- {
- F i l e I n f o r m a t i o n
-
- * DESCRIPTION
- Curve ++ (version T1.0) by Stephen Callender is a Turbo Pascal 4.0 program
- that performs multiple regression on X and Y data and then draws a line that
- will best match the data. The user can choose from four lines - straight,
- exponential, logarithmic or power.
-
- * ASSOCIATED FILES
- CURVE.PAS
- ASSAY.TXT
- CURVE.COM
- CURVE4.EXE
- CURVE4.PAS
- PRINTOUT.INC
- PT.LAS
- README
- SAMPLE.INC
- SAMPLE2.INC
- SAMPLE4.INC
- SAMPLE4B.INC
- SPACER.INC
- TOOLS.INC
- TOOLS4.INC
-
- * CHECKED BY
- DRM - 01/25/88
-
- * KEYWORDS
- CONTEST TUG-O-WARDS PROGRAM PASCAL V3.0 V4.0
-
- ==========================================================================
- }
-
- { CURVE++.PAS FROM APPLESOFT BASIC --> TURBO PASCAL SEPT. 12, 1986
- STEPHEN C. CALLENDER MODIFIED AND ENHANCED BASIC PROGRAM FROM PUBLIC DOMAIN
- UNDER DEVELOPMENT 9/16/86 SAMPLE ROUTINE ADDED
- ADD THE LAST ROUTINES SPACE, HARDCOPY PRINTOUT CURVE 10/27/86 11/21/86
- June 8, 1987 proofed by Stephen
- June 18, 1987 compiled
- revised with Turbo pascal version 4.0 Jan. 8, 1988 }
-
- PROGRAM CURVE;
- uses CRT, PRINTER, GRAPH;
- CONST BELL = #7;
-
- TYPE
- STR25 = STRING[25];
- CALC = ARRAY[1..4] OF REAL;
- MARK = ARRAY[1..14] OF STRING[20];
-
- VAR
- X,Y,Y1,Y2,X1,X2 : ARRAY[1..50] OF REAL;
- B, M, C : CALC;
- ENTRY, FLAG, POINT : INTEGER;
-
- PROCEDURE WAIT;
- VAR PAUSE : CHAR;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- READ(INPUT,PAUSE)
- END;
-
- {$I TOOLS.INC}
-
- PROCEDURE TITLE;
- BEGIN
- CLRSCR;
- WRITELN(' CURVE TURBO PASCAL IBM VERSION 2.0 ');
- WRITELN(' [C] 1/8/88 BY STEPHEN C. CALLENDER ');
- INVERSE;
- WRITE(' <+> MULTIPLE REGRESSION ON X,Y DATA <+> ');
- no_inverse; WRITELN;
- WRITELN(' DRAWS THE BEST LINE.');
- WRITELN; WRITELN;
- WRITELN(' FOUR FITS ARE AVAILABLE: ');
- WRITELN(' LINEAR : y = b + mx');
- WRITELN(' POWER : y = bx ^ m ');
- WRITELN(' LOGARITHMIC : y = b + b ln(x)');
- WRITELN(' EXPONENTIAL : y = b exp(mx) ');
- WRITELN;
- PAUSE
- END;
-
- PROCEDURE INITIALIZE;
- VAR
- N : INTEGER;
- BEGIN
- FOR N := 1 TO 4 DO
- BEGIN
- C[N] := 0; B[N] := 0; M[N] := 0
- END
- END;
-
- PROCEDURE LABELS(FFLAG : INTEGER; VAR BRAND : MARK);
- VAR NAME : MARK;
- BEGIN
- CASE FFLAG OF
- 1 : NAME[1] := ' LINEAR ';
- 2 : NAME[2] := ' POWER ';
- 3 : NAME[3] := ' LOGARITHMIC ';
- 4 : NAME[4] := ' EXPONENTIAL ';
- 5 : NAME[5] := ' DATA UNSUITED TO ';
- 6 : NAME[6] := ' DATA ERROR ';
- 7 : NAME[7] := ' COMPUTE ';
- END; { CASE }
- WRITELN(NAME[FFLAG])
- END;
-
- PROCEDURE SAVE;
- VAR N : INTEGER;
- FILER : TEXT;
- BEGIN
- WRITELN; WRITELN;
- INVERSE; WRITE('------SAVING TO THE DISK AS: ASSAY.TXT-----');
- NO_INVERSE;
- ASSIGN(FILER,'ASSAY.TXT');
- REWRITE(FILER);
- WRITELN(FILER,ENTRY);
- FOR N:= 1 TO ENTRY DO
- BEGIN
- WRITELN(FILER,X[N]);
- WRITELN(FILER,Y[N])
- END;
- CLOSE(FILER)
- END;
-
- PROCEDURE LOAD;
- VAR N : INTEGER;
- FILER : TEXT;
- BEGIN
- WRITELN;
- WRITELN; INVERSE;
- WRITE('-----LOADING THE FILE: ASSAY.TXT -----'); NO_INVERSE;
- ASSIGN(FILER,'ASSAY.TXT');
- RESET(FILER);
- READLN(FILER);
- FOR N := 1 TO ENTRY DO
- BEGIN
- READLN(FILER,X[N]);
- READLN(FILER,Y[N])
- END;
- CLOSE(FILER)
- END;
-
- PROCEDURE X_SINGLE_ENTRY;
- { X IS THE INDEX NO PAIRS }
- VAR N, IOCODE : INTEGER;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- N := 0; X[N] := 0; { JUNE 6, 1987 revision of former x index procedure }
- REPEAT { previous pascal procedure probably did not work }
- N := N + 1; { Version 1.43 Apple CP/M }
- WRITELN('N = ',N);
- WRITELN('X = ',X[N]:1:1);
- WRITELN; WRITE('Y = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- X[N] := X[N] + N;
- UNTIL N = ENTRY;
- POINT := 1
- END;
-
- PROCEDURE X_PAIRED_ENTRY;
- { X IS THE INDEX AND PAIRED NUMBERS }
- VAR N, IOCODE : INTEGER;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- N :=0; X[N] := 0; { this revision allows this procedure to work }
- REPEAT { unlike the original version from Basic }
- N := N + 1; { Integer and real numbers can not be mixed }
- WRITELN('N = ',N); { in Pascal }
- WRITELN('X = ',X[N]:1:1);
- WRITE('Y1 = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y1[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- WRITE('Y2 = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y2[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- Y[N] := (Y1[N] + Y2[N]) / 2;
- { DISPLAY VALUES }
- WRITELN('X = ',N); WRITELN;
- WRITELN('AVERAGE OF ',Y[N]:3:3,' & ',Y2[N]:3:3,' = ',Y[N]:3:3);
- X[N] := X[N] + 1;
- UNTIL N = ENTRY;
- POINT :=2
- END;
-
- PROCEDURE Y_SINGLE_ENTRY;
- VAR N, IOCODE : INTEGER;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- N := 0;
- REPEAT
- N := N + 1;
- WRITELN('N = ',N);
- WRITE('X = ? ');
- REPEAT
- {$I-} READLN(INPUT,X[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- WRITE('Y = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- WRITELN;
- UNTIL N = ENTRY;
- POINT :=3
- END;
-
- PROCEDURE Y_PAIRED_ENTRY;
- VAR N, IOCODE : INTEGER;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- N := 0;
- REPEAT
- N := N + 1;
- WRITELN('N = ',N);
- WRITE('X = ? ');
- REPEAT
- {$I-} READLN(INPUT,X[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- WRITE('Y1 = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y1[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- WRITE('Y2 = ? ');
- REPEAT
- {$I-} READLN(INPUT,Y2[N]);
- {$I+} IOCODE := IORESULT;
- IF IOCODE <> 0 THEN WRITELN('BAD INPUT! TRY 0.NUMBER ');
- UNTIL IOCODE = 0; WRITELN;
- Y[N] := (Y1[N] + Y2[N]) / 2;
- WRITELN(X[N]:3:3); WRITELN;
- WRITELN('average of ',Y1[N]:3:3,' & ',Y2[N]:3:3,' = ',Y[N]:3:3);
- UNTIL N = ENTRY;
- PAUSE;
- POINT :=4
- END;
-
- PROCEDURE DATA_ENTRY;
- VAR
- CHOICE : CHAR;
- BEGIN
- CLRSCR;
- INVERSE;
- WRITE('DATA ENTRY MODE');
- NO_INVERSE;
- WRITELN;
- WRITE('enter the number of data points for standard curve ');
- READLN(ENTRY);
- WRITELN('DATA POINT SELECTION: ');
- WRITELN('x (index) single points press < a > ' );
- WRITELN('x (index) paired points press < b > ' );
- WRITELN('y (index) single points press < c > ' );
- WRITELN('y (index) paired points press < d > ' );
- WRITELN;
- INVERSE;
- WRITE( 'CHOOSE YOUR SELECTION: ');
- NO_INVERSE;
- READLN(CHOICE);
- CASE CHOICE OF
- 'A','a' : X_SINGLE_ENTRY;
- 'B','b' : X_PAIRED_ENTRY;
- 'C','c' : Y_SINGLE_ENTRY;
- 'D','d' : Y_PAIRED_ENTRY;
- END; { CASE }
- save;
- END;
-
- PROCEDURE MENU;
- FORWARD;
-
- PROCEDURE EDIT_LIST;
- FORWARD;
-
- PROCEDURE EDIT_DATA;
- VAR N : INTEGER;
- CHOICE : CHAR;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- CLRSCR;
- INVERSE;
- WRITE('which data pair ? ');
- NO_INVERSE;
- READ(N);
- WRITELN;
- WRITELN(' DATA ',N,' PRESENTLY ');
- WRITELN;
- WRITELN('X = ',X[N]:3:3);
- WRITELN('Y = ',Y[N]:3:3); WRITELN;
- WRITELN('INPUT NEW DATA: ');
- IF (POINT = 1) OR (POINT = 2) THEN
- BEGIN
- WRITELN('X = ',N); WRITELN;
- WRITE('Y = ? ');
- READLN(INPUT,Y[N]); WRITELN
- END
- ELSE
- BEGIN
- WRITE('X = ? ');
- READLN(INPUT,X[N]);
- WRITELN;
- WRITE('Y = ? ');
- READLN(INPUT,Y[N]); WRITELN
- END;
- WRITELN;
- WRITE('press (return) = more or O = options ');
- READ(INPUT,CHOICE);
- IF CHOICE IN ['O','o'] THEN MENU
- ELSE EDIT_LIST
- END;
-
- PROCEDURE LIST_DATA;
- VAR N : INTEGER;
- BEGIN
- ASSIGN(OUTPUT,'');
- REWRITE(OUTPUT);
- CLRSCR;
- FOR N := 1 TO ENTRY DO BEGIN
- WRITELN(OUTPUT); WRITELN(OUTPUT,'# OF POINTS = ',ENTRY);
- WRITELN(OUTPUT,'N = ',N);
- WRITELN(OUTPUT); WRITELN(OUTPUT,'X = ',X[N]:3:3);
- WRITELN(OUTPUT,'Y = ',Y[N]:3:3);
- wait;
- PAUSE
- END
- END;
-
- PROCEDURE EDIT_LIST;
- VAR CHOOSE : CHAR;
- BEGIN
- ASSIGN(INPUT,'');
- RESET(INPUT);
- CLRSCR;
- WRITELN('do you wish to E)dit or L)ist data points of standard curve ');
- READ(INPUT,CHOOSE);
- CASE CHOOSE OF
- 'E','e' : EDIT_DATA;
- 'L','l' : LIST_DATA
- END
- END;
-
- {"passed in" flag for displaying the final results of the standard curve }
-
- PROCEDURE DISPLAY_CURVE(FFLAG : INTEGER);
- VAR
- NAME : MARK;
- BEGIN
- CLRSCR;
- WRITELN;
- LABELS(FFLAG,NAME); WRITELN;
- WRITELN('Y - INTERCEPT = ',B[FFLAG]:3:3); WRITELN;
- WRITELN('SLOPE = ',M[FFLAG]:3:3); WRITELN;
- WRITELN('CORR.COEFF = ',C[FFLAG]:3:3);
- PAUSE
- END;
-
- { new procedure works only under Turbo Pascal version 4.0 }
- PROCEDURE DISPLAY_GRAPH(FFLAG : INTEGER);
- VAR
- R, DRIVER, MODE, CODE : INTEGER;
- MX, MY : REAL;
- CX, CY ,XM, XN, YM, YN : REAL;
- XX, YY : ARRAY[1..20] OF REAL;
- XG, YG : ARRAY[1..20] OF integer;
- BEGIN
- CASE FFLAG OF
- 2 : BEGIN
- FOR R := 1 TO ENTRY DO BEGIN
- X[R] := Ln(X[R]);
- Y[R] := Ln(Y[R])
- END
- END;
- 3 : BEGIN
- FOR R := 1 TO ENTRY DO
- X[R] := Ln(X[R])
- END;
- 4 : BEGIN
- FOR R := 1 TO ENTRY DO
- Y[R] := Ln(Y[R])
- END
- END; { END OF CASE }
- { NORMALIZATION OF VARIABLES }
-
- XM := X[1];
- XN := X[1];
- YM := Y[1];
- YN := Y[1];
- FOR R := 2 TO ENTRY DO
- BEGIN
- IF XM < X[R] THEN XM := X[R];
- IF XN > X[R] THEN XN := X[R];
- IF YM < Y[R] THEN YM := Y[R];
- IF YN > Y[R] THEN YN := Y[R]
- END;
- CX := 275 / ((XM - XN) + 1);
- CY := 155 / ((YM - YN) + 1);
- FOR R := 1 TO ENTRY DO BEGIN
- XX[R] := X[R] * CX;
- YY[R] := Y[R] * CY
- END;
- MX := XX[1];
- MY := YY[1];
- FOR R := 2 TO ENTRY DO BEGIN
- IF MX > XX[R] THEN MX := XX[R];
- IF MY > YY[R] THEN MY := YY[R]
- END;
- MX := MX - 3;
- MY := MY - 3; { NEED INTEGERS FROM REAL NUMBERS FOR GRAPH }
- FOR R := 1 TO ENTRY DO BEGIN
- XG[R] := TRUNC(XX[R] - MX);
- YG[R] := TRUNC(YY[R] - MY)
- END;
- DRIVER := DETECT;
- INITGRAPH(DRIVER,MODE,'');
- CODE := GRAPHRESULT;
- IF CODE <> GROK THEN BEGIN
- WRITELN('------ NO GRAPHICS BOARD FOUND ! -------');
- WRITELN('-- YOUR PROGRAM HAS BEEN ABORTED -----');
- HALT(1)
- END; { DRAW X AND Y AXIS }
- line(0,0,0,190); { y axis }
- LINE(0,190,320,190); { x axis }
- FOR R := 1 TO ENTRY - 1 DO
- LINE(XG[R],(190-YG[R]),XG[R+1],(190-YG[R+1]));
- REPEAT
- OUTTEXTXY(0,320,'==== PRESS ANY KEY TO CONTINUE ========');
- UNTIL KEYPRESSED;
- CLOSEGRAPH
- END;
-
-
- PROCEDURE COMPUTE(FFLAG : INTEGER);
-
- VAR FLAG2, N, BEST : INTEGER;
- XX, YY, CC, XL, XY, YL, YS, XS : REAL;
- NAME : MARK;
- BEGIN
- INITIALIZE;
- XX := 0;
- XS := 0;
- YY := 0;
- CC := 0;
- XL := 0;
- XY := 0;
- YL := 0;
- YS := 0;
- CASE FFLAG OF
- 1 : BEGIN
- FOR N := 1 TO ENTRY DO
- BEGIN
- XX := XX + X[N];
- YY := YY + Y[N];
- XY := (XY + (X[N] * Y[N]));
- XS := XS + SQR(X[N]);
- YS := YS + SQR(Y[N]);
- END;
- { DEBUG; }
- M[1] := XY - ((XX * YY) / ENTRY);
- M[1] :=M[1] / (XS - (SQR(XX) / ENTRY));
- B[1] :=(YY / ENTRY) - (M[1] * (XX / ENTRY));
- C[1] :=SQR(XY - ((XX * YY) / ENTRY));
- C[1] :=C[1]/(XS-(SQR(XX)/ENTRY));
- C[1] :=C[1]/(YS - (SQR(YY)/ENTRY));
- { display the computation }
- DISPLAY_CURVE(1);
- WRITE(BELL)
- END;
-
- 2 : BEGIN
- FOR N := 1 TO ENTRY DO
- BEGIN
- XL :=LN(X[N]);
- YL :=LN(Y[N]);
- XX :=XX + XL;
- YY :=YY + YL;
- XY :=XY + (XL * YL);
- XS :=XS + SQR(XL);
- YS :=YS + SQR(YL)
- END;
- { debug; }
- M[2] := XY-(XX * YY/ENTRY);
- M[2] := M[2]/(XS-(SQR(XX)/ENTRY));
- B[2] := EXP((YY/ENTRY)-(M[2] * XX/ENTRY));
- C[2] := SQR(XY-(XX * YY/ENTRY));
- C[2] := C[2]/(XS-(SQR(XX)/ENTRY));
- C[2] := C[2]/(YS-(SQR(YY)/ENTRY));
- DISPLAY_CURVE(2);
- WRITE(BELL)
- END;
-
- 3 : BEGIN
- FOR N := 1 TO ENTRY DO
- BEGIN
- XL := LN(X[N]);
- YL := Y[N];
- XX := XX + XL;
- YY := YY + YL;
- XY := XY + (XL * YL);
- XS := XS + SQR(XL);
- YS := YS + SQR(YL)
- END;
- { debug; }
- M[3] := ((XY-(1/ENTRY)* XX * YY));
- M[3] := M[3] / (XS-((1/ENTRY) * SQR(XX) ));
- B[3] := (1/ENTRY) * (YY-(M[3] * XX));
- C[3] := SQR(XY-((1/ENTRY) * XX * YY));
- C[3] := C[3]/(XS-((1/ENTRY) * SQR(XX)));
- C[3] := C[3]/(YS-((1/ENTRY) * SQR(YY)));
- DISPLAY_CURVE(3);
- WRITE(BELL)
- END;
-
- 4 : BEGIN
- FOR N := 1 TO ENTRY DO
- BEGIN
- XL := X[N];
- YL := LN(Y[N]);
- XX := XX + XL;
- YY := YY + YL;
- XY := XY + (XL * YL);
- XS := XS + SQR(XL);
- YS := YS + SQR(YL)
- END;
- { debug; }
- M[4] := ((XY-((1/ENTRY) * XX * YY))/(XS-((1/ENTRY) * SQR(XX))));
- B[4] := EXP((YY/ENTRY)-(M[4] * (XX/ENTRY)));
- C[4] := SQR(XY-((1/ENTRY) * XX * YY));
- C[4] := C[4]/(XS-(SQR(XX)/ENTRY));
- C[4] := C[4]/(YS-(SQR(YY)/ENTRY));
- DISPLAY_CURVE(4);
- END;
-
- 5 : BEGIN
- FOR N := 1 TO 4 DO
- COMPUTE(N);
- if c[1] < c[2] then best := 2
- else best := 1;
- if c[3] < c[4] then best := 4
- else best := 3;
- writeln;
- compute(best);
- CLRSCR;
- display_curve(best);
- INVERSE; WRITE(' B E S T F I T '); NO_INVERSE;
- WRITELN;
- WRITE(BELL);
- PAUSE
- END;
- END; {CASE}
- READLN
- END; { procedure compute }
-
- {$I SAMPLE4.INC}
- {$I SAMPLE4B.INC}
- {$I PRINTOUT.INC}
-
- PROCEDURE MENU;
- VAR CHOICE, FIT : INTEGER;
- BEGIN
- CLRSCR;
- WRITELN(' options: '); WRITELN;
- WRITELN(' (1) compute linear curve');
- WRITELN(' (2) compute power curve');
- WRITELN(' (3) compute logarithmic curve');
- WRITELN(' (4) compute exponential curve');
- WRITELN(' (5) compute & find the best fit');
- WRITELN(' (6) LIST AND/OR EDIT DATA');
- WRITELN(' (7) ENTER DATA TABLE FOR STANDARD CURVE');
- WRITE(' (8) '); INVERSE;
- WRITE(' SAMPLES '); NO_INVERSE;
- WRITE(' FOR CALCULATIONS '); WRITELN;
- WRITELN(' (9) hardcopy of standard curve');
- WRITELN(' (10) load previous saved standard curve');
- WRITELN(' (11) display graph of standard curve');
- WRITELN(' (12) exit to the system'); WRITELN;
- INVERSE; WRITELN(' please make your selection: '); NO_INVERSE;
- READ(CHOICE);
- CASE CHOICE OF
- 1 : BEGIN
- COMPUTE(1);
- FLAG :=1;
- END;
- 2 : BEGIN
- COMPUTE(2);
- FLAG := 2
- END;
- 3 : BEGIN
- COMPUTE(3);
- FLAG := 3
- END;
- 4 : BEGIN
- COMPUTE(4);
- FLAG := 4
- END;
- 5 : COMPUTE(5);
- 6 : EDIT_LIST;
- 7 : DATA_ENTRY;
- 8 : SAMPLE_PREP(FIT);
- 9 : HARDCOPY;
- 10 : LOAD;
- 11 : DISPLAY_GRAPH(FLAG);
- 12 : HALT
- END; {CASE}
- MENU
- END;
-
- BEGIN
- TITLE;
- MENU
- END.
-
-
-