-- svd.ada singular value decomposition -- from Wilkinson and Reinsch: "Handbook of Automatic Computation" with real_arrays; use real_arrays; with text_io; use text_io; procedure svd(AA : in real_matrix; QQ : in out real_vector; UU : in out real_matrix; VV : in out real_matrix ) is subtype real is float; A : real_matrix(0..AA'length(1)-1,0..AA'length(2)-1) := AA; U : real_matrix(A'range(1),A'range(2)); V : real_matrix(a'range(2),A'range(2)); -- V.ReDimension(n,n); eps : real := float'epsilon; tol : real := float'small/eps; m : integer := A'length(1); -- number of rows n : integer := A'length(2); -- number of columns g : real := 0.0; f : real := 0.0; h : real := 0.0; x : real := 0.0; s : real := 0.0; c : real := 0.0; j : integer; l : integer; i : integer; l1 : integer; E : real_vector(0..n-1); -- RowVector E(n) EI : real_vector(0..n-1); -- RectMatrixRow EI(E,0) Q : real_vector(0..n-1); -- Q.ReDimension(n) UCI : real_vector(0..n-1); -- RectMatrixCol UCI(U,0) UCJ : real_vector(0..n-1); -- RectMatrixCol UCJ := UCI; URI : real_vector(0..n-1); -- RectMatrixRow URI(U,0,1,n-1) URJ : real_vector(0..n-1); -- RectMatrixRow URJ := URI; VCI : real_vector(0..n-1); -- RectMatrixCol VCI(V,n,n,0); VCJ : real_vector(0..n-1); -- RectMatrixCol VCJ := VCI; z : real; y : real; sei : real; tfc : boolean; limit : integer; begin if m= no. Cols"); raise array_index_error; end if; U := A; for i in 0..n-1 loop EI.First() := g; sei := g; EI.Right(); s := UCI.SumSquare(); if s1.0 then g := f * sqrt(1 + square(1/f)); elsif f<-1.0 then g := -f * sqrt(1 + square(1/f)); else g := sqrt(f*f + 1); end if; f := ((x-z)*(x+z) + h*(y / ((f<0.0) ? f-g : f+g)-h)) / x; c := 1.0; s := 1.0; for i in l+1..k loop g := E.element(i); y := Q.element(i); h := s*g; g *:= c; z := pythag(f,h,c,s); E.element(i-1) := z; f := x*c + g*s; g := -x*s + g*c; h := y*s; y := y*c; RectMatrixCol VCI(V,i); RectMatrixCol VCJ(V,i-1); ComplexScale(VCI, VCJ, c, s); z := pythag(f,h,c,s); Q.element(i-1) := z; f := c*g + s*y; x := -s*g + c*y; RectMatrixCol UCI(U,i); RectMatrixCol UCJ(U,i-1); ComplexScale(UCI, UCJ, c, s); end loop; -- i E.element(l) := 0.0; E.element(k) := f; Q.element(k) := x; end loop; -- limit if l/=k then put_line("ConvergenceException(A)"); end if; -- convergence: if z<0.0 then Q.element(k) := -z; RectMatrixCol VCI(V,k); VCI.Negate(); end if; end loop; -- on k end svd; --static Real pythag(Real f, Real g, Real& c, Real& s) -- return z=sqrt(f*f+g*g), c=f/z, s=g/z -- set c=1,s=0 if z==0 -- avoid floating point overflow or divide by zero --{ -- if (f==0 && g==0) { c=1.0; s=0.0; return 0.0; } -- Real af = f>=0 ? f : -f; -- Real ag = g>=0 ? g : -g; -- if (ag