Annotation of OpenXM_contrib/PHC/Ada/Homotopy/scaling.adb, Revision 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>