{$S+ } program least1; { --> 191 } { Pascal Program to perform a liner least-squares fit using a parabolic } { curve. Aeperate procedure PLOT needed } const maxr = 20; maxc = 3; type ary = array[1..maxr] of real; arys = array[1..maxc] of real; ary2s = array[1..maxc,1..maxc] of real; var x,y,y_calc : ary; coef : arys; nrow,ncol : integer; correl_coef : real; external procedure cls; procedure get_data(var x,y: ary; var nrow: integer); { get values for n and arrays x,y } var i : integer; begin nrow:=9; writeln; for i:=1 to nrow do x[i]:=i; y[1]:=2.07; y[2]:=8.6; y[3]:=14.42; y[4]:=15.8; y[5]:=18.92; y[6]:=17.96; y[7]:=12.98; y[8]:=6.45; y[9]:=0.27; end; { procedure get_data } procedure write_data; { print out the answers } var i : integer; begin writeln; writeln(' I X Y YCALC'); for i:=1 to nrow do writeln(i:3,x[i]:8:1,y[i]:9:2,y_calc[i]:9:2); writeln; writeln(' Coefficients '); for i:=1 to ncol do writeln(coef[i]:8:4); writeln; writeln('Correlation coefficient is ',correl_coef:8:5) end; { write_data } procedure solve(a: ary2s; y: arys; var coef: arys; nrow: integer; var error: boolean); var b : ary2s; i,j : integer; det : real; function deter(a: ary2s): real; { calculate the determinant of a 3-by-3matrix } begin deter:=a[1,1]*(a[2,2]*a[3,3]-a[3,2]*a[2,3]) -a[1,2]*(a[2,1]*a[3,3]-a[3,1]*a[2,3]) +a[1,3]*(a[2,1]*a[3,2]-a[3,1]*a[2,2]) end; procedure setup(var b : ary2s; var coef: arys; j : integer); var i : integer; begin { setup } for i:=1 to nrow do begin b[i,j]:=y[i]; if j>1 then b[i,j-1]:=a[i,j-1] end; coef[j]:=deter(b)/det end; { setup } begin { procedure solve } error:=false; for i:=1 to nrow do for j:=1 to nrow do b[i,j]:=a[i,j]; det:=deter(b); if det=0.0 then begin error:=true; writeln(chr(7),'ERROR: matrix is singular') end else begin setup(b,coef,1); setup(b,coef,2); setup(b,coef,3) end { esle } end; { procedure solve } procedure linfit(x,y: ary; var y_calc: ary; var coef: arys; nrow: integer; var ncol: integer); { least squares fit to a parabola } { nrow sets of x and y pair points } var a : ary2s; g : arys; i : integer; error : boolean; sum_x,sum_y,sum_xy,sum_x2, sum_y2,xi,yi,sxy,syy, sxx,sum_x3,sum_x4,sum_2y, denom,srs,x2 : real; begin { linfit } ncol:=3; { polynomial terms } sum_x:=0.0; sum_y:=0.0; sum_xy:=0.0; sum_x2:=0.0; sum_y2:=0.0; sum_x3:=0.0; sum_x4:=0.0; sum_2y:=0.0; for i:=1 to nrow do begin xi:=x[i]; yi:=y[i]; x2:=xi*xi; sum_x:=sum_x+xi; sum_y:=sum_y+yi; sum_xy:=sum_xy+xi*yi; sum_x2:=sum_x2+x2; sum_y2:=sum_y2+yi*yi; sum_x3:=sum_x3+xi*x2; sum_x4:=sum_x4+x2*x2; sum_2y:=sum_2y+x2*yi end; a[1,1]:=nrow; a[2,1]:=sum_x; a[1,2]:=sum_x; a[3,1]:=sum_x2; a[1,3]:=sum_x2; a[2,2]:=sum_x2; a[3,2]:=sum_x3; a[2,3]:=sum_x3; a[3,3]:=sum_x4; g[1]:=sum_y; g[2]:=sum_xy; g[3]:=sum_2y; solve(a,g,coef,ncol,error); srs:=0.0; for i:=1 to nrow do begin y_calc[i]:=coef[1]+coef[2]*x[i]+coef[3]*sqr(x[i]); srs:=srs+sqr(y[i]-y_calc[i]) end; correl_coef:=sqrt(1.0-srs/(sum_y2-sqr(sum_y)/nrow)) end; { linfit } { external procedure plot(x,y,y_calc: ary; nrow: integer); } {$I C:PLOT.LIB } { get ptocedure PLOT } begin { MAIN program } cls; get_data(x,y,nrow); linfit(x,y,y_calc,coef,nrow,ncol); write_data; plot(x,y,y_calc,nrow) end. { MAIN }