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