[BACK]Return to standard_complex_linear_solvers.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_linear_solvers.adb, Revision 1.1

1.1     ! maekawa     1: with Standard_Complex_Numbers;           use Standard_Complex_Numbers;
        !             2:
        !             3: package body Standard_Complex_Linear_Solvers is
        !             4:
        !             5: -- AUXLILIARIES :
        !             6:
        !             7:   function cabs ( c : Complex_Number ) return double_float is
        !             8:   begin
        !             9:     return (ABS(REAL_PART(c)) + ABS(IMAG_PART(c)));
        !            10:   end cabs;
        !            11:
        !            12:   function dconjg ( x : Complex_Number ) return Complex_Number is
        !            13:   begin
        !            14:     return Create(REAL_PART(x),-IMAG_PART(x));
        !            15:   end dconjg;
        !            16:
        !            17:   function csign ( x,y : Complex_Number ) return Complex_Number is
        !            18:   begin
        !            19:     return (Create(cabs(x)) * y / Create(cabs(y)));
        !            20:   end csign;
        !            21:
        !            22: -- TARGET ROUTINES :
        !            23:
        !            24:   procedure Scale ( a : in out Matrix; b : in out Vector ) is
        !            25:
        !            26:     fac : Complex_Number;
        !            27:
        !            28:     function Maximum ( a : in Matrix; i : in integer ) return Complex_Number is
        !            29:
        !            30:       res : integer := a'first(2);
        !            31:       max : double_float := cabs(a(i,res));
        !            32:       tmp : double_float;
        !            33:
        !            34:     begin
        !            35:       for j in a'first(2)+1..a'last(2) loop
        !            36:         tmp := cabs(a(i,j));
        !            37:         if tmp > max
        !            38:          then max := tmp; res := j;
        !            39:         end if;
        !            40:       end loop;
        !            41:       return a(i,res);
        !            42:     end Maximum;
        !            43:
        !            44:     procedure Divide ( a : in out Matrix; b : in out Vector;
        !            45:                        i : in integer; fac : in Complex_Number ) is
        !            46:     begin
        !            47:       for j in a'range(2) loop
        !            48:         a(i,j) := a(i,j)/fac;
        !            49:       end loop;
        !            50:       b(i) := b(i)/fac;
        !            51:     end Divide;
        !            52:
        !            53:   begin
        !            54:     for i in a'range(1) loop
        !            55:       fac := Maximum(a,i);
        !            56:       Divide(a,b,i,fac);
        !            57:     end loop;
        !            58:   end Scale;
        !            59:
        !            60: -- TARGET ROUTINES :
        !            61:
        !            62:   procedure lufac ( a : in out Matrix; n : in integer;
        !            63:                     ipvt : out Standard_Natural_Vectors.Vector;
        !            64:                     info : out natural ) is
        !            65:
        !            66:     kp1,l,nm1 : integer;
        !            67:     smax : double_float;
        !            68:     temp : Complex_Number;
        !            69:
        !            70:   begin
        !            71:     info := 0;
        !            72:     nm1 := n - 1;
        !            73:     if nm1 >= 1
        !            74:      then for k in 1..nm1 loop
        !            75:             kp1 := k + 1;
        !            76:
        !            77:           -- find the pivot index l
        !            78:
        !            79:             l := k; smax := cabs(a(k,k));  --modulus(a(k,k));
        !            80:             for i in kp1..n loop
        !            81:               if cabs(a(i,k)) > smax --modulus(a(i,k)) > smax
        !            82:                then l := i;
        !            83:                     smax := cabs(a(i,k)); --modulus(a(i,k));
        !            84:               end if;
        !            85:             end loop;
        !            86:             ipvt(k) := l;
        !            87:
        !            88:             if smax = 0.0
        !            89:              then -- this column is already triangularized
        !            90:                   info := k;
        !            91:              else
        !            92:
        !            93:                   -- interchange if necessary
        !            94:
        !            95:                   if l /= k
        !            96:                    then temp := a(l,k);
        !            97:                         a(l,k) := a(k,k);
        !            98:                         a(k,k) := temp;
        !            99:                   end if;
        !           100:
        !           101:                   -- compute multipliers
        !           102:
        !           103:                   temp := -Create(1.0)/a(k,k);
        !           104:                   for i in kp1..n loop
        !           105:                     a(i,k) := temp * a(i,k);
        !           106:                   end loop;
        !           107:
        !           108:                   -- row elimination with column indexing
        !           109:
        !           110:                   for j in kp1..n loop
        !           111:                     temp := a(l,j);
        !           112:                     if l /= k
        !           113:                      then a(l,j) := a(k,j);
        !           114:                           a(k,j) := temp;
        !           115:                     end if;
        !           116:                     for i in kp1..n loop
        !           117:                       a(i,j) := a(i,j) + temp * a(i,k);
        !           118:                     end loop;
        !           119:                   end loop;
        !           120:
        !           121:             end if;
        !           122:          end loop;
        !           123:     end if;
        !           124:     ipvt(n) := n;
        !           125:     if AbsVal(a(n,n)) = 0.0
        !           126:      then info := n;
        !           127:     end if;
        !           128:   end lufac;
        !           129:
        !           130:   procedure lufco ( a : in out Matrix; n : in integer;
        !           131:                     ipvt : out Standard_Natural_Vectors.Vector;
        !           132:                     rcond : out double_float ) is
        !           133:
        !           134:   -- NOTE :
        !           135:   --   rcond = 1/(norm(a)*(estimate of norm(inverse(a))))
        !           136:   --   estimate = norm(z)/norm(y) where a*z = y and ctrans(a)*y = e.
        !           137:   --   ctrans(a) is the conjugate transpose of a.
        !           138:   --   The components of e are chosen to cause maximum local
        !           139:   --   growth in teh elements of w where ctrans(u)*w = e.
        !           140:   --   The vectors are frequently rescaled to avoid overflow.
        !           141:
        !           142:     z : Standard_Complex_Vectors.Vector(1..n);
        !           143:     info,kb,kp1,l : integer;
        !           144:     s,sm,sum,anorm,ynorm : double_float;
        !           145:     ek,t,wk,wkm : Complex_Number;
        !           146:     ipvtt : Standard_Natural_Vectors.Vector(1..n);
        !           147:
        !           148:   begin
        !           149:     anorm := 0.0;                                    -- compute 1-norm of a
        !           150:     for j in 1..n loop
        !           151:       sum := 0.0;
        !           152:       for i in 1..n loop
        !           153:         sum := sum + cabs(a(i,j));
        !           154:       end loop;
        !           155:       if sum > anorm
        !           156:        then anorm := sum;
        !           157:       end if;
        !           158:     end loop;
        !           159:     lufac(a,n,ipvtt,info);                                        -- factor
        !           160:     for i in 1..n loop
        !           161:       ipvt(i) := ipvtt(i);
        !           162:     end loop;
        !           163:     ek := Create(1.0);                              -- solve ctrans(u)*w = e
        !           164:     for j in 1..n loop
        !           165:       z(j) := Create(0.0);
        !           166:     end loop;
        !           167:     for k in 1..n loop
        !           168:       if cabs(z(k)) /= 0.0
        !           169:        then ek := csign(ek,-z(k));
        !           170:       end if;
        !           171:       if cabs(ek-z(k)) > cabs(a(k,k))
        !           172:        then s := cabs(a(k,k))/cabs(ek-z(k));
        !           173:             z := Create(s) * z;
        !           174:             ek := Create(s) * ek;
        !           175:       end if;
        !           176:       wk := ek - z(k);
        !           177:       wkm := -ek - z(k);
        !           178:       s := cabs(wk);
        !           179:       sm := cabs(wkm);
        !           180:       if cabs(a(k,k)) = 0.0
        !           181:        then wk := Create(1.0);
        !           182:             wkm := Create(1.0);
        !           183:        else wk := wk / dconjg(a(k,k));
        !           184:             wkm := wkm / dconjg(a(k,k));
        !           185:       end if;
        !           186:       kp1 := k + 1;
        !           187:        if kp1 <= n
        !           188:         then for j in kp1..n loop
        !           189:                sm := sm + cabs(z(j)+wkm*dconjg(a(k,j)));
        !           190:                z(j) := z(j) + wk*dconjg(a(k,j));
        !           191:                s := s + cabs(z(j));
        !           192:              end loop;
        !           193:              if s < sm
        !           194:               then t := wkm - wk;
        !           195:                    wk := wkm;
        !           196:                    for j in kp1..n loop
        !           197:                      z(j) := z(j) + t*dconjg(a(k,j));
        !           198:                    end loop;
        !           199:              end if;
        !           200:        end if;
        !           201:        z(k) := wk;
        !           202:      end loop;
        !           203:      sum := 0.0;
        !           204:      for i in 1..n loop
        !           205:        sum := sum + cabs(z(i));
        !           206:      end loop;
        !           207:      s := 1.0 / sum;
        !           208:      z := Create(s) * z;
        !           209:      for k in 1..n loop                           -- solve ctrans(l)*y = w
        !           210:        kb := n+1-k;
        !           211:        if kb < n
        !           212:         then t := Create(0.0);
        !           213:              for i in (kb+1)..n loop
        !           214:                t := t + dconjg(a(i,kb))*z(i);
        !           215:              end loop;
        !           216:              z(kb) := z(kb) + t;
        !           217:        end if;
        !           218:        if cabs(z(kb)) > 1.0
        !           219:         then s := 1.0 / cabs(z(kb));
        !           220:              z := Create(s) * z;
        !           221:        end if;
        !           222:        l := ipvtt(kb);
        !           223:        t := z(l);
        !           224:        z(l) := z(kb);
        !           225:        z(kb)  := t;
        !           226:      end loop;
        !           227:      sum := 0.0;
        !           228:      for i in 1..n loop
        !           229:        sum := sum + cabs(z(i));
        !           230:      end loop;
        !           231:      s := 1.0 / sum;
        !           232:      z := Create(s) * z;
        !           233:      ynorm := 1.0;
        !           234:      for k in 1..n loop                                    -- solve l*v = y
        !           235:        l := ipvtt(k);
        !           236:        t := z(l);
        !           237:        z(l) := z(k);
        !           238:        z(k) := t;
        !           239:        if k < n
        !           240:         then for i in (k+1)..n loop
        !           241:                z(i) := z(i) + t * a(i,k);
        !           242:              end loop;
        !           243:        end if;
        !           244:        if cabs(z(k)) > 1.0
        !           245:         then s := 1.0 / cabs(z(k));
        !           246:              z := Create(s) * z;
        !           247:              ynorm := s * ynorm;
        !           248:        end if;
        !           249:      end loop;
        !           250:      sum := 0.0;
        !           251:      for i in 1..n loop
        !           252:        sum := sum + cabs(z(i));
        !           253:      end loop;
        !           254:      s := 1.0 / sum;
        !           255:      z := Create(s) * z;
        !           256:      ynorm := s * ynorm;
        !           257:      for k in 1..n loop                                    -- solve u*z = v
        !           258:        kb := n+1-k;
        !           259:        if cabs(z(kb)) > cabs(a(kb,kb))
        !           260:         then s := cabs(a(kb,kb)) / cabs(z(kb));
        !           261:              z := Create(s) * z;
        !           262:              ynorm := s * ynorm;
        !           263:        end if;
        !           264:        if cabs(a(kb,kb)) = 0.0
        !           265:         then z(kb) := Create(1.0);
        !           266:         else z(kb) := z(kb) / a(kb,kb);
        !           267:        end if;
        !           268:        t := -z(kb);
        !           269:        for i in 1..(kb-1) loop
        !           270:          z(i) := z(i) + t * a(i,kb);
        !           271:        end loop;
        !           272:      end loop;
        !           273:      sum := 0.0;                                       -- make znorm = 1.0
        !           274:      for i in 1..n loop
        !           275:        sum := sum + cabs(z(i));
        !           276:      end loop;
        !           277:      s := 1.0 / sum;
        !           278:      z := Create(s) * z;
        !           279:      ynorm := s * ynorm;
        !           280:      if anorm = 0.0
        !           281:       then rcond := 0.0;
        !           282:       else rcond := ynorm/anorm;
        !           283:      end if;
        !           284:   end lufco;
        !           285:
        !           286:   procedure lusolve ( a : in Matrix; n : in integer;
        !           287:                       ipvt : in Standard_Natural_Vectors.Vector;
        !           288:                       b : in out Vector ) is
        !           289:
        !           290:     l,nm1,kb : integer;
        !           291:     temp : Complex_Number;
        !           292:
        !           293:   begin
        !           294:     nm1 := n-1;
        !           295:     if nm1 >= 1                                             -- solve l*y = b
        !           296:      then for k in 1..nm1 loop
        !           297:             l := ipvt(k);
        !           298:             temp := b(l);
        !           299:             if l /= k
        !           300:              then b(l) := b(k);
        !           301:                   b(k) := temp;
        !           302:             end if;
        !           303:             for i in (k+1)..n loop
        !           304:               b(i) := b(i) + temp * a(i,k);
        !           305:             end loop;
        !           306:           end loop;
        !           307:     end if;
        !           308:     for k in 1..n loop                                     -- solve u*x = y
        !           309:       kb := n+1-k;
        !           310:       b(kb) := b(kb) / a(kb,kb);
        !           311:       temp := -b(kb);
        !           312:       for j in 1..(kb-1) loop
        !           313:         b(j) := b(j) + temp * a(j,kb);
        !           314:       end loop;
        !           315:     end loop;
        !           316:   end lusolve;
        !           317:
        !           318:   procedure Triangulate ( a : in out Matrix; n,m : in integer ) is
        !           319:
        !           320:     max,cbs : double_float;
        !           321:     temp : Complex_Number;
        !           322:     pivot,k,kcolumn : integer;
        !           323:     tol : constant double_float := 10.0**(-10);
        !           324:
        !           325:   begin
        !           326:     k := 1;
        !           327:     kcolumn := 1;
        !           328:     while (k <= n) and (kcolumn <= m) loop
        !           329:       max := 0.0;                                             -- find pivot
        !           330:       pivot := 0;
        !           331:       for l in k..n loop
        !           332:         cbs := cabs(a(l,kcolumn));
        !           333:         if (cbs > tol) and then (cbs > max)
        !           334:          then max := cbs;
        !           335:               pivot := l;
        !           336:         end if;
        !           337:       end loop;
        !           338:       if pivot = 0
        !           339:        then kcolumn := kcolumn + 1;
        !           340:        else if pivot /= k                       -- interchange if necessary
        !           341:              then for i in 1..m loop
        !           342:                     temp := a(pivot,i);
        !           343:                     a(pivot,i) := a(k,i);
        !           344:                     a(k,i) := temp;
        !           345:                   end loop;
        !           346:             end if;
        !           347:             for j in (kcolumn+1)..m loop                   -- triangulate a
        !           348:               a(k,j) := a(k,j) / a(k,kcolumn);
        !           349:             end loop;
        !           350:             a(k,kcolumn) := Create(1.0);
        !           351:             for i in (k+1)..n loop
        !           352:               for j in (kcolumn+1)..m loop
        !           353:                 a(i,j) := a(i,j) - a(i,kcolumn) * a(k,j);
        !           354:               end loop;
        !           355:               a(i,kcolumn) := Create(0.0);
        !           356:             end loop;
        !           357:             k := k + 1;
        !           358:             kcolumn := kcolumn + 1;
        !           359:       end if;
        !           360:     end loop;
        !           361:   end Triangulate;
        !           362:
        !           363:   procedure Diagonalize ( a : in out Matrix; n,m : in integer ) is
        !           364:
        !           365:     max : double_float;
        !           366:     temp : Complex_Number;
        !           367:     pivot,k,kcolumn : integer;
        !           368:
        !           369:   begin
        !           370:     k := 1;
        !           371:     kcolumn := 1;
        !           372:     while (k <= n) and (kcolumn <= m) loop
        !           373:       max := 0.0;                                               -- find pivot
        !           374:       for l in k..n loop
        !           375:         if cabs(a(l,kcolumn)) > max
        !           376:          then max := cabs(a(l,kcolumn));
        !           377:               pivot := l;
        !           378:         end if;
        !           379:       end loop;
        !           380:       if max = 0.0
        !           381:        then kcolumn := kcolumn + 1;
        !           382:        else if pivot /= k                        -- interchange if necessary
        !           383:              then for i in 1..m loop
        !           384:                     temp := a(pivot,i);
        !           385:                     a(pivot,i) := a(k,i);
        !           386:                     a(k,i) := temp;
        !           387:                   end loop;
        !           388:             end if;
        !           389:             for j in (kcolumn+1)..m loop                    -- diagonalize a
        !           390:               a(k,j) := a(k,j) / a(k,kcolumn);
        !           391:             end loop;
        !           392:             a(k,kcolumn) := Create(1.0);
        !           393:             for i in 1..(k-1) loop
        !           394:               for j in (kcolumn+1)..m loop
        !           395:                 a(i,j) := a(i,j) - a(i,kcolumn) * a(k,j);
        !           396:               end loop;
        !           397:             end loop;
        !           398:             for i in (k+1)..n loop
        !           399:               for j in (kcolumn+1)..m loop
        !           400:                 a(i,j) := a(i,j) - a(i,kcolumn) * a(k,j);
        !           401:               end loop;
        !           402:             end loop;
        !           403:             for j in 1..(k-1) loop
        !           404:               a(j,kcolumn) := Create(0.0);
        !           405:             end loop;
        !           406:             for j in (k+1)..n loop
        !           407:               a(j,kcolumn) := Create(0.0);
        !           408:             end loop;
        !           409:             k := k + 1;
        !           410:             kcolumn := kcolumn + 1;
        !           411:       end if;
        !           412:     end loop;
        !           413:   end Diagonalize;
        !           414:
        !           415: end Standard_Complex_Linear_Solvers;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>