Annotation of OpenXM_contrib/PHC/Ada/Continuation/multprec_root_refiners.adb, Revision 1.1.1.1
1.1 maekawa 1: with integer_io; use integer_io;
2: with Standard_Floating_Numbers; use Standard_Floating_Numbers;
3: with Multprec_Floating_Numbers_io; use Multprec_Floating_Numbers_io;
4: with Multprec_Complex_Numbers; use Multprec_Complex_Numbers;
5: with Multprec_Complex_Numbers_io; use Multprec_Complex_Numbers_io;
6: with Multprec_Complex_Vectors; use Multprec_Complex_Vectors;
7: with Standard_Natural_Vectors;
8: with Multprec_Complex_Matrices; use Multprec_Complex_Matrices;
9: with Multprec_Complex_Linear_Solvers; use Multprec_Complex_Linear_Solvers;
10: with Multprec_Complex_Norms_Equals; use Multprec_Complex_Norms_Equals;
11: with Multprec_Complex_Solutions_io; use Multprec_Complex_Solutions_io;
12:
13: package body Multprec_Root_Refiners is
14:
15: -- AUXILIARIES :
16:
17: function Is_Real ( sol : Solution; tol : Floating_Number ) return boolean is
18:
19: res : boolean := true;
20:
21: begin
22: for i in sol.v'range loop
23: declare
24: abstmp : Floating_Number := AbsVal(IMAG_PART(sol.v(i)));
25: begin
26: if abstmp > tol
27: then res := false;
28: end if;
29: Clear(abstmp);
30: end;
31: exit when not res;
32: end loop;
33: return res;
34: end Is_Real;
35:
36: function Equal ( s1,s2 : Solution; tol : Floating_Number ) return boolean is
37: begin
38: for i in s1.v'range loop
39: if not Equal(s1.v(i),s2.v(i),tol)
40: then return false;
41: end if;
42: end loop;
43: return true;
44: end Equal;
45:
46: function Complex_Conjugate ( s : Solution ) return Solution is
47:
48: res : Solution(s.n) := s;
49:
50: begin
51: for i in res.v'range loop
52: res.v(i) := Create(REAL_PART(s.v(i)),-IMAG_PART(s.v(i)));
53: end loop;
54: return res;
55: end Complex_Conjugate;
56:
57: function Is_Clustered ( sol : Solution; nb : natural; sols : Solution_List;
58: tol : Floating_Number ) return natural is
59:
60: tmp : Solution_List := sols;
61: cnt : natural := 0;
62:
63: begin
64: while not Is_Null(tmp) loop
65: cnt := cnt + 1;
66: if cnt /= nb
67: then if Equal(sol,Head_Of(tmp).all,tol)
68: then return cnt;
69: end if;
70: end if;
71: tmp := Tail_Of(tmp);
72: end loop;
73: return nb;
74: end Is_Clustered;
75:
76: function Is_Clustered ( sol : Solution; nb : natural; sols : Solution_Array;
77: tol : Floating_Number ) return natural is
78: begin
79: for i in sols'range loop
80: if i /= nb
81: then if Equal(sol,sols(i).all,tol)
82: then return i;
83: end if;
84: end if;
85: end loop;
86: return nb;
87: end Is_Clustered;
88:
89: function Multiplicity ( sol : Solution; sols : Solution_List;
90: tol : Floating_Number ) return natural is
91:
92: tmp : Solution_List := sols;
93: cnt : natural := 0;
94:
95: begin
96: while not Is_Null(tmp) loop
97: if Equal(sol,Head_Of(tmp).all,tol)
98: then cnt := cnt + 1;
99: end if;
100: tmp := Tail_Of(tmp);
101: end loop;
102: return cnt;
103: end Multiplicity;
104:
105: function Multiplicity ( sol : Solution; sols : Solution_Array;
106: tol : Floating_Number ) return natural is
107: cnt : natural := 0;
108:
109: begin
110: for i in sols'range loop
111: if Equal(sol,sols(i).all,tol)
112: then cnt := cnt + 1;
113: end if;
114: end loop;
115: return cnt;
116: end Multiplicity;
117:
118: procedure Write_Bar ( file : in file_type ) is
119: begin
120: for i in 1..75 loop
121: put(file,'=');
122: end loop;
123: new_line(file);
124: end Write_Bar;
125:
126: procedure Write_Info ( file : in file_type; zero : in Solution;
127: i,n,numb : in natural; fail : in boolean ) is
128:
129: -- DESCRIPTION :
130: -- The information concerning the zero is written
131:
132: begin
133: -- Write_Bar(file);
134: put(file,"solution "); put(file,i,1); put(file," : ");
135: put(file," start residual : "); put(file,zero.res,3); new_line(file);
136: put(file,zero);
137: end Write_Info;
138:
139: procedure Root_Accounting
140: ( file : in file_type; ls : in out Link_to_Solution;
141: nb : in natural; sa : in out Solution_Array;
142: fail : in boolean; tolsing,tolclus : in Floating_Number;
143: nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus : in out natural ) is
144:
145: -- DESCRIPTION :
146: -- This procedure does root accounting of the solution sol, w.r.t. the
147: -- solution list sols. Information will be provided concerning the type
148: -- of solution.
149:
150: tolreal : Floating_Number := Create(10.0**(-13));
151:
152: begin
153: if fail
154: then put_line(file," no solution ==");
155: nbfail := nbfail + 1;
156: ls.m := 0;
157: else if Is_Real(ls.all,tolreal)
158: then put(file," real ");
159: nbreal := nbreal + 1;
160: else put(file," complex ");
161: nbcomp := nbcomp + 1;
162: end if;
163: if sa(nb).rco < tolsing
164: then declare
165: m : natural := Multiplicity(ls.all,sa,tolclus);
166: begin
167: if m = 1
168: then m := 0;
169: end if;
170: ls.m := m;
171: end;
172: put_line(file,"singular ==");
173: nbsing := nbsing + 1;
174: else declare
175: nb2 : natural := Is_Clustered(ls.all,nb,sa,tolclus);
176: begin
177: if nb2 = nb
178: then put_line(file,"regular ==");
179: nbreg := nbreg + 1;
180: else put(file,"clustered : ");
181: put(file,nb2,1);
182: put_line(file," ==");
183: nbclus := nbclus + 1;
184: end if;
185: ls.m := 1;
186: end;
187: end if;
188: end if;
189: Clear(tolreal);
190: end Root_Accounting;
191:
192: procedure Root_Accounting
193: ( ls : in out Link_to_Solution; nb : in natural;
194: sa : in out Solution_Array; fail : in boolean;
195: tolsing,tolclus : in Floating_Number ) is
196:
197: -- DESCRIPTION :
198: -- This procedure does root accounting of the solution sol, w.r.t. the
199: -- solution list sols. Information will be provided concerning the type
200: -- of solution.
201:
202: begin
203: if fail
204: then ls.m := 0;
205: elsif sa(nb).rco < tolsing
206: then declare
207: m : natural := Multiplicity(ls.all,sa,tolclus);
208: begin
209: if m = 1
210: then ls.m := 0;
211: else ls.m := m;
212: end if;
213: end;
214: else ls.m := 1;
215: end if;
216: end Root_Accounting;
217:
218: procedure Write_Global_Info
219: ( file : in file_type;
220: tot,nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus : in natural ) is
221:
222: begin
223: Write_Bar(file);
224: put(file,"A list of "); put(file,tot,1);
225: put_line(file," solutions has been refined :");
226: put(file,"Number of regular solutions : "); put(file,nbreg,1);
227: put_line(file,".");
228: put(file,"Number of singular solutions : "); put(file,nbsing,1);
229: put_line(file,".");
230: put(file,"Number of real solutions : "); put(file,nbreal,1);
231: put_line(file,".");
232: put(file,"Number of complex solutions : "); put(file,nbcomp,1);
233: put_line(file,".");
234: put(file,"Number of clustered solutions : "); put(file,nbclus,1);
235: put_line(file,".");
236: put(file,"Number of failures : "); put(file,nbfail,1);
237: put_line(file,".");
238: Write_Bar(file);
239: end Write_Global_Info;
240:
241: -- TARGET ROUTINES :
242:
243: procedure Silent_Newton
244: ( p_eval : in Eval_Poly_Sys; j_eval : in Eval_Jaco_Mat;
245: zero : in out Solution; epsxa,epsfa : in Floating_Number;
246: numit : in out natural; max : in natural;
247: fail : out boolean ) is
248:
249: n : natural := p_eval'length;
250: jacobian : matrix(1..n,1..n);
251: ipvt : Standard_Natural_Vectors.Vector(1..n);
252: y,deltax : Vector(1..n);
253:
254: begin
255: y := eval(p_eval,zero.v); -- y = f(zero)
256: for i in 1..max loop
257: jacobian := Eval(j_eval,zero.v); -- solve jacobian*deltax = -f(zero)
258: lufco(jacobian,n,ipvt,zero.rco);
259: if Equal(zero.rco,0.0)
260: then fail := (Sum_Norm(y) > epsfa);
261: return; -- singular Jacobian matrix
262: end if;
263: deltax := -y; Clear(y);
264: lusolve(jacobian,n,ipvt,deltax);
265: Add(zero.v,deltax); -- make the updates
266: y := eval(p_eval,zero.v);
267: Clear(zero.err); Clear(zero.res);
268: zero.err := Sum_Norm(deltax); zero.res := Sum_Norm(y);
269: numit := numit + 1;
270: if ( zero.err < epsxa ) or else ( zero.res < epsfa )
271: -- stopping criteria
272: then fail := false; exit;
273: elsif numit >= max
274: then fail := true; exit;
275: end if;
276: Clear(deltax); Clear(jacobian);
277: end loop;
278: jacobian := eval(j_eval,zero.v); -- compute condition number
279: lufco(jacobian,n,ipvt,zero.rco);
280: Clear(jacobian);
281: exception
282: when numeric_error | constraint_error => fail := true; return;
283: end Silent_Newton;
284:
285: procedure Reporting_Newton
286: ( file : in file_type;
287: p_eval : in Eval_Poly_Sys; j_eval : in Eval_Jaco_Mat;
288: zero : in out Solution; epsxa,epsfa : in Floating_Number;
289: numit : in out natural; max : in natural;
290: fail : out boolean ) is
291:
292: n : natural := p_eval'length;
293: jacobian : matrix(1..n,1..n);
294: ipvt : Standard_Natural_Vectors.Vector(1..n);
295: y,deltax : Vector(1..n);
296:
297: begin
298: y := Eval(p_eval,zero.v); -- y = f(zero)
299: for i in 1..max loop
300: jacobian := eval(j_eval,zero.v); -- solve jacobian*deltax = -f(zero)
301: lufco(jacobian,n,ipvt,zero.rco);
302: if Equal(zero.rco,0.0) -- singular jacobian matrix
303: then fail := (Sum_Norm(y) > epsfa); -- accuracy not reached yet
304: return;
305: end if;
306: deltax := -y; Clear(y);
307: lusolve(jacobian,n,ipvt,deltax);
308: Add(zero.v,deltax); -- make the updates
309: y := eval(p_eval,zero.v);
310: Clear(zero.err); Clear(zero.res);
311: zero.err := Sum_Norm(deltax); zero.res := Sum_Norm(y);
312: numit := numit + 1;
313: put(file,"Step "); put(file,numit,4); new_line(file); -- output
314: put(file," |errxa| : "); put(file,zero.err); new_line(file);
315: put(file," |errfa| : "); put(file,zero.res); new_line(file);
316: if ( zero.err < epsxa ) or else ( zero.res < epsfa )
317: -- stopping criteria
318: then fail := false; exit;
319: elsif numit >= max
320: then fail := true; exit;
321: end if;
322: Clear(deltax); Clear(jacobian);
323: end loop;
324: jacobian := eval(j_eval,zero.v); -- compute condition number
325: lufco(jacobian,n,ipvt,zero.rco);
326: Clear(jacobian);
327: exception
328: when numeric_error | constraint_error => fail := true; return;
329: end Reporting_Newton;
330:
331: procedure Silent_Root_Refiner
332: ( p : in Poly_Sys; sols : in out Solution_List;
333: epsxa,epsfa,tolsing : in Floating_Number;
334: numit : in out natural; max : in natural ) is
335:
336: n : natural := p'length;
337: p_eval : Eval_Poly_Sys(1..n) := Create(p);
338: jac : Jaco_Mat(1..n,1..n) := Create(p);
339: jac_eval : Eval_Jaco_Mat(1..n,1..n) := Create(jac);
340: numb : natural;
341: fail : boolean;
342: sa : Solution_Array(1..Length_Of(sols)) := Create(sols);
343: eval_acc : Vector(1..n);
344:
345: begin
346: for i in sa'range loop
347: numb := 0;
348: Clear(sa(i).res);
349: eval_acc := Eval(p_eval,sa(i).v);
350: sa(i).res := Sum_Norm(eval_acc);
351: Clear(eval_acc);
352: if sa(i).res < 1.0
353: then Silent_Newton(p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
354: else fail := true;
355: end if;
356: Root_Accounting(sa(i),i,sa(sa'first..i),fail,tolsing,epsxa);
357: numit := numit + numb;
358: end loop;
359: clear(p_eval); clear(jac); clear(jac_eval);
360: Shallow_Clear(sols); sols := Create(sa); -- Shallow_Clear(sa);
361: end Silent_Root_Refiner;
362:
363: procedure Silent_Root_Refiner
364: ( p : in Poly_Sys; sols,refsols : in out Solution_List;
365: epsxa,epsfa,tolsing : in Floating_Number;
366: numit : in out natural; max : in natural ) is
367:
368: n : natural := p'length;
369: p_eval : Eval_Poly_Sys(1..n) := Create(p);
370: jac : Jaco_Mat(1..n,1..n) := Create(p);
371: jac_eval : Eval_Jaco_Mat(1..n,1..n) := Create(jac);
372: numb : natural;
373: fail : boolean;
374: sa : Solution_Array(1..Length_Of(sols)) := Create(sols);
375: refsols_last : Solution_List;
376: eval_acc : Vector(1..n);
377:
378: begin
379: for i in sa'range loop
380: numb := 0;
381: Clear(sa(i).res);
382: eval_acc := Eval(p_eval,sa(i).v);
383: sa(i).res := Sum_Norm(eval_acc);
384: Clear(eval_acc);
385: if sa(i).res < 1.0
386: then Silent_Newton(p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
387: if not fail
388: then Append(refsols,refsols_last,sa(i).all);
389: end if;
390: else fail := true;
391: end if;
392: Root_Accounting(sa(i),i,sa(sa'first..i),fail,tolsing,epsxa);
393: numit := numit + numb;
394: end loop;
395: clear(p_eval); clear(jac); clear(jac_eval);
396: Shallow_Clear(sols); sols := Create(sa); -- Shallow_Clear(sa);
397: end Silent_Root_Refiner;
398:
399: procedure Reporting_Root_Refiner
400: ( file : in file_type;
401: p : in Poly_Sys; sols : in out Solution_List;
402: epsxa,epsfa,tolsing : in Floating_Number;
403: numit : in out natural; max : in natural;
404: wout : in boolean ) is
405:
406: n : natural := p'length;
407: p_eval : Eval_Poly_Sys(1..n) := Create(p);
408: jac : Jaco_Mat(1..n,1..n) := Create(p);
409: jac_eval : Eval_Jaco_Mat(1..n,1..n) := Create(jac);
410: numb : natural;
411: nbfail,nbreg,nbsing,nbclus,nbreal,nbcomp : natural := 0;
412: nbtot : constant natural := Length_Of(sols);
413: fail : boolean;
414: sa : Solution_Array(1..nbtot) := Create(sols);
415: eval_acc : Vector(1..n);
416:
417: begin
418: new_line(file);
419: put_line(file,"THE SOLUTIONS :"); new_line(file);
420: put(file,nbtot,1); put(file," "); put(file,n,1); new_line(file);
421: Write_Bar(file);
422: for i in sa'range loop
423: numb := 0;
424: Clear(sa(i).res);
425: eval_acc := Eval(p_eval,sa(i).v);
426: sa(i).res := Sum_Norm(eval_acc);
427: Clear(eval_acc);
428: if sa(i).res < 1.0
429: then
430: if wout
431: then Reporting_Newton
432: (file,p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
433: else Silent_Newton
434: (p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
435: end if;
436: else
437: fail := true;
438: end if;
439: Write_Info(file,sa(i).all,i,n,numb,fail);
440: Root_Accounting(file,sa(i),i,sa(sa'first..i),fail,tolsing,epsxa,
441: nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus);
442: numit := numit + numb;
443: end loop;
444: Write_Global_Info(file,nbtot,nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus);
445: clear(p_eval); clear(jac); clear(jac_eval);
446: Shallow_Clear(sols); sols := Create(sa); -- Shallow_Clear(sa);
447: end Reporting_Root_Refiner;
448:
449: procedure Reporting_Root_Refiner
450: ( file : in file_type;
451: p : in Poly_Sys; sols,refsols : in out Solution_List;
452: epsxa,epsfa,tolsing : in Floating_Number;
453: numit : in out natural; max : in natural;
454: wout : in boolean ) is
455:
456: n : natural := p'length;
457: p_eval : Eval_Poly_Sys(1..n) := Create(p);
458: jac : Jaco_Mat(1..n,1..n) := Create(p);
459: jac_eval : Eval_Jaco_Mat(1..n,1..n) := Create(jac);
460: numb : natural;
461: nbfail,nbreg,nbsing,nbclus,nbreal,nbcomp : natural := 0;
462: nbtot : constant natural := Length_Of(sols);
463: fail : boolean;
464: sa : Solution_Array(1..nbtot) := Create(sols);
465: refsols_last : Solution_List;
466: eval_acc : Vector(1..n);
467:
468: begin
469: new_line(file);
470: put_line(file,"THE SOLUTIONS :"); new_line(file);
471: put(file,nbtot,1); put(file," "); put(file,n,1); new_line(file);
472: Write_Bar(file);
473: for i in sa'range loop
474: numb := 0;
475: Clear(sa(i).res);
476: eval_acc := Eval(p_eval,sa(i).v);
477: sa(i).res := Sum_Norm(eval_acc);
478: Clear(eval_acc);
479: if sa(i).res < 1.0
480: then
481: if wout
482: then Reporting_Newton
483: (file,p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
484: else Silent_Newton
485: (p_eval,jac_eval,sa(i).all,epsxa,epsfa,numb,max,fail);
486: end if;
487: if not fail
488: then Append(refsols,refsols_last,sa(i).all);
489: end if;
490: else
491: fail := true;
492: end if;
493: Write_Info(file,sa(i).all,i,n,numb,fail);
494: Root_Accounting(file,sa(i),i,sa(sa'first..i),fail,tolsing,epsxa,
495: nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus);
496: numit := numit + numb;
497: end loop;
498: Write_Global_Info(file,nbtot,nbfail,nbreal,nbcomp,nbreg,nbsing,nbclus);
499: clear(p_eval); clear(jac); clear(jac_eval);
500: Shallow_Clear(sols); sols := Create(sa); -- Shallow_Clear(sa);
501: end Reporting_Root_Refiner;
502:
503: end Multprec_Root_Refiners;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>