source: Sophya/trunk/SophyaLib/NTools/poly.cc@ 490

Last change on this file since 490 was 490, checked in by ansari, 26 years ago

Merge avec PEIDA++ (~V 3.8) et nettoyage pour nouveau PPersist Reza+cmv 21/10/99

File size: 18.3 KB
Line 
1#include "machdefs.h"
2#include "poly.h"
3#include "linfit.h"
4
5//++
6// Class Poly
7// Lib Outils++
8// include poly.h
9//
10// Classe de calcul sur polynômes à une variable.
11//--
12
13//++
14// Links Parents
15// Vector
16//--
17
18//++
19// Titre Constructeurs
20//--
21
22
23//++
24// Poly::Poly(int degre=0)
25//
26// Crée un nouveau polynôme, en allouant de la place pour
27// le degré spécifié.
28//--
29
30Poly::Poly(int degre)
31: Vector(degre+1), dirty(0), deg(0)
32{
33 END_CONSTRUCTOR
34}
35
36
37void Poly::UpdateDeg() const
38{
39 int i = nalloc-1;
40 while (data[i] == 0 && i>0) i--;
41
42 (int&) deg = i; // bientot mutable dans ANSI C++
43 (int&) dirty = 0;
44}
45
46//++
47// Titre Méthodes
48//--
49
50//++
51// double& Poly::operator[](int i)
52// Permet d'accéder au coefficient de degré i (avec version
53// const).
54//--
55
56//++
57double Poly::operator()(double x) const
58//
59// Calcule la valeur du polynôme au point x.
60//--
61{
62 UpdateDegIfDirty();
63 double res = data[deg];
64 for (int i=deg-1; i>=0; i--) {
65 res *= x;
66 res += data[i];
67 }
68 return res;
69}
70
71//++
72void Poly::Derivate()
73//
74// Remplace le polynôme par le polynôme dérivé.
75//--
76{
77 UpdateDegIfDirty();
78 if (deg == 0) { data[0] = 0; return;}
79 for (int i=1; i<=deg; i++)
80 data[i-1] = data[i]*i;
81 data[deg] = 0;
82 deg--;
83}
84
85
86//++
87void Poly::Derivate(Poly& der) const
88//
89// Retourne dans der le polynôme dérivé.
90//--
91{
92 UpdateDegIfDirty();
93 der.Realloc(deg);
94// der.Zero(); // on sait que Realloc met a zero le reste.
95 for (int i=1; i<=deg; i++)
96 der.data[i-1] = data[i]*i;
97}
98
99
100//++
101int Poly::Roots(Vector& roots) const
102//
103// Retourne dans roots les racines réelles, si on sait
104// les calculer. Retourne le nombre de racines.
105//--
106{
107 UpdateDegIfDirty();
108
109 switch (deg)
110 {
111 case 0 : // degre 0
112 return 0;
113 case 1 : // degre 1
114 roots.Realloc(1);
115 return Root1(roots(0));
116 case 2 : // degre 2
117 roots.Realloc(2);
118 return Root2(roots(0),roots(1));
119 default :
120 THROW(parmErr);
121 }
122}
123
124
125//++
126int Poly::Root1(double& r) const
127//
128// Seulement si le polynôme est de degré 1: retourne
129// la racine dans "r". Retourne 1 (nombre de racines).
130//--
131{
132 UpdateDegIfDirty();
133 if (deg != 1) THROW(sizeMismatchErr);
134
135 if (data[1] == 0) return 0;
136 r = -data[0]/data[1];
137 return 1;
138}
139
140//++
141int Poly::Root2(double& r1, double& r2) const
142//
143// Seulement si le polynôme est de degre 2: retourne
144// les racines dans "r1" et "r2". Retourne 0, 1 ou 2
145// (nombre de racines).
146//--
147{
148 UpdateDegIfDirty();
149 if (deg != 2) THROW(sizeMismatchErr);
150
151 double delta = data[1]*data[1] - 4*data[0]*data[2];
152 if (delta < 0) return 0;
153 if (delta == 0) {
154 r1 = r2 = -data[1]/2/data[0];
155 return 1;
156 }
157 r1 = (-data[1] - sqrt(delta))/2/data[0];
158 r2 = (-data[1] + sqrt(delta))/2/data[0];
159 return 2;
160}
161
162//++
163Poly& Poly::operator = (Poly const& a)
164//
165// Opérateur d'affectation.
166//--
167{
168 if (this == &a) return *this;
169 Vector::operator=(a);
170
171 UpdateDeg();
172 return *this;
173}
174
175//++
176// Titres Opérations sur polynômes
177//--
178
179//++
180Poly& Poly::operator += (Poly const& b)
181//
182//--
183{
184 UpdateDegIfDirty();
185 b.UpdateDegIfDirty();
186
187 if (b.deg > deg)
188 Realloc(b.deg);
189
190 int n = (deg > b.deg) ? deg : b.deg;
191 for (int i=0; i<=n; i++)
192 data[i] += b.data[i];
193
194 UpdateDeg();
195 return *this;
196}
197
198//++
199Poly& Poly::operator -= (Poly const& b)
200//
201//--
202{
203 UpdateDegIfDirty();
204 b.UpdateDegIfDirty();
205
206 if (b.deg > deg)
207 Realloc(b.deg);
208
209 int n = (deg > b.deg) ? deg : b.deg;
210 for (int i=0; i<=n; i++)
211 data[i] -= b.data[i];
212
213 UpdateDeg();
214 return *this;
215}
216
217
218//++
219Poly operator+ (Poly const& a, Poly const& b)
220//
221//--
222#if HAS_NAMED_RETURN
223 return c((a.deg > b.deg)?(a.deg+1):(b.deg+1))
224#endif
225{
226#if !HAS_NAMED_RETURN
227Poly c((a.deg > b.deg)?(a.deg+1):(b.deg+1));
228#endif
229 c = a;
230 c += b;
231#if !HAS_NAMED_RETURN
232return c;
233#endif
234}
235
236//++
237Poly operator- (Poly const& a, Poly const& b)
238//
239//--
240#if HAS_NAMED_RETURN
241 return c((a.deg > b.deg)?(a.deg+1):(b.deg+1))
242#endif
243{
244#if !HAS_NAMED_RETURN
245Poly c((a.deg > b.deg)?(a.deg+1):(b.deg+1));
246#endif
247 c = a;
248 c -= b;
249#if !HAS_NAMED_RETURN
250return c;
251#endif
252}
253
254//++
255Poly operator* (Poly const& a, Poly const& b)
256//
257//--
258//#if HAS_NAMED_RETURN
259// return c(a.deg + b.deg)
260//#endif
261{
262//#if !HAS_NAMED_RETURN
263Poly c(a.deg + b.deg);
264//#endif
265 a.UpdateDegIfDirty();
266 b.UpdateDegIfDirty();
267
268 c.deg = a.deg + b.deg;
269
270 for (int i=0; i<=c.deg; i++) {
271 c[i] = 0;
272 int kmin = (i <= a.deg) ? 0 : i - a.deg;
273 int kmax = (i <= a.deg) ? i : a.deg;
274 for (int k=kmin; k<=kmax; k++)
275 c[i] += a[k] * b[i-k];
276 }
277//#if !HAS_NAMED_RETURN
278return c;
279//#endif
280}
281
282//++
283Poly& Poly::operator *= (double a)
284//
285//--
286{
287 UpdateDegIfDirty();
288
289 for (int i=0; i<=deg; i++)
290 data[i] *= a;
291
292 return *this;
293}
294
295
296//++
297Poly operator* (double a, Poly const& b)
298//
299//--
300#if HAS_NAMED_RETURN
301 return c(b)
302#endif
303{
304#if !HAS_NAMED_RETURN
305 Poly c(b);
306#endif
307
308 c *= a;
309
310#if !HAS_NAMED_RETURN
311 return c;
312#endif
313}
314
315
316void Poly::ReadSelf(PInPersist& s)
317{
318 int_4 dg;
319 s >> dg;
320 Realloc(dg, true);
321
322#ifdef DEBUG
323 int r = nr; int c = nc;
324#endif
325
326 Vector::ReadSelf(s);
327
328#ifdef DEBUG
329 DBASSERT(r == nr && c == nc);
330#endif
331 UpdateDeg();
332
333 #ifdef DEBUG
334 DBASSERT(dg == deg);
335 #endif
336}
337
338void Poly::WriteSelf(POutPersist& s) const
339{
340 UpdateDegIfDirty();
341 ((Poly*)(this))->Realloc(deg, true);
342 s << deg;
343 Vector::WriteSelf(s);
344}
345
346//++
347void Poly::Print(ostream& s) const
348//
349// Impresssion.
350//--
351{
352 UpdateDegIfDirty();
353 int nz=0;
354 for (int i = deg; i>=0; i--) {
355 if ((*this)[i] != 0) {
356 nz = 1;
357 if (i < deg && (*this)[i] > 0) s << "+";
358 s << (*this)[i];
359 if (i == 1) s << "*X ";
360 if (i > 1) s << "*X^" << i << " ";
361 }
362 }
363 if (!nz) s << " 0 ";
364}
365
366//++
367ostream& operator << (ostream& s, const Poly& a)
368//
369// Impressions sur le stream "s".
370//--
371{
372 a.Print(s);
373 return s;
374}
375
376//++
377double Poly::Fit(Vector const& x, Vector const& y, int degre)
378//
379// Ajustement polynomial par moindre carrés. Un polynôme de
380// degré "degre" est ajusté sur les données "x" et "y", et stocké dans
381// l'objet courant. Retourne le chi2.
382//--
383{
384 int n = x.NElts();
385 if (n != y.NElts()) THROW(sizeMismatchErr);
386
387 Realloc(degre);
388
389 Matrix a(degre+1, n);
390
391 for (int c=0; c<n; c++) {
392 double xpow = 1.0;
393 for (int l=0; l<=degre; l++) {
394 a(l,c) = xpow;
395 xpow *= x(c);
396 }
397 }
398
399 double rc = LinFit(a,y,(Vector&)*this);
400 UpdateDeg();
401 return rc;
402}
403
404//++
405double Poly::Fit(Vector const& x, Vector const& y, Vector const& erry2, int degre,
406 Vector& errCoef)
407//
408// Ajustement polynomial par moindre carrés. Un polynôme de
409// degré est ajusté sur les données x et y, et stocké dans
410// l'objet courant. erry2 contient le carre des erreurs sur y.
411// Retourne le chi2.
412//--
413{
414 int n = x.NElts();
415 if (n != y.NElts()) THROW(sizeMismatchErr);
416 if (n != erry2.NElts()) THROW(sizeMismatchErr);
417
418 Realloc(degre);
419 errCoef.Realloc(degre+1);
420
421 Matrix a(degre+1, n);
422
423 for (int c=0; c<n; c++) {
424 double xpow = 1.0;
425 for (int l=0; l<=degre; l++) {
426 a(l,c) = xpow;
427 xpow *= x(c);
428 }
429 }
430
431 double rc = LinFit(a,y,erry2,(Vector&)*this,errCoef);
432 UpdateDeg();
433 return rc;
434}
435
436int binomial(int n, int p)
437{
438 int c = 1;
439 for (int i=n-p+1; i<=n; i++) c *= i;
440 for (int j=2; j<=p; j++) c /= j;
441 return c;
442}
443
444
445//++
446// Poly Poly::power(int n) const
447//
448// Retourne le polynôme à la puissance n
449//--
450
451Poly Poly::power(int n) const // a accelerer !!!
452{
453 if (n < 0) THROW(rangeCheckErr);
454 if (n == 0) { Poly r(0); r[0] = 1; return r;}
455 if (n == 1) { return *this; }
456 return *this * power(n-1);
457}
458
459//++
460Poly Poly::operator() (Poly const& b) const
461//
462// Substitution d'un polynôme dans un autre.
463//--
464{
465 Poly c(b.Degre()*Degre());
466 for (int i=0; i<= Degre(); i++)
467 c += (*this)[i] * b.power(i);
468 return c;
469}
470
471
472// ******************* POLY 2 VARIABLES ******************
473
474//++
475// Class Poly2
476// Lib Outils++
477// include poly.h
478//
479// Classe de calcul sur polynômes à deux variables.
480//--
481
482//++
483// Links Parents
484// Vector
485//--
486
487//++
488// Titre Constructeurs
489//--
490
491//++
492Poly2::Poly2(int degreX, int degreY)
493//
494// Crée un polynôme de degrés partiels degreX et degreY.
495//--
496:Vector((degreX+1)*(degreY+1)), dirty(0),
497 maxDegX(degreX), maxDegY(degreY), degX(0), degY(0), deg(0)
498{
499 END_CONSTRUCTOR
500}
501
502//++
503Poly2::Poly2(Poly const& polX, Poly const& polY)
504//
505// Crée un polynôme à deux variables comme produit
506// de deux polynômes à une variable, p2(x,y)=px(x)py(y)
507//--
508:Vector((polX.Degre()+1)*(polY.Degre()+1)), dirty(0),
509 maxDegX(polX.Degre()), maxDegY(polY.Degre()),
510 degX(polX.Degre()), degY(polY.Degre()), deg(degX+degY)
511{
512 for (int i=0; i<=degX; i++)
513 for (int j=0; j<=degY; j++)
514 Coef(i,j) = polX[i]*polY[j];
515 END_CONSTRUCTOR
516}
517
518//++
519Poly2::Poly2(Poly2 const& a)
520//
521// Constructeur par copie.
522//--
523:Vector(a), dirty(a.dirty),
524 maxDegX(a.maxDegX), maxDegY(a.maxDegY),
525 degX(a.degX), degY(a.degY), deg(a.deg)
526{
527 END_CONSTRUCTOR
528}
529
530
531//++
532// Titre Méthodes
533//--
534
535//++
536Poly2& Poly2::operator = (Poly2 const& a)
537//
538// Opérateur d'affectation.
539//--
540{
541 if (this == &a) return *this;
542 if (maxDegX < a.DegX() || maxDegY < a.DegY())
543 Realloc(a.DegX(), a.DegY());
544
545
546 for (int i=0; i<= maxDegX; i++)
547 for (int j=0; j<= maxDegY; j++)
548 Coef(i,j) = a.Coef(i,j);
549
550 UpdateDeg();
551 return *this;
552}
553
554//++
555void Poly2::Realloc(int degreX, int degreY)
556//
557// Redimensionne le polynôme comme etant un
558// polynôme de degrés partiels degreX et degreY.
559//--
560{
561 UpdateDegIfDirty();
562 Poly2 tmp(*this);
563 Vector::Realloc((degreX+1)*(degreY+1));
564 Zero();
565 maxDegX = degreX;
566 maxDegY = degreY;
567
568// Attention - Reza 30/09/99
569// il faut prendre le min en degre du polynome de depart et le nouveau
570 int cdegx = (tmp.degX < degreX) ? tmp.degX : degreX;
571 int cdegy = (tmp.degY < degreY) ? tmp.degY : degreY;
572 for (int i=0; i<= cdegx; i++)
573 for (int j=0; j<= cdegy; j++)
574 Coef(i,j) = tmp.Coef(i,j);
575}
576
577
578void Poly2::UpdateDeg() const
579{
580 (int&)degX=(int&)degY=(int&)deg=0;
581
582 for (int dx=0; dx<=maxDegX; dx++)
583 for (int dy=0; dy<=maxDegY; dy++)
584 if (Coef(dx,dy) != 0) {
585 if (dx > degX) (int&)degX = dx;
586 if (dy > degY) (int&)degY = dy;
587 if (dx+dy > deg) (int&)deg = dx+dy;
588 }
589
590 (int&)dirty = 0;
591}
592
593//++
594// int Poly2::DegX() const
595// Degré partiel en X.
596// int Poly2::DegY() const
597// Degré partiel en Y
598// int Poly2::MaxDegX() const
599// Degré partiel maximum (alloué) en X
600// int Poly2::MaxDegY() const
601// Degré partiel maximum (alloué) en Y
602// int Poly2::Deg() const
603// Degré total.
604//--
605
606//++
607// double& Poly2::Coef(int dx, int dy)
608// Retourne le coefficient de x^dx y^dy
609// (avec aussi version const).
610//--
611
612//++
613double Poly2::operator()(double x, double y) const
614//
615// Retourne la valeur en (x,y).
616//--
617{
618 UpdateDegIfDirty();
619 double res = 0;
620 double xPow = 1;
621 for (int dx=0; dx<=maxDegX; dx++) {
622 double yPow = 1;
623 for (int dy=0; dy<=maxDegY; dy++) {
624 res += Coef(dx,dy) * xPow * yPow;
625 yPow *= y;
626 }
627 xPow *= x;
628 }
629 return res;
630}
631
632//++
633double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
634 int degreX, int degreY)
635//
636// Ajustement par moindre carrés z = P(x,y), degrés partiels imposés.
637//--
638{
639 int n = x.NElts();
640 if (n != y.NElts()) THROW(sizeMismatchErr);
641 if (n != z.NElts()) THROW(sizeMismatchErr);
642
643 Realloc(degreX, degreY);
644
645 Matrix a((degreX+1)*(degreY+1), n);
646
647 for (int c=0; c<n; c++) {
648 double xPow = 1.0;
649 for (int dx = 0; dx <= degreX; dx++) {
650 double yPow = 1.0;
651 for (int dy = 0; dy <= degreY; dy++) {
652 a(IndCoef(dx,dy), c) = xPow*yPow;
653 yPow *= y(c);
654 }
655 xPow *= x(c);
656 }
657 }
658
659 double rc = LinFit(a,z,(Vector&)*this);
660 UpdateDeg();
661 return rc;
662}
663
664
665//++
666double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
667 Vector const& errz2, int degreX, int degreY,
668 Vector& errCoef)
669//
670// Ajustement par moindre carrés z = P(x,y), degrés partiels imposés,
671// et erreurs^2 sur z dans errz2.
672//--
673{
674 int n = x.NElts();
675 if (n != y.NElts()) THROW(sizeMismatchErr);
676 if (n != z.NElts()) THROW(sizeMismatchErr);
677 if (n != errz2.NElts()) THROW(sizeMismatchErr);
678
679 Realloc(degreX, degreY);
680 errCoef.Realloc((degreX+1)*(degreY+1));
681
682 Matrix a((degreX+1)*(degreY+1), n);
683
684 for (int c=0; c<n; c++) {
685 double xPow = 1.0;
686 for (int dx = 0; dx <= degreX; dx++) {
687 double yPow = 1.0;
688 for (int dy = 0; dy <= degreY; dy++) {
689 a(IndCoef(dx,dy), c) = xPow*yPow;
690 yPow *= y(c);
691 }
692 xPow *= x(c);
693 }
694 }
695
696 double rc = LinFit(a,z,errz2,(Vector&)*this,errCoef);
697 UpdateDeg();
698 return rc;
699}
700
701//++
702double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
703 int degre)
704//
705// Ajustement par moindre carrés z = P(x,y), degré total imposé.
706//--
707{
708 int n = x.NElts();
709 if (n != y.NElts()) THROW(sizeMismatchErr);
710 if (n != z.NElts()) THROW(sizeMismatchErr);
711
712 Realloc(degre, degre); // certains vaudront 0, impose.
713
714 Matrix a((degre+1)*(degre+2)/2, n);
715 Vector cf((degre+1)*(degre+2)/2);
716#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
717
718 for (int c=0; c<n; c++) {
719 double xPow = 1.0;
720 for (int dx = 0; dx <= degre; dx++) {
721 double yPow = 1.0;
722 for (int dy = 0; dy <= degre; dy++) {
723 if (dy+dx <= degre)
724 a(C_INDEX(dx,dy), c) = xPow*yPow;
725 yPow *= y(c);
726 }
727 xPow *= x(c);
728 }
729 }
730
731 double rc = LinFit(a,z,cf);
732
733 for (int dx = 0; dx <= degre; dx++)
734 for (int dy = 0; dy <= degre; dy++)
735 if (dx+dy <= degre)
736 Coef(dx,dy) = cf(C_INDEX(dx,dy));
737 else
738 Coef(dx,dy) = 0;
739
740 UpdateDeg();
741 return rc;
742}
743
744
745//++
746double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
747 Vector const& errz2, int degre,
748 Vector& errCoef)
749//
750// Ajustement par moindre carrés z = P(x,y), degré total imposé,
751// et erreurs^2 sur z dans errz2.
752//--
753{
754 int n = x.NElts();
755 if (n != y.NElts()) THROW(sizeMismatchErr);
756 if (n != z.NElts()) THROW(sizeMismatchErr);
757 if (n != errz2.NElts()) THROW(sizeMismatchErr);
758
759 Realloc(degre, degre);
760 errCoef.Realloc((degre+1)*(degre+1));
761#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
762
763 Matrix a((degre+1)*(degre+2)/2, n);
764 Vector cf((degre+1)*(degre+2)/2);
765 Vector ecf((degre+1)*(degre+2)/2);
766
767 for (int c=0; c<n; c++) {
768 double xPow = 1.0;
769 for (int dx = 0; dx <= degre; dx++) {
770 double yPow = 1.0;
771 for (int dy = 0; dy <= degre; dy++) {
772 if (dy+dx <= degre)
773 a(C_INDEX(dx,dy), c) = xPow*yPow;
774 yPow *= y(c);
775 }
776 xPow *= x(c);
777 }
778 }
779
780 double rc = LinFit(a,z,errz2,cf,ecf);
781
782
783 for (int dx = 0; dx <= degre; dx++)
784 for (int dy = 0; dy <= degre; dy++)
785 if (dx+dy <= degre) {
786 Coef(dx,dy) = cf(C_INDEX(dx,dy));
787 errCoef(IndCoef(dx,dy)) = ecf(C_INDEX(dx,dy));
788 } else {
789 Coef(dx,dy) = 0;
790 errCoef(IndCoef(dx,dy)) = 0;
791 }
792 UpdateDeg();
793 return rc;
794}
795
796
797void Poly2::ReadSelf(PInPersist& s)
798{
799 int_4 dgx, dgy;
800 s >> dgx >> dgy;
801
802 Realloc(dgx, dgy);
803
804#ifdef DEBUG
805 int r = nr; int c = nc;
806#endif
807
808 Vector::ReadSelf(s);
809
810#ifdef DEBUG
811 DBASSERT(r == nr && c == nc);
812#endif
813 UpdateDeg();
814}
815
816void Poly2::WriteSelf(POutPersist& s) const
817{
818 s << maxDegX << maxDegY;
819 Vector::WriteSelf(s);
820}
821
822//++
823void Poly2::Print(ostream& s) const
824//
825// Impression sur stream s.
826//--
827{
828 UpdateDegIfDirty();
829 int nz=0;
830 int notfirst=0;
831 for (int dx = degX; dx>=0; dx--)
832 for (int dy= degY; dy>=0; dy--) {
833 double c = Coef(dx,dy);
834 if (c != 0) {
835 nz = 1;
836 if (notfirst && c > 0) {
837 s << "+";
838 notfirst = 1;
839 }
840 s << c << " ";
841 if (dx == 1) s << "* X ";
842 if (dx > 1) s << "* X^" << dx << " ";
843 if (dy == 1) s << "* Y ";
844 if (dy > 1) s << "* Y^" << dy << " ";
845 s << endl;
846 }
847 }
848 if (!nz) s << " 0 ";
849}
850
851//++
852ostream& operator << (ostream& s, const Poly2& a)
853//
854// Impression sur stream s.
855//--
856{
857 a.Print(s);
858 return s;
859}
860
861
862//++
863// Titre Opérations
864//--
865
866//++
867Poly2& Poly2::operator += (Poly2 const& b)
868//
869//--
870{
871 if (maxDegX < b.DegX() || maxDegY < b.DegY())
872 Realloc(b.DegX(),b.DegY());
873
874 UpdateDegIfDirty();
875
876 int mx = b.DegX();
877 int my = b.DegY();
878 for (int i=0; i<= mx; i++)
879 for (int j=0; j<= my; j++)
880 Coef(i,j) += b.Coef(i,j);
881
882 UpdateDeg();
883 return *this;
884}
885
886//++
887Poly2& Poly2::operator -= (Poly2 const& b)
888//
889//--
890{
891 if (maxDegX < b.DegX() || maxDegY < b.DegY())
892 Realloc(b.DegX(),b.DegY());
893
894 UpdateDegIfDirty();
895
896 int mx = b.DegX();
897 int my = b.DegY();
898 for (int i=0; i<= mx; i++)
899 for (int j=0; j<= my; j++)
900 Coef(i,j) -= b.Coef(i,j);
901
902 UpdateDeg();
903 return *this;
904}
905
906//++
907Poly2 operator+ (Poly2 const& a, Poly2 const& b)
908//
909//--
910#if HAS_NAMED_RETURN
911 return c(a)
912#endif
913{
914#if !HAS_NAMED_RETURN
915Poly2 c(a);
916#endif
917 c += b;
918#if !HAS_NAMED_RETURN
919return c;
920#endif
921}
922
923//++
924Poly2 operator- (Poly2 const& a, Poly2 const& b)
925//
926//--
927#if HAS_NAMED_RETURN
928 return c(a)
929#endif
930{
931#if !HAS_NAMED_RETURN
932Poly2 c(a);
933#endif
934 c -= b;
935#if !HAS_NAMED_RETURN
936return c;
937#endif
938}
939
940//++
941Poly2& Poly2::operator *= (double a)
942//
943//--
944{
945 for (int i=0; i<NElts(); i++)
946 data[i] *= a;
947
948 return *this;
949}
950
951//++
952Poly2 operator * (double a, Poly2 const& b)
953//
954//--
955#if HAS_NAMED_RETURN
956 return c(b)
957#endif
958{
959#if !HAS_NAMED_RETURN
960Poly2 c(b);
961#endif
962 c *= a;
963#if !HAS_NAMED_RETURN
964return c;
965#endif
966}
967
968//++
969Poly2 operator* (Poly2 const& a, Poly2 const& b)
970//
971//--
972{
973 Poly2 c(a.DegX() + b.DegX(), a.DegY() + b.DegY());
974 a.UpdateDegIfDirty();
975 b.UpdateDegIfDirty();
976
977 for (int i=0; i<=a.DegX(); i++)
978 for (int j=0; j<=a.DegY(); j++)
979 for (int k=0; k<=b.DegX(); k++)
980 for (int l=0; l<=b.DegY(); l++)
981 c.Coef(i+k,j+l) += a.Coef(i,j)*b.Coef(k,l);
982 return c;
983}
984
985//++
986Poly2 Poly2::power(int n) const
987//
988// Calcule le polynôme P(x,y)^n
989//--
990{
991 if (n < 0) THROW(rangeCheckErr);
992 if (n == 0) { Poly2 r(0); r.Coef(0,0) = 1; return r;}
993 if (n == 1) { return *this; }
994 return *this * power(n-1);
995}
996
997
998//++
999Poly2 Poly2::operator() (Poly const& a, Poly const& b) const
1000//
1001// Substitution de deux polynômes en X et Y,
1002// P2(pa(x), pb(y)).
1003//--
1004{
1005 UpdateDegIfDirty();
1006 Poly2 c(maxDegX*a.Degre(), maxDegY*b.Degre());
1007
1008 for (int i=0; i<= degX; i++)
1009 for (int j=0; j<= degY; j++) {
1010 Poly2 d(a.power(i), b.power(j));
1011 c += Coef(i,j) * d;
1012 }
1013
1014 return c;
1015}
1016
1017//++
1018Poly2 Poly::operator() (Poly2 const& a) const
1019//
1020// Substitution d'un polynôme à deux variables dans
1021// un polynôme à une variable, P(P2(x,y)).
1022//--
1023{
1024 Poly2 c(a.MaxDegX()*Degre(), a.MaxDegY()*Degre());
1025
1026 for (int i=0; i<= Degre(); i++)
1027 c += (*this)[i] * a.power(i);
1028 return c;
1029}
1030
1031
Note: See TracBrowser for help on using the repository browser.