ð#Syntax10.Scn.FntææMODULE Stat; (* :Program. Stat.Mod :Contents. calculates statistics of x/y values :Author. Matthias Scherrer :Address. Baselstrasse 63, CH-4242 Laufen :Copyright. PD :Language. Oberon :Translator. Oberon V3.00d :History. V1.0, 01-Dec-92 for Oberon 2.14d :History. V1.1, 29-Dec-92 adapted to Oberon V3.00d :History. fixed x.n + 1 error in Mean - gh, Sept 1999 Adapted to Oberon V4 by Ulf Dittmer (ucdittme@top.cis.syr.edu). Also now graceful error reporting and some minor changes. *) IMPORT MathL; TYPE stat* = RECORD n* : INTEGER; (* number of values *) Ex*, Ey*, (* sum of x, y *) maxx*, minx*, (* smallest/biggest x/y *) maxy*, miny*, Ex2*, Ey2*, (* sum of x^2, y^2 *) Exy*, (* sum of x*y *) mx*, my*, (* mean value *) sx*, sy*, (* standard deviation *) b*, c*, (* linear regression y=b*x+c *) sb*, sc*, (* variance b,c *) r* : LONGREAL; (* correlation coefficient *) error* : BOOLEAN; (* flag for (un)successful calculation *) END; PROCEDURE Sum(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate Ex, Ey, Ex2, Ey2, Exy *) VAR i : INTEGER; a, b : LONGREAL; BEGIN x.Ex:=0; x.Ey:=0; x.Ex2:=0; x.Ey2:=0; x.Exy:=0; FOR i:=0 TO x.n-1 DO a:=d0[i]; b:=d1[i]; x.Ex:=x.Ex+a; x.Ey:=x.Ey+b; x.Ex2:=x.Ex2+a*a; x.Ey2:=x.Ey2+b*b; x.Exy:=x.Exy+a*b; END END Sum; PROCEDURE Mean(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate mx, my *) VAR i : INTEGER; BEGIN x.mx:=0; x.my:=0; FOR i:=0 TO x.n-1 DO x.mx:=x.mx+d0[i]; x.my:=x.my+d1[i]; END; IF (x.n # 0) THEN x.mx:=x.mx/(x.n); x.my:=x.my/(x.n); ELSE x.error := TRUE END; END Mean; PROCEDURE MaxMin(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate maxx, maxy, minx, miny *) VAR i : INTEGER; xmin, xmax, ymin, ymax : LONGREAL; BEGIN xmin:=d0[0]; xmax:=xmin; ymin:=d1[0]; ymax:=ymin; FOR i:=0 TO x.n-1 DO IF d0[i] > xmax THEN xmax:=d0[i] END; IF d0[i] < xmin THEN xmin:=d0[i] END; IF d1[i] > ymax THEN ymax:=d1[i] END; IF d1[i] < ymin THEN ymin:=d1[i] END; END; x.maxx:= xmax; x.minx:=xmin; x.maxy:= ymax; x.miny:=ymin; END MaxMin; PROCEDURE Variance(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate sx, sy *) VAR i : INTEGER; BEGIN FOR i:=0 TO x.n-1 DO x.sx:=x.sx+(d0[i]-x.mx)*(d0[i]-x.mx); x.sy:=x.sy+(d1[i]-x.my)*(d1[i]-x.my); END; IF (x.n # 0) THEN x.sx:=MathL.sqrt(x.sx/x.n); x.sy:=MathL.sqrt(x.sy/x.n); ELSE x.error := TRUE END; END Variance; PROCEDURE LinReg(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate b, c *) VAR i : INTEGER; n, z : LONGREAL; BEGIN n:=0; z:=0; FOR i:=0 TO x.n-1 DO z:=z+(d0[i]-x.mx)*(d1[i]-x.my); n:=n+(d0[i]-x.mx)*(d0[i]-x.mx); END; IF (n # 0) THEN x.b:=z/n; x.c:=x.my-x.b*x.mx ELSE x.error := TRUE END; END LinReg; PROCEDURE LinRegS(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate sb, sc *) VAR t1,t2,t3,t4 : LONGREAL; i : INTEGER; BEGIN t1:=0; t2:=0; t4:=0; FOR i:=0 TO x.n-1 DO t1:=t1+(d1[i]-x.my)*(d1[i]-x.my); t2:=t2+(d0[i]-x.mx)*(d0[i]-x.mx); t4:=t4+d0[i]*d0[i]; END; t3:=(x.n-1)*t2; IF (t3 # 0) THEN x.sb:=MathL.sqrt((t1-x.b*x.b*t2)/t3) ELSE x.error := TRUE END; IF (x.n + 1 # 0) THEN x.sc:=MathL.sqrt(x.sb*x.sb*t4/(x.n+1)) ELSE x.error := TRUE END; END LinRegS; PROCEDURE CorrelCoeff(VAR x : stat; d0, d1 : ARRAY OF LONGREAL); (* calculate r *) VAR t1,t2,t3 : LONGREAL; i : INTEGER; BEGIN t1:=0; t2:=0; t3:=0; FOR i:=0 TO x.n-1 DO t1:=t1+(d0[i]-x.mx)*(d1[i]-x.my); t2:=t2+(d0[i]-x.mx)*(d0[i]-x.mx); t3:=t3+(d1[i]-x.my)*(d1[i]-x.my); END; x.r := ABS(t1/MathL.sqrt(t2*t3)); END CorrelCoeff; PROCEDURE DoStat* (VAR x : stat; d0, d1 : ARRAY OF LONGREAL); BEGIN x.error := FALSE; Mean(x,d0,d1); (* must be called first *) Sum(x,d0,d1); MaxMin(x,d0,d1); Variance(x,d0,d1); LinReg(x,d0,d1); (* linear regression *) LinRegS(x,d0,d1); (* variance of linear regression *) CorrelCoeff(x,d0,d1); (* correlation coefficient *) END DoStat; END Stat.