Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Matrices/standard_floating_qr_decomposition.adb, Revision 1.1
1.1 ! maekawa 1: with Standard_Floating_Numbers; use Standard_Floating_Numbers;
! 2: with Standard_Mathematical_Functions; use Standard_Mathematical_Functions;
! 3:
! 4: package body Standard_Floating_QR_Decomposition is
! 5:
! 6: -- AUXILIARIES :
! 7:
! 8: function min0 ( a,b : integer ) return integer is
! 9:
! 10: -- DESCRIPTION : returns the minimum of a and b.
! 11:
! 12: begin
! 13: if a <= b
! 14: then return a;
! 15: else return b;
! 16: end if;
! 17: end min0;
! 18:
! 19: function dmax1 ( a,b : double_float ) return double_float is
! 20:
! 21: -- DESCRIPTION : returns the maximum of a and b.
! 22:
! 23: begin
! 24: if a >= b
! 25: then return a;
! 26: else return b;
! 27: end if;
! 28: end dmax1;
! 29:
! 30: function dsign ( a,b : double_float ) return double_float is
! 31:
! 32: -- DESCRIPTION : returns the absolute value of a, set to the same sign as b.
! 33:
! 34: begin
! 35: if b >= 0.0
! 36: then return abs(a);
! 37: else return -abs(a);
! 38: end if;
! 39: end dsign;
! 40:
! 41: procedure dswap ( a : in out Standard_Floating_Matrices.Matrix;
! 42: k1,k2 : in natural ) is
! 43:
! 44: -- DESCRIPTION :
! 45: -- Swaps the columns k1 and k2 in the matrix a.
! 46:
! 47: tmp : double_float;
! 48:
! 49: begin
! 50: for i in a'range(1) loop
! 51: tmp := a(i,k1); a(i,k1) := a(i,k2); a(i,k2) := tmp;
! 52: end loop;
! 53: end dswap;
! 54:
! 55: function dnrm2 ( a : Standard_Floating_Matrices.Matrix; row,col : natural )
! 56: return double_float is
! 57:
! 58: -- DESCRIPTION :
! 59: -- Computes the 2-norm of the vector in the column col of the matrix,
! 60: -- starting at the given row.
! 61:
! 62: sum : double_float := 0.0;
! 63:
! 64: begin
! 65: for i in row..a'last(1) loop
! 66: sum := sum + a(i,col)*a(i,col);
! 67: end loop;
! 68: return SQRT(sum);
! 69: end dnrm2;
! 70:
! 71: function ddot ( a : Standard_Floating_Matrices.Matrix; row,k1,k2 : natural )
! 72: return double_float is
! 73:
! 74: -- DESCRIPTION :
! 75: -- Returns the inner product of the vectors in the columns k1 and k2,
! 76: -- starting at the given row.
! 77:
! 78: res : double_float := 0.0;
! 79:
! 80: begin
! 81: for i in row..a'last(1) loop
! 82: res := res + a(i,k1)*a(i,k2);
! 83: end loop;
! 84: return res;
! 85: end ddot;
! 86:
! 87: procedure daxpy ( a : in out Standard_Floating_Matrices.Matrix;
! 88: f : in double_float; row,k1,k2 : in integer ) is
! 89:
! 90: -- DESCRIPTION :
! 91: -- The column k2 is added with f times the column k1, starting at row.
! 92:
! 93: begin
! 94: for i in row..a'last(1) loop
! 95: a(i,k2) := a(i,k2) + f*a(i,k1);
! 96: end loop;
! 97: end daxpy;
! 98:
! 99: procedure dscal ( a : in out Standard_Floating_Matrices.Matrix;
! 100: f : in double_float; row,col : in integer ) is
! 101:
! 102: -- DESCRIPTION :
! 103: -- Multiplies the column col of the matrix with f, starting at row.
! 104:
! 105: begin
! 106: for i in row..a'last(1) loop
! 107: a(i,col) := f*a(i,col);
! 108: end loop;
! 109: end dscal;
! 110:
! 111: procedure QRD ( x : in out Standard_Floating_Matrices.Matrix;
! 112: qraux : in out Standard_Floating_Vectors.Vector;
! 113: jpvt : in out Standard_Natural_Vectors.Vector;
! 114: piv : in boolean ) is
! 115:
! 116: n : constant natural := x'length(1); -- number of rows
! 117: p : constant natural := x'length(2); -- number of columns
! 118: work : Standard_Floating_Vectors.Vector(x'range(2));
! 119: jj,jp,lp1,lup,maxj,pl,pu : integer;
! 120: maxnrm,tt,nrmxl,t : double_float;
! 121: negj,swapj : boolean;
! 122:
! 123: begin
! 124: pl := 1; pu := 0;
! 125: if piv
! 126: then for j in x'range(2) loop -- rearrange columns according to jpvt
! 127: swapj := (jpvt(j) > 0);
! 128: negj := (jpvt(j) < 0);
! 129: jpvt(j) := j;
! 130: if negj
! 131: then jpvt(j) := -j;
! 132: end if;
! 133: if (swapj and then (j /= pl))
! 134: then dswap(x,pl,j);
! 135: jpvt(j) := jpvt(pl);
! 136: jpvt(pl) := j;
! 137: pl := pl + 1;
! 138: end if;
! 139: end loop;
! 140: pu := p;
! 141: for j in 1..p loop
! 142: jj := p - j + 1;
! 143: if jpvt(jj) < 0
! 144: then jpvt(jj) := -jpvt(jj);
! 145: if jj /= pu
! 146: then dswap(x,pu,jj);
! 147: jp := jpvt(pu);
! 148: jpvt(pu) := jpvt(jj);
! 149: jpvt(jj) := jp;
! 150: end if;
! 151: pu := pu - 1;
! 152: end if;
! 153: end loop;
! 154: end if;
! 155: for j in pl..pu loop -- compute norms of the free columns
! 156: qraux(j) := dnrm2(x,1,j);
! 157: work(j) := qraux(j);
! 158: end loop;
! 159: lup := min0(n,p); -- perform the householder reduction of x
! 160: for l in 1..lup loop
! 161: if (l >= pl and l < pu)
! 162: then maxnrm := 0.0; -- locate column with largest norm and
! 163: maxj := l; -- bring it in the pivot position
! 164: for j in l..pu loop
! 165: if qraux(j) > maxnrm
! 166: then maxnrm := qraux(j);
! 167: maxj := j;
! 168: end if;
! 169: end loop;
! 170: if maxj /= l
! 171: then dswap(x,l,maxj);
! 172: qraux(maxj) := qraux(l);
! 173: work(maxj) := work(l);
! 174: jp := jpvt(maxj);
! 175: jpvt(maxj) := jpvt(l);
! 176: jpvt(l) := jp;
! 177: end if;
! 178: end if;
! 179: qraux(l) := 0.0;
! 180: if l /= n
! 181: then nrmxl := dnrm2(x,l,l); -- householder transformation for column l
! 182: if nrmxl /= 0.0
! 183: then if x(l,l) /= 0.0
! 184: then nrmxl := dsign(nrmxl,x(l,l));
! 185: end if;
! 186: dscal(x,1.0/nrmxl,l,l);
! 187: x(l,l) := 1.0 + x(l,l);
! 188: lp1 := l + 1; -- apply the transformation to the remaining
! 189: for j in lp1..p loop -- columns, updating the norms
! 190: t := -ddot(x,l,l,j)/x(l,l);
! 191: daxpy(x,t,l,l,j);
! 192: if (j >= pl) and (j <= pu) and (qraux(j) /= 0.0)
! 193: then tt := 1.0 - (abs(x(l,j))/qraux(j))**2;
! 194: tt := dmax1(tt,0.0);
! 195: t := tt;
! 196: tt := 1.0 + 0.05*tt*(qraux(j)/work(j))**2;
! 197: if tt /= 1.0
! 198: then qraux(j) := qraux(j)*SQRT(t);
! 199: else qraux(j) := dnrm2(x,l+1,j);
! 200: work(j) := qraux(j);
! 201: end if;
! 202: end if;
! 203: end loop;
! 204: qraux(l) := x(l,l); -- save the transformation
! 205: x(l,l) := -nrmxl;
! 206: end if;
! 207: end if;
! 208: end loop;
! 209: end QRD;
! 210:
! 211: procedure Permute_Columns ( x : in out Standard_Floating_Matrices.Matrix;
! 212: jpvt : in Standard_Natural_Vectors.Vector ) is
! 213:
! 214: res : Standard_Floating_Matrices.Matrix(x'range(1),x'range(2));
! 215:
! 216: begin
! 217: for k in jpvt'range loop
! 218: for i in res'range(1) loop
! 219: res(i,k) := x(i,jpvt(k));
! 220: end loop;
! 221: end loop;
! 222: x := res;
! 223: end Permute_Columns;
! 224:
! 225: procedure Permute ( x : in out Standard_Floating_Vectors.Vector;
! 226: jpvt : in Standard_Natural_Vectors.Vector ) is
! 227:
! 228: res : Standard_Floating_Vectors.Vector(x'range);
! 229:
! 230: begin
! 231: for k in jpvt'range loop
! 232: res(k) := x(jpvt(k));
! 233: end loop;
! 234: x := res;
! 235: end Permute;
! 236:
! 237: procedure Basis ( qr : in out Standard_Floating_Matrices.Matrix;
! 238: x : in Standard_Floating_Matrices.Matrix ) is
! 239:
! 240: sum : double_float;
! 241: wrk : Standard_Floating_Vectors.Vector(qr'range(2));
! 242:
! 243: begin
! 244: for j in x'range(2) loop -- compute jth column of q
! 245: for i in qr'range(1) loop
! 246: sum := x(i,j);
! 247: for k in qr'first(2)..(j-1) loop
! 248: sum := sum - qr(i,k)*qr(k,j);
! 249: end loop;
! 250: wrk(i) := sum/qr(j,j);
! 251: end loop;
! 252: for i in qr'range(1) loop
! 253: qr(i,j) := wrk(i);
! 254: end loop;
! 255: end loop;
! 256: end Basis;
! 257:
! 258: end Standard_Floating_QR_Decomposition;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>