unit TestSvd;

interface

{$I _crw_sysdef}

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

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

procedure Test_Svd;

implementation

procedure Test_svd;
const M=5; N=3; NA=10; NU=7; NV=9;
var
 A,iA,U,V,RV1,W,X,Y:array[0..100] of double;
 i,j:integer;
 SVD:TSVD;
begin
 writeln('************** Start _svd unit test ******************************');

 { create test matrix }
 for i:=0 to M-1 do for j:=0 to N-1 do A[i*NA+j]:=i+1+j*M;

 writeln('SVD Test');
 if SingularDecomposition(A,U,W,V,RV1,M,N,NA,NU,NV,true,true) then begin
  writeln('W=');
  for i:=0 to N-1 do write(' ',W[i]:8:5);
  writeln;
  writeln('U=');
  for i:=0 to M-1 do begin
   for j:=0 to N-1 do begin
    write(' ',U[i*NU+j]:8:5);
   end;
   writeln;
  end;
  writeln('V=');
  for i:=0 to N-1 do begin
   for j:=0 to N-1 do begin
    write(' ',V[i*NV+j]:8:5);
   end;
   writeln;
  end;
 end else writeln('SVD error');
 //readln;

 writeln('TSVD test');
 SVD:=TSVD.Create(A,M,N,NA);
 if SVD.Ok then with SVD do begin
  writeln('W=');
  for i:=0 to N-1 do write(' ',W[i]:8:5);
  writeln;
  writeln('U=');
  for i:=0 to M-1 do begin
   for j:=0 to N-1 do begin
    write(' ',U[i*N+j]:8:5);
   end;
   writeln;
  end;
  writeln('V=');
  for i:=0 to N-1 do begin
   for j:=0 to N-1 do begin
    write(' ',V[i*N+j]:8:5);
   end;
   writeln;
  end;
  writeln('Rank=',Rank(0));
  Y[0]:=5; Y[1]:=5; Y[2]:=5; Y[3]:=5; Y[4]:=5;
  writeln('TSVD.Solve test');
  if SVD.Solve(X,Y,1e-8) then begin
   for i:=0 to N-1 do write(X[i]:8:5,' ');
   writeln;
  end else writeln('TSVD.Solve error');
 end else writeln('TSVD error');
 Kill(SVD);
 //readln;

 Y[0]:=5; Y[1]:=5; Y[2]:=5; Y[3]:=5; Y[4]:=5;
 writeln('LS_Solve test');
 if SVD_Solve(M,N,NA,A,X,Y,0,0) then begin
  for i:=0 to N-1 do writeln(X[i]:8:5);
 end else writeln('LS_Solve error');

 writeln('PInvert test');
 if SVD_PInvert(M,N,NA,M,A,iA,0,0) then begin
  for i:=0 to N-1 do begin
   for j:=0 to M-1 do write(iA[i*M+j]:8:5,' ');
   writeln;
  end;
 end else writeln('PInvert Error');

 writeln('************** Stop _svd unit test ******************************');
end;

end.
