unit TestLsqPoly;
 
{$I _crw_sysdef}

{$IFDEF FPC}{$mode Delphi}{$ENDIF}{$H+}

interface
 
uses
 _crw_sharemem, // NB: THIS UNIT MUST BE FIRST !!!
 {$IFDEF UNIX} cthreads, dl, {$ENDIF}
 {$IFDEF WINDOWS} windows, {$ENDIF}
 sysutils, classes, math,
 _crw_alloc, _crw_fpu, _crw_zm, _crw_lsqpoly;

procedure Test_LsqPoly;

implementation

const
 n = 1000;
 eps = 1e-12;
 errors : integer = 0;
var
 x,y,w,y1,y2 : array[0..n-1] of double;

procedure Test_LsqPoly;
var i:integer; p,pw:TPolynom;
 procedure Testing(msg:shortstring; pow:Integer; cen,sca:double);
 var i:integer; e,e1,e2,ew,ew1,ew2,sw:double;
 begin
  p:=NewPolynom(pow,cen,sca); 
  pw:=NewPolynomCopy(p); 
  if not p.Find(x,y,n) then writeln('Error in find.');
  if not pw.FindWeight(x,y,w,n) then writeln('Error in findweight.');
  e:=0; e1:=0; e2:=0; ew:=0; ew1:=0; ew2:=0; sw:=0;
  for i:=0 to n-1 do begin
   e:=e+sqr(p.get(x[i])-y[i]);
   e1:=e1+sqr(p.get(x[i],1)-y1[i]);
   e2:=e2+sqr(p.get(x[i],2)-y2[i]);
   ew:=ew+sqr(pw.get(x[i])-y[i])*abs(w[i]);
   ew1:=ew1+sqr(pw.get(x[i],1)-y1[i])*abs(w[i]);
   ew2:=ew2+sqr(pw.get(x[i],2)-y2[i])*abs(w[i]);
   sw:=sw+abs(w[i]);
  end;
  e:=sqrt(e/n);
  e1:=sqrt(e1/n);
  e2:=sqrt(e2/n);
  ew:=sqrt(ew/sw);
  ew1:=sqrt(ew1/sw);
  ew2:=sqrt(ew2/sw);
  inc(errors,ord(e>eps));
  inc(errors,ord(e1>eps));
  inc(errors,ord(e2>eps));
  inc(errors,ord(ew>eps));
  inc(errors,ord(ew1>eps));
  inc(errors,ord(ew2>eps));
  writeln;
  writeln;
  writeln;
  writeln('Test:',msg:25,' p=',p.power:2,' c=',p.center:11:4,' s=',p.scale:11:4);
  writeln('e  =',e);
  writeln('ew =',ew);
  writeln('e1  =',e1);
  writeln('ew1 =',ew1);
  writeln('e2  =',e2);
  writeln('ew2 =',ew2);
  for i:=0 to p.power do writeln('c[',i,']=',p[i]);
  writeln('Errors found: ',errors);
  writeln;
  writeln;
  //write('Press enter...');readln;
  //writeln;
  Kill(p);
  Kill(pw);
 end;
begin
 errors:=0;
 writeln('Test of LsqPoly unit start.');
 {}
 for i:=0 to n-1 do begin
  x[i]:=(random-0.5)*2*10;
  y[i]:=pi;
  y1[i]:=0;
  y2[i]:=0;
  w[i]:=1;
 end;
 Testing('y=pi,w=1',0,0,1);
 {}
 for i:=0 to n-1 do begin
  x[i]:=(random-0.5)*2*10;
  y[i]:=pi+3*x[i];
  y1[i]:=3;
  y2[i]:=0;
  w[i]:=1;
 end;
 Testing('y=pi+3*x, w=1',1,1,2);
 {}
 for i:=0 to n-1 do begin
  x[i]:=(random-0.5)*2*10;
  y[i]:=pi+3*x[i]+1.5*sqr(x[i]);
  y1[i]:=3+2*1.5*x[i];
  y2[i]:=2*1.5;
  w[i]:=1;
 end;
 Testing('y=pi+3*x+1.5*x^2, w=1',2,0,1);
 {}
 for i:=0 to n-1 do begin
  x[i]:=(random-0.5)*2*10;
  y[i]:=pi+3*x[i]+1.5*sqr(x[i]);
  y1[i]:=3+2*1.5*x[i];
  y2[i]:=2*1.5;
  w[i]:=x[i];
 end;
 Testing('y=pi+3*x+1.5*x^2, w=x',2,0,1);
 {}
 writeln('Test of LsqPoly unit done.');
end;

end.
