(*------------------------------------------------------------------------------
     :Program.    Statistik.mod
     :Contents.   Berechnet eine Statistik von x/y Werten
     :Author.     Matthias Scherrer
     :Address.    Baselstrasse 63, CH-4242 Laufen
     :Phone.      ++(0)61/7613975
     :Copyright.  PD
     :Language.   Oberon
     :Translator. Oberon V3.00d
     :History.    V1.0,01-Dec-92  fuer Oberon 2.14d
     :History.    V1.1,29-Dec-92  angepasst an Oberon V3.00d
------------------------------------------------------------------------------*)
MODULE Statistik;

IMPORT ml : MATHLIB;

TYPE  stat* = RECORD
            n*      : INTEGER;    (* Anzahl Werte *)
            Ex*,Ey*,              (* Summe x,y *)
            maxx*,minx*,          (* Groesstes/kleinstes x/y *)  
            maxy*,miny*,
            Ex2*,Ey2*,            (* Summe x^2,y^2 *)
            Exy*,                 (* Summe x*y *)
            mx*, my*,             (* Mittelwert *)
            sx*,sy*,              (* Streuung x,y *)
            b*,c*,                (* lin.Regression y=b*x+c *)
            sb*,sc*,              (* Streuung b,c *)
            r*      : LONGREAL;   (* Korrelationskoeffizient *)
      END;


PROCEDURE Summe(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR i   : INTEGER;
    a,b : LONGREAL;
BEGIN
  i:=0; 
  x.Ex:=0; x.Ey:=0; x.Ex2:=0; x.Ey2:=0; x.Exy:=0;
  REPEAT 
    a:=d[i,0]; b:=d[i,1];
    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;
    INC(i);
  UNTIL i>x.n;
END Summe;


PROCEDURE Mittelwert(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR i : INTEGER;
BEGIN
  i:=0; x.mx:=0; x.my:=0;
  REPEAT
    x.mx:=x.mx+d[i,0];
    x.my:=x.my+d[i,1];
    INC(i);
  UNTIL i>x.n;
  IF (x.n+1)#0 THEN x.mx:=x.mx/(x.n+1); x.my:=x.my/(x.n+1); 
               ELSE HALT(20) END;
END Mittelwert;


PROCEDURE MaxMin(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR i         : INTEGER;
    xmin,xmax,
    ymin,ymax : LONGREAL;
BEGIN
  i:=0; 
  xmin:=d[i,0]; xmax:=xmin; 
  ymin:=d[i,1]; ymax:=ymin; 
  REPEAT
    IF d[i,0] > xmax THEN xmax:=d[i,0] END; 
    IF d[i,0] < xmin THEN xmin:=d[i,0] END;
    IF d[i,1] > ymax THEN ymax:=d[i,1] END; 
    IF d[i,1] < ymin THEN ymin:=d[i,1] END;
    INC(i);
  UNTIL i>x.n;
  x.maxx:= xmax; x.minx:=xmin;
  x.maxy:= ymax; x.miny:=ymin;
END MaxMin;


PROCEDURE Streuung(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR i : INTEGER;
BEGIN
  i:=0; 
  REPEAT
    x.sx:=x.sx+(d[i,0]-x.mx)*(d[i,0]-x.mx);
    x.sy:=x.sy+(d[i,1]-x.my)*(d[i,1]-x.my);
    INC(i);
  UNTIL i>x.n;
  IF x.n#0 THEN x.sx:=ml.SQRT(x.sx/x.n); x.sy:=ml.SQRT(x.sy/x.n); 
           ELSE HALT(20) END;
END Streuung;


PROCEDURE LinReg(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR i     : INTEGER;
    n,z   : LONGREAL;
BEGIN
  n:=0; z:=0; i:=0;
  REPEAT
    z:=z+(d[i,0]-x.mx)*(d[i,1]-x.my);
    n:=n+(d[i,0]-x.mx)*(d[i,0]-x.mx);
    INC(i);
  UNTIL i>x.n;
  IF n#0 THEN x.b:=z/n; x.c:=x.my-x.b*x.mx ELSE HALT(20) END;
END LinReg;


PROCEDURE LinRegS(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR t1,t2,t3,t4 : LONGREAL;
    i           : INTEGER;
BEGIN
  i:=0; t1:=0; t2:=0; t4:=0;
  REPEAT
    t1:=t1+(d[i,1]-x.my)*(d[i,1]-x.my);
    t2:=t2+(d[i,0]-x.mx)*(d[i,0]-x.mx);
    t4:=t4+d[i,0]*d[i,0];
    INC(i);
  UNTIL i>x.n;
  t3:=(x.n-1)*t2;
  IF t3#0 THEN x.sb:=ml.SQRT((t1-x.b*x.b*t2)/t3) ELSE HALT(20) END;
  IF (x.n+1)#0 THEN x.sc:=ml.SQRT(x.sb*x.sb*t4/(x.n+1)) ELSE HALT(20) END;
END LinRegS;


PROCEDURE KorrelKoeff(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
VAR t1,t2,t3 : LONGREAL;
    i        : INTEGER;
BEGIN
  i:=0; t1:=0; t2:=0; t3:=0;
  REPEAT
    t1:=t1+(d[i,0]-x.mx)*(d[i,1]-x.my);
    t2:=t2+(d[i,0]-x.mx)*(d[i,0]-x.mx);
    t3:=t3+(d[i,1]-x.my)*(d[i,1]-x.my);
    INC(i);
  UNTIL i>x.n;
  x.r:=t1/ml.SQRT(t2*t3);
  IF x.r<0 THEN x.r:=-x.r END;
END KorrelKoeff;


PROCEDURE DoStat*(VAR x: stat; d: ARRAY OF ARRAY OF LONGREAL);
BEGIN
  Mittelwert(x,d);  (* MUSS zuerst aufgerufen werden! *)
  Summe(x,d);       
  MaxMin(x,d);
  Streuung(x,d);
  LinReg(x,d);      (* Lineare Regression *)
  LinRegS(x,d);     (* Streuung d. linearen Regression *)
  KorrelKoeff(x,d); (* Korrelationskoeffizient *)
END DoStat;


END Statistik.
