Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Polynomials/generic_polynomials.adb, Revision 1.1.1.1
1.1 maekawa 1: with unchecked_deallocation;
2: with Generic_Lists;
3: with Graded_Lexicographic_Order; use Graded_Lexicographic_Order;
4:
5: package body Generic_Polynomials is
6:
7: -- REPRESENTATION INVARIANT :
8: -- 1. Only terms with a coefficient different from zero are stored.
9: -- 2. The terms in any polynomial are ordered from high to low degree
10: -- according to the graded lexicographic order.
11:
12: use Ring;
13:
14: -- DATA STRUCTURES :
15:
16: package Term_List is new Generic_Lists(Term);
17: type Poly_Rep is new Term_List.List;
18:
19: procedure free is new unchecked_deallocation(Poly_Rep,Poly);
20:
21: -- AUXILIARY OPERATIONS :
22:
23: procedure Shuffle ( p : in out Poly ) is
24:
25: -- DESCRIPTION :
26: -- Changes the position of the terms in p back to the normal order.
27: -- Needed to guarantee the second representation invariant.
28:
29: res : Poly := Null_Poly;
30:
31: procedure Shuffle_Term ( t : in Term; cont : out boolean ) is
32: begin
33: Add(res,t);
34: cont := true;
35: end Shuffle_Term;
36: procedure Shuffle_Terms is new Visiting_Iterator(Shuffle_Term);
37:
38: begin
39: Shuffle_Terms(p);
40: Clear(p); Copy(res,p); Clear(res);
41: end Shuffle;
42:
43: procedure Append_Copy ( first,last : in out Poly_Rep; t : in Term ) is
44:
45: -- DESCRIPTION :
46: -- Appends a copy of the term to the list.
47:
48: tt : Term;
49:
50: begin
51: Copy(t,tt);
52: Append(first,last,tt);
53: end Append_Copy;
54:
55: -- CONSTRUCTORS :
56:
57: function Create ( n : natural ) return Poly is
58: begin
59: return Create(Ring.Create(n));
60: end Create;
61:
62: function Create ( n : number ) return Poly is
63:
64: t : Term;
65:
66: begin
67: Copy(n,t.cf);
68: return Create(t);
69: end Create;
70:
71: function Create ( t : Term ) return Poly is
72:
73: p : Poly;
74:
75: begin
76: if Equal(t.cf,zero)
77: then p := Null_Poly;
78: else declare
79: tt : Term;
80: begin
81: Copy(t,tt);
82: p := new Poly_Rep;
83: Construct(tt,p.all);
84: end;
85: end if;
86: return p;
87: end Create;
88:
89: procedure Copy ( t1 : in Term; t2 : in out Term ) is
90: begin
91: Clear(t2);
92: Standard_Natural_Vectors.Copy
93: (Standard_Natural_Vectors.Link_to_Vector(t1.dg),
94: Standard_Natural_Vectors.Link_to_Vector(t2.dg));
95: Copy(t1.cf,t2.cf);
96: end Copy;
97:
98: procedure Copy ( p: in Poly_Rep; q : in out Poly_Rep ) is
99:
100: lp,lq : Poly_Rep;
101: t : Term;
102:
103: begin
104: Clear(q);
105: if not Is_Null(p)
106: then lp := p;
107: while not Is_Null(lp) loop
108: t := Head_Of(lp);
109: Append_Copy(q,lq,t);
110: lp := Tail_Of(lp);
111: end loop;
112: end if;
113: end Copy;
114:
115: procedure Copy ( p : in Poly; q : in out Poly ) is
116:
117: l : Poly_Rep;
118:
119: begin
120: Clear(q);
121: if p /= Null_Poly
122: then Copy(p.all,l);
123: q := new Poly_Rep'(l);
124: else q := Null_Poly;
125: end if;
126: end Copy;
127:
128: -- SELECTORS :
129:
130: function Equal ( t1,t2 : Term ) return boolean is
131: begin
132: if not Equal(t1.dg,t2.dg)
133: then return false;
134: else return Equal(t1.cf,t2.cf);
135: end if;
136: end Equal;
137:
138: function Equal ( p,q : Poly_Rep ) return boolean is
139:
140: lp, lq : Poly_Rep;
141:
142: begin
143: lp := p;
144: lq := q;
145: while not Is_Null(lp) and not Is_Null(lq) loop
146: if not Equal(Head_Of(lp),Head_Of(lq))
147: then return false;
148: else lp := Tail_Of(lp);
149: lq := Tail_Of(lq);
150: end if;
151: end loop;
152: if Is_Null(lp) and Is_Null(lq)
153: then return true;
154: else return false;
155: end if;
156: end Equal;
157:
158: function Equal ( p,q : Poly ) return boolean is
159: begin
160: if (p = Null_Poly) and (q = Null_Poly)
161: then return true;
162: elsif (p = Null_Poly) or (q = Null_Poly)
163: then return false;
164: else return Equal(p.all,q.all);
165: end if;
166: end Equal;
167:
168: function Number_Of_Unknowns ( p : Poly ) return natural is
169:
170: temp : Term;
171:
172: begin
173: if (p = Null_Poly) or else Is_Null(p.all)
174: then return 0;
175: else temp := Head_Of(p.all);
176: if temp.dg = null
177: then return 0;
178: else return temp.dg'length;
179: end if;
180: end if;
181: end Number_Of_Unknowns;
182:
183: function Number_Of_Terms ( p : Poly ) return natural is
184: begin
185: if (p = Null_Poly) or else Is_Null(p.all)
186: then return 0;
187: else return Length_Of(p.all);
188: end if;
189: end Number_Of_Terms;
190:
191: function Degree ( p : Poly ) return integer is
192:
193: temp : Term;
194:
195: begin
196: if (p = Null_Poly) or else Is_Null(p.all)
197: then return -1;
198: else temp := Head_Of(p.all);
199: if temp.dg = null
200: then return 0;
201: else return integer(Sum(temp.dg));
202: end if;
203: end if;
204: end Degree;
205:
206: function Degree ( p : Poly; i : integer ) return integer is
207:
208: res : integer := 0;
209:
210: procedure Degree_Term (t : in Term; continue : out boolean) is
211: index,temp : integer;
212: begin
213: if t.dg /= null
214: then index := t.dg'first + i - 1;
215: temp := t.dg(index);
216: if (temp > 0) and then (temp > res)
217: then res := temp;
218: end if;
219: continue := true;
220: end if;
221: end Degree_Term;
222: procedure Degree_Terms is new Visiting_Iterator(process => Degree_Term);
223:
224: begin
225: if p = Null_Poly or else Is_Null(p.all)
226: then return -1;
227: else Degree_Terms(p);
228: return res;
229: end if;
230: end Degree;
231:
232: function "<" ( d1,d2 : Degrees ) return boolean is
233: begin
234: return Standard_Natural_Vectors.Link_to_Vector(d1)
235: < Standard_Natural_Vectors.Link_to_Vector(d2);
236: end "<";
237:
238: function ">" ( d1,d2 : Degrees ) return boolean is
239: begin
240: return Standard_Natural_Vectors.Link_to_Vector(d1)
241: > Standard_Natural_Vectors.Link_to_Vector(d2);
242: end ">";
243:
244: function Coeff ( p : Poly; d : degrees ) return number is
245:
246: l : Poly_Rep;
247: t : term;
248: res : number;
249:
250: begin
251: Copy(zero,res);
252: if p /= Null_Poly
253: then l := p.all;
254: while not Is_Null(l) loop
255: t := Head_Of(l);
256: exit when (t.dg < d);
257: if Equal(t.dg,d)
258: then Copy(t.cf,res);
259: exit;
260: else l := Tail_Of(l);
261: end if;
262: end loop;
263: end if;
264: return res;
265: end Coeff;
266:
267: -- ARITHMETICAL OPERATIONS :
268:
269: function "+" ( p : Poly; t : Term ) return Poly is
270:
271: temp : Poly;
272:
273: begin
274: Copy(p,temp);
275: Add(temp,t);
276: return temp;
277: end "+";
278:
279: function "+" ( t : Term; p : Poly ) return Poly is
280: begin
281: return p+t;
282: end "+";
283:
284: function "+" ( p,q : Poly ) return Poly is
285:
286: temp : Poly;
287:
288: begin
289: Copy(p,temp);
290: Add(temp,q);
291: return temp;
292: end "+";
293:
294: function "+" ( p : Poly ) return Poly is
295:
296: res : Poly;
297:
298: begin
299: Copy(p,res);
300: return res;
301: end "+";
302:
303: function "-" ( p : Poly; t : Term ) return Poly is
304:
305: temp : Poly;
306:
307: begin
308: Copy(p,temp);
309: Sub(temp,t);
310: return temp;
311: end "-";
312:
313: function "-" ( t : Term; p : Poly ) return Poly is
314:
315: temp : Poly;
316:
317: begin
318: temp := Create(t);
319: Sub(temp,p);
320: return temp;
321: end "-";
322:
323: function "-" ( p : Poly ) return Poly is
324:
325: temp : Poly;
326:
327: begin
328: Copy(p,temp);
329: Min(temp);
330: return temp;
331: end "-";
332:
333: function "-" ( p,q : Poly ) return Poly is
334:
335: temp : Poly;
336:
337: begin
338: Copy(p,temp);
339: Sub(temp,q);
340: return temp;
341: end "-";
342:
343: function "*" ( p : Poly; a : number ) return Poly is
344:
345: temp : Poly;
346:
347: begin
348: Copy(p,temp);
349: Mul(temp,a);
350: return temp;
351: end "*";
352:
353: function "*" ( a : number; p : Poly ) return Poly is
354: begin
355: return p*a;
356: end "*";
357:
358: function "*" ( p : Poly; t : Term ) return Poly is
359:
360: temp : Poly;
361:
362: begin
363: Copy(p,temp);
364: Mul(temp,t);
365: return temp;
366: end "*";
367:
368: function "*" ( t : Term; p : Poly ) return Poly is
369: begin
370: return p*t;
371: end "*";
372:
373: function "*" ( p,q : Poly ) return Poly is
374:
375: temp : Poly;
376:
377: begin
378: Copy(p,temp);
379: Mul(temp,q);
380: return temp;
381: end "*";
382:
383: procedure Add ( p : in out Poly; t : in Term ) is
384:
385: l1,l2,temp : Poly_Rep;
386: tt,tp : Term;
387:
388: begin
389: if t.cf /= zero
390: then Copy(t,tt);
391: if p = Null_Poly
392: then p := new Poly_Rep;
393: Construct(tt,p.all);
394: else tp := Head_Of(p.all);
395: if tt.dg > tp.dg
396: then Construct(tt,p.all);
397: elsif Equal(tt.dg,tp.dg)
398: then Add(tp.cf,tt.cf);
399: if tp.cf /= zero
400: then Set_Head(p.all,tp);
401: else Clear(tp);
402: if Is_Null(Tail_Of(p.all))
403: then Term_List.Clear(Term_List.List(p.all));
404: free(p);
405: else Swap_Tail(p.all,l1);
406: Term_List.Clear(Term_List.List(p.all));
407: p.all := l1;
408: end if;
409: end if;
410: Clear(tt);
411: else l1 := p.all;
412: l2 := Tail_Of(l1);
413: while not Is_Null(l2) loop
414: tp := Head_Of(l2);
415: if tt.dg > tp.dg
416: then Construct(tt,temp);
417: Swap_Tail(l1,temp);
418: l1 := Tail_Of(l1);
419: Swap_Tail(l1,temp);
420: return;
421: elsif Equal(tt.dg,tp.dg)
422: then Add(tp.cf,tt.cf);
423: if tp.cf /= zero
424: then Set_Head(l2,tp);
425: else Clear(tp);
426: temp := Tail_Of(l2);
427: Swap_Tail(l1,temp);
428: end if;
429: Clear(tt);
430: return;
431: else l1 := l2;
432: l2 := Tail_Of(l1);
433: end if;
434: end loop;
435: Construct(tt,temp);
436: Swap_Tail(l1,temp);
437: end if;
438: end if;
439: end if;
440: end Add;
441:
442: procedure Add ( p : in out Poly; q : in Poly ) is
443:
444: procedure Add ( t : in Term; continue : out boolean ) is
445: begin
446: Add(p,t);
447: continue := true;
448: end Add;
449: procedure Adds is new Visiting_Iterator(Add);
450:
451: begin
452: Adds(q);
453: end Add;
454:
455: procedure Sub ( p : in out Poly; t : in Term ) is
456:
457: temp : Term;
458:
459: begin
460: Standard_Natural_Vectors.Copy
461: (Standard_Natural_Vectors.Link_to_Vector(t.dg),
462: Standard_Natural_Vectors.Link_to_Vector(temp.dg));
463: temp.cf := -t.cf;
464: Add(p,temp);
465: Standard_Natural_Vectors.Clear
466: (Standard_Natural_Vectors.Link_to_Vector(temp.dg));
467: Clear(temp.cf);
468: end Sub;
469:
470: procedure Sub ( p : in out Poly; q : in Poly ) is
471:
472: temp : Poly := -q;
473:
474: begin
475: Add(p,temp);
476: Clear(temp);
477: end Sub;
478:
479: procedure Min ( p : in out Poly ) is
480:
481: procedure Min ( t : in out Term; continue : out boolean ) is
482: begin
483: Min(t.cf);
484: continue := true;
485: end Min;
486: procedure Min_Terms is new Changing_Iterator (process => Min);
487:
488: begin
489: Min_Terms(p);
490: end Min;
491:
492: procedure Mul ( p : in out Poly; a : in number ) is
493:
494: procedure Mul_Term ( t : in out Term; continue : out boolean ) is
495: begin
496: Mul(t.cf,a);
497: continue := true;
498: end Mul_Term;
499: procedure Mul_Terms is new Changing_Iterator (process => Mul_Term);
500:
501: begin
502: Mul_Terms(p);
503: end Mul;
504:
505: procedure Mul ( p : in out Poly; t : in Term ) is
506:
507: procedure Mul ( tp : in out Term; continue : out boolean ) is
508: begin
509: Standard_Natural_Vectors.Add
510: (Standard_Natural_Vectors.Link_to_Vector(tp.dg),
511: Standard_Natural_Vectors.Link_to_Vector(t.dg));
512: Mul(tp.cf,t.cf);
513: continue := true;
514: end Mul;
515: procedure Mul_Terms is new Changing_Iterator (process => Mul);
516:
517: begin
518: Mul_Terms(p);
519: end Mul;
520:
521: procedure Mul ( p : in out Poly; q : in Poly ) is
522:
523: res : Poly;
524: l : Poly_Rep;
525: t : Term;
526:
527: begin
528: if (q = Null_Poly) or else Is_Null(q.all)
529: then Clear(p);
530: else l := q.all;
531: res := Null_Poly;
532: while not Is_Null(l) loop
533: t := Head_Of(l);
534: declare
535: temp : Poly;
536: begin
537: temp := p * t;
538: Add(res,temp);
539: Clear(temp);
540: end;
541: l := Tail_Of(l);
542: end loop;
543: Copy(res,p); Clear(res);
544: end if;
545: end Mul;
546:
547: procedure Diff ( p : in out Poly; i : in integer ) is
548:
549: procedure Diff_Term ( t : in out Term; continue : out boolean ) is
550:
551: temp : number;
552: index : integer := t.dg'first + i - 1;
553:
554: begin
555: if t.dg(index) = 0
556: then Clear(t);
557: Copy(zero,t.cf);
558: else temp := Create(t.dg(index));
559: Mul(t.cf,temp);
560: Clear(temp);
561: t.dg(index) := t.dg(index) - 1;
562: end if;
563: continue := true;
564: end Diff_Term;
565: procedure Diff_Terms is new Changing_Iterator( process => Diff_Term );
566:
567: begin
568: Diff_Terms(p);
569: end Diff;
570:
571: function Diff ( p : Poly; i : integer ) return Poly is
572:
573: res : Poly;
574:
575: begin
576: Copy(p,res);
577: Diff(res,i);
578: return res;
579: end Diff;
580:
581: -- ITERATORS :
582:
583: procedure Visiting_Iterator ( p : in Poly ) is
584:
585: l : Poly_Rep;
586: temp : Term;
587: continue : boolean;
588:
589: begin
590: if p /= Null_Poly
591: then l := p.all;
592: while not Is_Null(l) loop
593: temp := Head_Of(l);
594: process(temp,continue);
595: exit when not continue;
596: l := Tail_Of(l);
597: end loop;
598: end if;
599: end Visiting_Iterator;
600:
601: procedure Changing_Iterator ( p : in out Poly ) is
602:
603: q,lq,lp : Poly_Rep;
604: t : Term;
605: continue : boolean := true;
606:
607: procedure Copy_append is
608:
609: temp : Term;
610:
611: begin
612: Copy(t,temp);
613: if continue
614: then process(temp,continue);
615: end if;
616: if not Equal(temp.cf,zero)
617: then Append(q,lq,temp);
618: else Clear(temp);
619: end if;
620: Clear(t);
621: end Copy_append;
622:
623: begin
624: if p = Null_Poly
625: then return;
626: else lp := p.all;
627: while not Is_Null(lp) loop
628: t := Head_Of(lp);
629: Copy_append;
630: lp := Tail_Of(lp);
631: end loop;
632: Term_List.Clear(Term_List.List(p.all)); free(p);
633: if Is_Null(q)
634: then p := Null_Poly;
635: else p := new Poly_Rep'(q);
636: end if;
637: Shuffle(p); -- ensure the second representation invariant
638: end if;
639: end Changing_Iterator;
640:
641: -- DESTRUCTORS :
642:
643: procedure Clear ( d : in out Degrees ) is
644: begin
645: Standard_Natural_Vectors.Clear(Standard_Natural_Vectors.Link_to_Vector(d));
646: end Clear;
647:
648: procedure Clear ( t : in out Term ) is
649: begin
650: Clear(t.dg);
651: Clear(t.cf);
652: end Clear;
653:
654: procedure Clear ( p : in out Poly_Rep ) is
655:
656: l : Poly_Rep := p;
657: t : Term;
658:
659: begin
660: if Is_Null(p)
661: then return;
662: else while not Is_Null(l) loop
663: t := Head_Of(l);
664: Clear(t);
665: l := Tail_Of(l);
666: end loop;
667: Term_List.Clear(Term_List.List(p));
668: end if;
669: end Clear;
670:
671: procedure Clear ( p : in out Poly ) is
672: begin
673: if p /= Null_Poly
674: then Clear(p.all);
675: free(p);
676: p := Null_Poly;
677: end if;
678: end Clear;
679:
680: end Generic_Polynomials;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>