[BACK]Return to scaling.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Homotopy

Annotation of OpenXM_contrib/PHC/Ada/Homotopy/scaling.adb, Revision 1.1.1.1

1.1       maekawa     1: with Standard_Complex_Numbers;           use Standard_Complex_Numbers;
                      2: with Standard_Mathematical_Functions;    use Standard_Mathematical_Functions;
                      3: with Standard_Natural_Vectors;
                      4: with Standard_Complex_Matrices;          use Standard_Complex_Matrices;
                      5: with Standard_Complex_Linear_Solvers;    use Standard_Complex_Linear_Solvers;
                      6:
                      7: package body Scaling is
                      8:
                      9:   function log ( b : in natural; x : in double_float ) return double_float is
                     10:   begin
                     11:     return ( LOG10(x)/LOG10(double_float(b)) );
                     12:   end log;
                     13:
                     14:   procedure Scale ( p : in out Poly ) is
                     15:
                     16:     sum : double_float := 0.0;
                     17:     number : natural := 0;
                     18:     factor : Complex_Number;
                     19:
                     20:     procedure Add_To_Sum ( t : in Term; continue : out boolean ) is
                     21:     begin
                     22:       sum := sum + AbsVal(t.cf);
                     23:       number := number + 1;
                     24:       continue := true;
                     25:     end Add_To_Sum;
                     26:     procedure Compute_Sum is new Visiting_Iterator(Add_To_Sum);
                     27:
                     28:   begin
                     29:     Compute_Sum(p);
                     30:     factor := Create(double_float(number)/sum);
                     31:     Mul(p,factor);
                     32:   end Scale;
                     33:
                     34:   procedure Scale ( s : in out Poly_Sys ) is
                     35:   begin
                     36:     for i in s'range loop
                     37:       scale(s(i));
                     38:     end loop;
                     39:   end Scale;
                     40:
                     41:   procedure Scale ( s : in out Poly_Sys; bas : in natural := 2;
                     42:                     diff : in boolean; cond : out double_float;
                     43:                     sccff : out vector ) is
                     44:
                     45:     r1,r2,target : Poly;
                     46:     n : natural := s'last - s'first + 1;
                     47:     nm : natural := 2*n;
                     48:     mat : Matrix(1..nm,1..nm);
                     49:     right : Vector(1..nm);
                     50:
                     51:     function Center_Coefficients ( s : in Poly_Sys; bas : in natural )
                     52:                                  return Poly is
                     53:       r1,r1i : Poly;
                     54:       n : natural := s'last - s'first + 1;
                     55:
                     56:       procedure Scan ( p : in Poly; i : in natural ) is
                     57:
                     58:         init : Poly;
                     59:         t_init : Term;
                     60:
                     61:         procedure Scan_Term ( t : in Term; continue : out boolean ) is
                     62:
                     63:           tt : Term;
                     64:           temp : Poly;
                     65:
                     66:         begin
                     67:           Copy(init,temp);
                     68:           continue := true;
                     69:           for k in t.dg'range loop
                     70:             if t.dg(k) /= 0
                     71:              then tt.cf := Create(double_float(t.dg(k)));
                     72:                   tt.dg := new Standard_Natural_Vectors.Vector'(1..2*n => 0);
                     73:                   tt.dg(k) := 1;
                     74:                   Add(temp,tt);
                     75:                   Clear(tt);
                     76:             end if;
                     77:           end loop;
                     78:           tt.cf := Create(log(bas,AbsVal(t.cf)));
                     79:           tt.dg := new Standard_Natural_Vectors.Vector'(1..2*n => 0);
                     80:           Add(temp,tt);
                     81:           Clear(tt);
                     82:           Mul(temp,temp);
                     83:           Add(r1i,temp);
                     84:           Clear(temp);
                     85:         end Scan_Term;
                     86:         procedure Scan_Terms is new Visiting_Iterator(Scan_Term);
                     87:
                     88:       begin
                     89:         t_init.cf := Create(1.0);
                     90:         t_init.dg := new Standard_Natural_Vectors.Vector'(1..2*n => 0);
                     91:         t_init.dg(n+i) := 1;
                     92:         init := Create(t_init);
                     93:         Clear(t_init);
                     94:         Scan_Terms(p);
                     95:       end Scan;
                     96:
                     97:     begin
                     98:       r1 := Null_Poly;
                     99:       for i in s'range loop
                    100:         Scan(s(i),i);
                    101:         Add(r1,r1i);
                    102:         Clear(r1i);
                    103:       end loop;
                    104:       return r1;
                    105:     end Center_Coefficients;
                    106:
                    107:     function Reduce_Diff ( s : in Poly_Sys; bas : in natural ) return Poly is
                    108:
                    109:       r2,r2i : Poly;
                    110:
                    111:       procedure Scan2 (p : in Poly; t : in Term; nr : in natural) is
                    112:
                    113:         count : natural := 0;
                    114:
                    115:         procedure Scan2_Term (t2 : in Term; continue : out boolean) is
                    116:
                    117:           tt : Term;
                    118:           temp : Poly := Null_Poly;
                    119:
                    120:         begin
                    121:           continue := true;
                    122:           count := count + 1;
                    123:           if count > nr
                    124:            then
                    125:              for i in t2.dg'range loop
                    126:                if t.dg(i) /= t2.dg(i)
                    127:                 then tt.dg := new Standard_Natural_Vectors.Vector'(1..2*n => 0);
                    128:                      tt.dg(i) := 1;
                    129:                      tt.cf := Create(double_float(t.dg(i)-t2.dg(i)));
                    130:                      Add(temp,tt);
                    131:                      Clear(tt);
                    132:                end if;
                    133:              end loop;
                    134:           end if;
                    135:           tt.dg := new Standard_Natural_Vectors.Vector'(1..2*n => 0);
                    136:           tt.cf := Create(log(bas,(AbsVal(t.cf)/AbsVal(t2.cf))));
                    137:           Add(temp,tt);
                    138:           Clear(tt);
                    139:           Mul(temp,temp);
                    140:           Add(r2i,temp);
                    141:           Clear(temp);
                    142:         end Scan2_Term;
                    143:         procedure Scan2_Terms is new Visiting_Iterator(Scan2_Term);
                    144:
                    145:       begin
                    146:         Scan2_Terms(p);
                    147:       end Scan2;
                    148:
                    149:       procedure Scan ( p : in Poly ) is
                    150:
                    151:         nr : natural := 0;
                    152:
                    153:         procedure Scan_Term ( t : in Term; continue : out boolean ) is
                    154:         begin
                    155:           nr := nr + 1;
                    156:           continue := true;
                    157:           Scan2(p,t,nr);
                    158:         end Scan_Term;
                    159:         procedure Scan_Terms is new Visiting_Iterator(Scan_Term);
                    160:
                    161:       begin
                    162:         Scan_Terms(p);
                    163:       end Scan;
                    164:
                    165:     begin
                    166:       r2 := Null_Poly;
                    167:       for i in s'range loop
                    168:         Scan(s(i));
                    169:         Add(r1,r2i);
                    170:         Clear(r2i);
                    171:       end loop;
                    172:       return r2;
                    173:     end Reduce_Diff;
                    174:
                    175:     procedure Make_Linear_System ( r : in Poly; mat : out Matrix;
                    176:                                    right : out Vector ) is
                    177:       drj : Poly;
                    178:
                    179:       procedure Init_Linear_System ( m : out Matrix; r : out Vector ) is
                    180:       begin
                    181:         for i in m'range(1) loop
                    182:           r(i) := Create(0.0);
                    183:           for j in m'range(2) loop
                    184:             m(i,j) := Create(0.0);
                    185:           end loop;
                    186:         end loop;
                    187:       end Init_Linear_System;
                    188:
                    189:       procedure Scan ( p : in Poly; j : in natural ) is
                    190:
                    191:         procedure Scan_Term ( t : in Term; continue : out boolean ) is
                    192:         begin
                    193:           continue := true;
                    194:           for i in t.dg'range loop
                    195:             if t.dg(i) = 1
                    196:              then mat(j,i) := t.cf;
                    197:                   return;
                    198:             end if;
                    199:           end loop;
                    200:           right(j) := -t.cf;
                    201:         end Scan_Term;
                    202:         procedure Scan_Terms is new Visiting_Iterator (Scan_Term);
                    203:
                    204:       begin
                    205:         Scan_Terms(p);
                    206:       end Scan;
                    207:
                    208:     begin
                    209:       Init_Linear_System(mat,right);
                    210:       for j in 1..Number_Of_Unknowns(r) loop
                    211:         drj := Standard_Complex_Polynomials.Diff(r,j);
                    212:         Scan(drj,j);
                    213:       end loop;
                    214:     end Make_Linear_System;
                    215:
                    216:     procedure Scale ( s : in out Poly_Sys; bas : in natural;
                    217:                       mat : in out Matrix; right : in out Vector;
                    218:                       cond : out double_float ) is
                    219:
                    220:       n : natural := s'last - s'first + 1;
                    221:       ipvt : Standard_Natural_Vectors.Vector(1..2*n);
                    222:
                    223:       procedure Scale ( p : in out Poly; ip : in natural;
                    224:                         scalingcoeff : in Vector; bas : in natural ) is
                    225:
                    226:         procedure Scale_Term ( t : in out Term; continue : out boolean ) is
                    227:
                    228:           exp : double_float := 0.0;
                    229:
                    230:         begin
                    231:           exp := REAL_PART(scalingcoeff(n+ip));
                    232:           for k in t.dg'range loop
                    233:             exp := exp + double_float(t.dg(k))*REAL_PART(scalingcoeff(k));
                    234:           end loop;
                    235:           t.cf := t.cf * Create(double_float(bas) ** exp);
                    236:           continue := true;
                    237:         end Scale_Term;
                    238:         procedure Scale_Terms is new Changing_Iterator (Scale_Term);
                    239:
                    240:       begin
                    241:         Scale_Terms(p);
                    242:       end Scale;
                    243:
                    244:     begin
                    245:       lufco(mat,2*n,ipvt,cond);
                    246:       lusolve(mat,2*n,ipvt,right);
                    247:       for i in s'range loop
                    248:         Scale(s(i),i,right,bas);
                    249:       end loop;
                    250:     end Scale;
                    251:
                    252:   begin
                    253:     r1 := center_coefficients(s,bas);
                    254:     if diff
                    255:      then r2 := reduce_diff(s,bas);
                    256:           target := r1 + r2;
                    257:           clear(r1); clear(r2);
                    258:      else copy(r1,target); clear(r1);
                    259:     end if;
                    260:     Make_Linear_System(target,mat,right);
                    261:     clear(target);
                    262:     scale(s,bas,mat,right,cond);
                    263:     sccff := right;
                    264:   end Scale;
                    265:
                    266:   procedure Scale ( basis : in natural; sccff : in Vector;
                    267:                     s : in out Solution ) is
                    268:   begin
                    269:     for i in s.v'range loop
                    270:       s.v(i) := Create(double_float(basis)**REAL_PART(sccff(i))) * s.v(i);
                    271:     end loop;
                    272:   end Scale;
                    273:
                    274:   procedure Scale ( basis : in natural; sccff : in Vector;
                    275:                     sols : in out Solution_List ) is
                    276:   begin
                    277:     if Is_Null(sols)
                    278:      then null;
                    279:      else declare
                    280:             temp : Solution_List := sols;
                    281:             n : natural := Head_Of(sols).n;
                    282:             s : Solution(n);
                    283:             l : Link_To_Solution;
                    284:           begin
                    285:             while not Is_Null(temp) loop
                    286:               l := Head_Of(temp);
                    287:               s := l.all;
                    288:               Scale(basis,sccff,s);
                    289:               Clear(l);
                    290:               l := new Solution'(s);
                    291:               Set_Head(temp,l);
                    292:               temp := Tail_Of(temp);
                    293:             end loop;
                    294:           end;
                    295:     end if;
                    296:   end Scale;
                    297:
                    298: end Scaling;

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