\ ***************************************************************************** \ \ L I N R E G \ \ Program: LINREG \ \ Programmer: Dr. David G. Simpson \ Department of Physical Science \ Prince George's Community College \ Largo, Maryland 20774 \ \ Date: February 3, 2002 \ \ Language: Forth \ \ Description: The word LINREG defined here performs a linear regression \ analysis for a set of data given as (X,Y) pairs. The output \ from the word is the slope and y-intercept of the least- \ squares best fit straight line through the data points. \ \ Note: ANS Standard Forth program labeling: \ \ ANS Forth Program \ Requiring PAD from the Core-Extensions word set \ Requiring the Floating-Point word set \ Requiring FS. FSQRT F~ from the Floating-Point Extensions word set \ \ ***************************************************************************** \ Constant declarations -9999.0E0 FCONSTANT END-VALUE \ x value to end data input loop 1.0E-8 FCONSTANT TOLERANCE \ floating-point comparison tolerance \ Variable declarations FVARIABLE X \ input x value FVARIABLE Y \ input y value FVARIABLE N \ number of input data points FVARIABLE SUMX \ sum of x values FVARIABLE SUMX2 \ sum of squares of x values FVARIABLE SUMXY \ sum of xy products FVARIABLE SUMY \ sum of y values FVARIABLE SUMY2 \ sum of squares of y values \ Print introductory message : PRINT-INTRO ( -- ) CR CR ." LINREG - Perform linear regression" CR ." Enter X=-9999 to stop data entry and compute linear regression." ; \ Initialize sums to zero : INIT-SUMS ( -- ) 0.0E0 N F! 0.0E0 SUMX F! 0.0E0 SUMX2 F! 0.0E0 SUMXY F! 0.0E0 SUMY F! 0.0E0 SUMY2 F! ; \ Input (x,y) data : GET-DATA ( -- ) BEGIN \ start of data input loop CR CR \ print spaces ." Enter X: " \ prompt to enter X PAD 50 ACCEPT \ read X string into PAD PAD SWAP >FLOAT X F! DROP \ convert to float and store in X X F@ END-VALUE TOLERANCE F~ 0= \ if equal to end value, exit loop WHILE \ while X not equal to end value.. CR \ start new line ." Enter Y: " \ prompt to enter Y value PAD 50 ACCEPT \ read Y string into PAD PAD SWAP >FLOAT Y F! DROP \ convert to float and store in Y N F@ 1.0E0 F+ N F! \ increment N by 1 SUMX F@ X F@ F+ SUMX F! \ add X to sum of X SUMX2 F@ X F@ FDUP F* F+ SUMX2 F! \ add X**2 to sum of X**2 SUMXY F@ X F@ Y F@ F* F+ SUMXY F! \ add XY to sum of XY SUMY F@ Y F@ F+ SUMY F! \ add Y to sum of Y SUMY2 F@ Y F@ FDUP F* F+ SUMY2 F! \ add Y**2 to sum of Y**2 REPEAT \ end of data input loop ; \ Compute slope of line m and leave on stack : COMPUTE-SLOPE ( -- m ) N F@ SUMXY F@ F* SUMX F@ SUMY F@ F* F- N F@ SUMX2 F@ F* SUMX F@ FDUP F* F- F/ ; \ Compute y-intercept and leave on stack : COMPUTE-INTERCEPT ( -- b ) SUMY F@ SUMX2 F@ F* SUMX F@ SUMXY F@ F* F- N F@ SUMX2 F@ F* SUMX F@ FDUP F* F- F/ ; \ Compute correlation coefficient and leave on stack : COMPUTE-CORRELATION ( -- r ) SUMXY F@ SUMX F@ SUMY F@ F* N F@ F/ F- SUMX2 F@ SUMX F@ FDUP F* N F@ F/ F- SUMY2 F@ SUMY F@ FDUP F* N F@ F/ F- F* FSQRT F/ ; \ Compute and display results : COMPUTE-RESULTS ( -- ) CR CR ." Slope m = " COMPUTE-SLOPE FS. CR ." y-intercept b = " COMPUTE-INTERCEPT FS. CR ." Correlation r = " COMPUTE-CORRELATION FS. CR CR ; \ LINREG (main word) - compute linear regression : LINREG ( -- ) DECIMAL \ make sure base is decimal PRINT-INTRO \ print intro message INIT-SUMS \ initialize sums to 0 GET-DATA \ get (x,y) data and accumulate sums COMPUTE-RESULTS \ compute and display results ;