[BACK]Return to standard_complex_qr_decomposition.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Math_Lib / Matrices

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>