Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Implift/binomial_system_solvers.adb, Revision 1.1.1.1
1.1 maekawa 1: with Standard_Complex_Numbers; use Standard_Complex_Numbers;
2: with Standard_Complex_Numbers_Polar; use Standard_Complex_Numbers_Polar;
3: with Standard_Integer_Vectors;
4: with Standard_Complex_Norms_Equals; use Standard_Complex_Norms_Equals;
5: with Transforming_Solutions; use Transforming_Solutions;
6:
7: package body Binomial_System_Solvers is
8:
9: -- AN INTERMEDIATE ROUTINE : --
10:
11: procedure Factorize ( v : in out VecVec; n : in natural;
12: t : in out Transfo ) is
13:
14: -- DESCRIPTION :
15: -- This routines factorizes the binomial system defined by the
16: -- degrees in the Vector v;
17:
18: -- ON ENTRY :
19: -- v defines the degrees of binomial system
20: -- n the number of unknowns to be eliminated
21:
22: -- ON RETURN :
23: -- v the factorized binomial system
24: -- t the transformations used to factorize
25:
26: tt : Transfo;
27: pivot : integer;
28: tmp : Standard_Integer_Vectors.Link_to_Vector;
29:
30: begin
31: t := Id(v'last);
32: for i in 1..n loop
33: pivot := 0; -- search for pivot
34: for j in i..v'last loop
35: if v(j)(i) /= 0
36: then pivot := j;
37: exit;
38: end if;
39: end loop;
40: if pivot /= 0 -- interchange if necessary
41: then if pivot /= i
42: then tmp := v(i);
43: v(i) := v(pivot);
44: v(pivot) := tmp;
45: end if;
46: tt := Rotate(v(i),i);
47: Apply(tt,v(i));
48: for j in (i+1)..v'last loop
49: Apply(tt,v(j));
50: v(j).all(i) := 0;
51: end loop;
52: Mult1(t,tt);
53: Clear(tt);
54: end if;
55: end loop;
56: end Factorize;
57:
58: -- AUXILIARY ROUTINES :
59:
60: procedure Update ( sols1,sols2 : in out Solution_List ) is
61:
62: tmp : Solution_List := sols2;
63: ls : Link_to_Solution;
64:
65: begin
66: while not Is_Null(tmp) loop
67: ls := Head_Of(tmp);
68: declare
69: nls : Link_to_Solution := new Solution'(ls.all);
70: begin
71: Construct(nls,sols1);
72: end;
73: tmp := Tail_Of(tmp);
74: end loop;
75: Clear(sols2);
76: end Update;
77:
78: procedure Solve ( v : in VecVec; cv : in Vector;
79: i,n : in natural; sols : in out Solution_List;
80: acc : in out Vector ) is
81:
82: t : Transfo;
83: pivot,d : integer;
84: a : Complex_Number;
85: c : Vector(cv'range) := cv;
86: rv : Vector(cv'range);
87: tmp : Standard_Integer_Vectors.Link_to_Vector;
88: nv : VecVec(v'range);
89: temp : array(v'range) of integer;
90: newsols : Solution_List;
91:
92: begin
93: for j in i..v'last loop
94: nv(j) := new Standard_Integer_Vectors.Vector'(v(j).all);
95: end loop;
96: pivot := 0; -- search for pivot
97: for j in i..v'last loop
98: if nv(j)(i) /= 0
99: then pivot := j;
100: exit;
101: end if;
102: end loop;
103: if pivot /= 0 -- interchange if necessary
104: then if pivot /= i
105: then tmp := nv(i);
106: nv(i) := nv(pivot);
107: nv(pivot) := tmp;
108: a := c(i);
109: c(i) := c(pivot);
110: c(pivot) := a;
111: end if;
112: t := Rotate(nv(i),i);
113: Apply(t,nv(i));
114: for j in (i+1)..nv'last loop
115: Apply(t,nv(j));
116: temp(j) := nv(j)(i);
117: nv(j)(i) := 0;
118: end loop;
119: d := nv(i)(i); -- compute the solutions
120: if d < 0
121: then d := -d;
122: rv(i) := Create(1.0)/c(i);
123: else rv(i) := c(i);
124: end if;
125: for j in 1..d loop
126: a := Root(rv(i),d,j);
127: acc(i) := a;
128: for k in (i+1)..nv'last loop
129: rv(k) := c(k)*a**(-temp(k));
130: end loop;
131: if i < n
132: then Solve(nv,rv,i+1,n,newsols,acc);
133: else declare -- i = n
134: ls : Link_to_Solution;
135: s : Solution(n);
136: begin
137: s.t := Create(0.0);
138: s.m := 1;
139: s.v := acc;
140: ls := new Solution'(s);
141: Construct(ls,newsols);
142: end;
143: end if;
144: Transform(t,newsols);
145: Update(sols,newsols);
146: end loop;
147: Clear(t);
148: end if;
149: for j in i..nv'last loop
150: Standard_Integer_Vectors.Clear(nv(j));
151: end loop;
152: end Solve;
153:
154: -- THE SOLVER :
155:
156: procedure Solve ( v : in VecVec; cv : in Vector;
157: n : in natural; sols : in out Solution_List ) is
158:
159: wv : VecVec(v'range); -- workspace
160: acc : Vector(cv'range); -- accumulator
161:
162: begin
163: for i in v'range loop
164: wv(i) := new Standard_Integer_Vectors.Vector'(v(i).all);
165: end loop;
166: Solve(wv,cv,v'first,v'last,sols,acc);
167: Clear(wv);
168: end Solve;
169:
170: -- COMPUTING THE RESIDUALS :
171:
172: procedure Residuals ( v : in VecVec; cv : in Vector;
173: n : in natural; sols : in Solution_List;
174: res : out Vector ) is
175: nb : natural;
176: x : Vector(cv'range);
177: tmp : Solution_List;
178:
179: function Eval ( v : VecVec; cv,x : Vector ) return Vector is
180:
181: -- DESCRIPTION :
182: -- Computes the value of the vector x in the system defined by
183: -- v and cv.
184:
185: y : Standard_Complex_Vectors.Vector(x'range);
186:
187: begin
188: for i in x'range loop
189: y(i) := Create(1.0);
190: for j in v(i)'range loop
191: y(i) := y(i)*x(j)**v(i)(j);
192: end loop;
193: y(i) := y(i) - cv(i);
194: end loop;
195: return y;
196: end Eval;
197:
198: begin
199: tmp := sols;
200: nb := 1;
201: while not Is_Null(tmp) loop
202: x := Head_Of(tmp).v;
203: res(nb) := Create(Max_Norm(Eval(v,cv,x)));
204: tmp := Tail_Of(tmp);
205: nb := nb + 1;
206: end loop;
207: end Residuals;
208:
209: end Binomial_System_Solvers;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>