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

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

Creation module DPC/NTools Reza 09/04/99

File size: 18.0 KB
Line 
1#include "defs.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 DBASSERT(r == nr && c == nc);
329 UpdateDeg();
330
331 #ifdef DEBUG
332 DBASSERT(dg == deg);
333 #endif
334}
335
336void Poly::WriteSelf(POutPersist& s) const
337{
338 UpdateDegIfDirty();
339 ((Poly*)(this))->Realloc(deg, true);
340 s << deg;
341 Vector::WriteSelf(s);
342}
343
344//++
345void Poly::Print(ostream& s) const
346//
347// Impresssion.
348//--
349{
350 UpdateDegIfDirty();
351 int nz=0;
352 for (int i = deg; i>=0; i--) {
353 if ((*this)[i] != 0) {
354 nz = 1;
355 if (i < deg && (*this)[i] > 0) s << "+";
356 s << (*this)[i];
357 if (i == 1) s << "*X ";
358 if (i > 1) s << "*X^" << i << " ";
359 }
360 }
361 if (!nz) s << " 0 ";
362}
363
364//++
365ostream& operator << (ostream& s, const Poly& a)
366//
367// Impressions sur le stream "s".
368//--
369{
370 a.Print(s);
371 return s;
372}
373
374//++
375double Poly::Fit(Vector const& x, Vector const& y, int degre)
376//
377// Ajustement polynomial par moindre carrés. Un polynôme de
378// degré "degre" est ajusté sur les données "x" et "y", et stocké dans
379// l'objet courant. Retourne le chi2.
380//--
381{
382 int n = x.NElts();
383 if (n != y.NElts()) THROW(sizeMismatchErr);
384
385 Realloc(degre);
386
387 Matrix a(degre+1, n);
388
389 for (int c=0; c<n; c++) {
390 double xpow = 1.0;
391 for (int l=0; l<=degre; l++) {
392 a(l,c) = xpow;
393 xpow *= x(c);
394 }
395 }
396
397 double rc = LinFit(a,y,(Vector&)*this);
398 UpdateDeg();
399 return rc;
400}
401
402//++
403double Poly::Fit(Vector const& x, Vector const& y, Vector const& erry2, int degre,
404 Vector& errCoef)
405//
406// Ajustement polynomial par moindre carrés. Un polynôme de
407// degré est ajusté sur les données x et y, et stocké dans
408// l'objet courant. erry2 contient le carre des erreurs sur y.
409// Retourne le chi2.
410//--
411{
412 int n = x.NElts();
413 if (n != y.NElts()) THROW(sizeMismatchErr);
414 if (n != erry2.NElts()) THROW(sizeMismatchErr);
415
416 Realloc(degre);
417 errCoef.Realloc(degre+1);
418
419 Matrix a(degre+1, n);
420
421 for (int c=0; c<n; c++) {
422 double xpow = 1.0;
423 for (int l=0; l<=degre; l++) {
424 a(l,c) = xpow;
425 xpow *= x(c);
426 }
427 }
428
429 double rc = LinFit(a,y,erry2,(Vector&)*this,errCoef);
430 UpdateDeg();
431 return rc;
432}
433
434int binomial(int n, int p)
435{
436 int c = 1;
437 for (int i=n-p+1; i<=n; i++) c *= i;
438 for (int j=2; j<=p; j++) c /= j;
439 return c;
440}
441
442
443//++
444// Poly Poly::power(int n) const
445//
446// Retourne le polynôme à la puissance n
447//--
448
449Poly Poly::power(int n) const // a accelerer !!!
450{
451 if (n < 0) THROW(rangeCheckErr);
452 if (n == 0) { Poly r(0); r[0] = 1; return r;}
453 if (n == 1) { return *this; }
454 return *this * power(n-1);
455}
456
457//++
458Poly Poly::operator() (Poly const& b) const
459//
460// Substitution d'un polynôme dans un autre.
461//--
462{
463 Poly c(b.Degre()*Degre());
464 for (int i=0; i<= Degre(); i++)
465 c += (*this)[i] * b.power(i);
466 return c;
467}
468
469
470// ******************* POLY 2 VARIABLES ******************
471
472//++
473// Class Poly2
474// Lib Outils++
475// include poly.h
476//
477// Classe de calcul sur polynômes à deux variables.
478//--
479
480//++
481// Links Parents
482// Vector
483//--
484
485//++
486// Titre Constructeurs
487//--
488
489//++
490Poly2::Poly2(int degreX, int degreY)
491//
492// Crée un polynôme de degrés partiels degreX et degreY.
493//--
494:Vector((degreX+1)*(degreY+1)), dirty(0),
495 maxDegX(degreX), maxDegY(degreY), degX(0), degY(0), deg(0)
496{
497 END_CONSTRUCTOR
498}
499
500//++
501Poly2::Poly2(Poly const& polX, Poly const& polY)
502//
503// Crée un polynôme à deux variables comme produit
504// de deux polynômes à une variable, p2(x,y)=px(x)py(y)
505//--
506:Vector((polX.Degre()+1)*(polY.Degre()+1)), dirty(0),
507 maxDegX(polX.Degre()), maxDegY(polY.Degre()),
508 degX(polX.Degre()), degY(polY.Degre()), deg(degX+degY)
509{
510 for (int i=0; i<=degX; i++)
511 for (int j=0; j<=degY; j++)
512 Coef(i,j) = polX[i]*polY[j];
513 END_CONSTRUCTOR
514}
515
516//++
517Poly2::Poly2(Poly2 const& a)
518//
519// Constructeur par copie.
520//--
521:Vector(a), dirty(a.dirty),
522 maxDegX(a.maxDegX), maxDegY(a.maxDegY),
523 degX(a.degX), degY(a.degY), deg(a.deg)
524{
525 END_CONSTRUCTOR
526}
527
528
529//++
530// Titre Méthodes
531//--
532
533//++
534Poly2& Poly2::operator = (Poly2 const& a)
535//
536// Opérateur d'affectation.
537//--
538{
539 if (this == &a) return *this;
540 if (maxDegX < a.DegX() || maxDegY < a.DegY())
541 Realloc(a.DegX(), a.DegY());
542
543
544 for (int i=0; i<= maxDegX; i++)
545 for (int j=0; j<= maxDegY; j++)
546 Coef(i,j) = a.Coef(i,j);
547
548 UpdateDeg();
549 return *this;
550}
551
552//++
553void Poly2::Realloc(int degreX, int degreY)
554//
555// Redimensionne le polynôme comme etant un
556// polynôme de degrés partiels degreX et degreY.
557//--
558{
559 UpdateDegIfDirty();
560 Poly2 tmp(*this);
561 Vector::Realloc((degreX+1)*(degreY+1));
562 Zero();
563 maxDegX = degreX;
564 maxDegY = degreY;
565
566 for (int i=0; i<= tmp.degX; i++)
567 for (int j=0; j<= tmp.degY; j++)
568 Coef(i,j) = tmp.Coef(i,j);
569}
570
571
572void Poly2::UpdateDeg() const
573{
574 (int&)degX=(int&)degY=(int&)deg=0;
575
576 for (int dx=0; dx<=maxDegX; dx++)
577 for (int dy=0; dy<=maxDegY; dy++)
578 if (Coef(dx,dy) != 0) {
579 if (dx > degX) (int&)degX = dx;
580 if (dy > degY) (int&)degY = dy;
581 if (dx+dy > deg) (int&)deg = dx+dy;
582 }
583
584 (int&)dirty = 0;
585}
586
587//++
588// int Poly2::DegX() const
589// Degré partiel en X.
590// int Poly2::DegY() const
591// Degré partiel en Y
592// int Poly2::MaxDegX() const
593// Degré partiel maximum (alloué) en X
594// int Poly2::MaxDegY() const
595// Degré partiel maximum (alloué) en Y
596// int Poly2::Deg() const
597// Degré total.
598//--
599
600//++
601// double& Poly2::Coef(int dx, int dy)
602// Retourne le coefficient de x^dx y^dy
603// (avec aussi version const).
604//--
605
606//++
607double Poly2::operator()(double x, double y) const
608//
609// Retourne la valeur en (x,y).
610//--
611{
612 UpdateDegIfDirty();
613 double res = 0;
614 double xPow = 1;
615 for (int dx=0; dx<=maxDegX; dx++) {
616 double yPow = 1;
617 for (int dy=0; dy<=maxDegY; dy++) {
618 res += Coef(dx,dy) * xPow * yPow;
619 yPow *= y;
620 }
621 xPow *= x;
622 }
623 return res;
624}
625
626//++
627double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
628 int degreX, int degreY)
629//
630// Ajustement par moindre carrés z = P(x,y), degrés partiels imposés.
631//--
632{
633 int n = x.NElts();
634 if (n != y.NElts()) THROW(sizeMismatchErr);
635 if (n != z.NElts()) THROW(sizeMismatchErr);
636
637 Realloc(degreX, degreY);
638
639 Matrix a((degreX+1)*(degreY+1), n);
640
641 for (int c=0; c<n; c++) {
642 double xPow = 1.0;
643 for (int dx = 0; dx <= degreX; dx++) {
644 double yPow = 1.0;
645 for (int dy = 0; dy <= degreY; dy++) {
646 a(IndCoef(dx,dy), c) = xPow*yPow;
647 yPow *= y(c);
648 }
649 xPow *= x(c);
650 }
651 }
652
653 double rc = LinFit(a,z,(Vector&)*this);
654 UpdateDeg();
655 return rc;
656}
657
658
659//++
660double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
661 Vector const& errz2, int degreX, int degreY,
662 Vector& errCoef)
663//
664// Ajustement par moindre carrés z = P(x,y), degrés partiels imposés,
665// et erreurs^2 sur z dans errz2.
666//--
667{
668 int n = x.NElts();
669 if (n != y.NElts()) THROW(sizeMismatchErr);
670 if (n != z.NElts()) THROW(sizeMismatchErr);
671 if (n != errz2.NElts()) THROW(sizeMismatchErr);
672
673 Realloc(degreX, degreY);
674 errCoef.Realloc((degreX+1)*(degreY+1));
675
676 Matrix a((degreX+1)*(degreY+1), n);
677
678 for (int c=0; c<n; c++) {
679 double xPow = 1.0;
680 for (int dx = 0; dx <= degreX; dx++) {
681 double yPow = 1.0;
682 for (int dy = 0; dy <= degreY; dy++) {
683 a(IndCoef(dx,dy), c) = xPow*yPow;
684 yPow *= y(c);
685 }
686 xPow *= x(c);
687 }
688 }
689
690 double rc = LinFit(a,z,errz2,(Vector&)*this,errCoef);
691 UpdateDeg();
692 return rc;
693}
694
695//++
696double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
697 int degre)
698//
699// Ajustement par moindre carrés z = P(x,y), degré total imposé.
700//--
701{
702 int n = x.NElts();
703 if (n != y.NElts()) THROW(sizeMismatchErr);
704 if (n != z.NElts()) THROW(sizeMismatchErr);
705
706 Realloc(degre, degre); // certains vaudront 0, impose.
707
708 Matrix a((degre+1)*(degre+2)/2, n);
709 Vector cf((degre+1)*(degre+2)/2);
710#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
711
712 for (int c=0; c<n; c++) {
713 double xPow = 1.0;
714 for (int dx = 0; dx <= degre; dx++) {
715 double yPow = 1.0;
716 for (int dy = 0; dy <= degre; dy++) {
717 if (dy+dx <= degre)
718 a(C_INDEX(dx,dy), c) = xPow*yPow;
719 yPow *= y(c);
720 }
721 xPow *= x(c);
722 }
723 }
724
725 double rc = LinFit(a,z,cf);
726
727 for (int dx = 0; dx <= degre; dx++)
728 for (int dy = 0; dy <= degre; dy++)
729 if (dx+dy <= degre)
730 Coef(dx,dy) = cf(C_INDEX(dx,dy));
731 else
732 Coef(dx,dy) = 0;
733
734 UpdateDeg();
735 return rc;
736}
737
738
739//++
740double Poly2::Fit(Vector const& x, Vector const& y, Vector const& z,
741 Vector const& errz2, int degre,
742 Vector& errCoef)
743//
744// Ajustement par moindre carrés z = P(x,y), degré total imposé,
745// et erreurs^2 sur z dans errz2.
746//--
747{
748 int n = x.NElts();
749 if (n != y.NElts()) THROW(sizeMismatchErr);
750 if (n != z.NElts()) THROW(sizeMismatchErr);
751 if (n != errz2.NElts()) THROW(sizeMismatchErr);
752
753 Realloc(degre, degre);
754 errCoef.Realloc((degre+1)*(degre+1));
755#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
756
757 Matrix a((degre+1)*(degre+2)/2, n);
758 Vector cf((degre+1)*(degre+2)/2);
759 Vector ecf((degre+1)*(degre+2)/2);
760
761 for (int c=0; c<n; c++) {
762 double xPow = 1.0;
763 for (int dx = 0; dx <= degre; dx++) {
764 double yPow = 1.0;
765 for (int dy = 0; dy <= degre; dy++) {
766 if (dy+dx <= degre)
767 a(C_INDEX(dx,dy), c) = xPow*yPow;
768 yPow *= y(c);
769 }
770 xPow *= x(c);
771 }
772 }
773
774 double rc = LinFit(a,z,errz2,cf,ecf);
775
776
777 for (int dx = 0; dx <= degre; dx++)
778 for (int dy = 0; dy <= degre; dy++)
779 if (dx+dy <= degre) {
780 Coef(dx,dy) = cf(C_INDEX(dx,dy));
781 errCoef(IndCoef(dx,dy)) = ecf(C_INDEX(dx,dy));
782 } else {
783 Coef(dx,dy) = 0;
784 errCoef(IndCoef(dx,dy)) = 0;
785 }
786 UpdateDeg();
787 return rc;
788}
789
790
791void Poly2::ReadSelf(PInPersist& s)
792{
793 int_4 dgx, dgy;
794 s >> dgx >> dgy;
795
796 Realloc(dgx, dgy);
797
798 #ifdef DEBUG
799 int r = nr; int c = nc;
800 #endif
801
802 Vector::ReadSelf(s);
803
804 DBASSERT(r == nr && c == nc);
805 UpdateDeg();
806}
807
808void Poly2::WriteSelf(POutPersist& s) const
809{
810 s << maxDegX << maxDegY;
811 Vector::WriteSelf(s);
812}
813
814//++
815void Poly2::Print(ostream& s) const
816//
817// Impression sur stream s.
818//--
819{
820 UpdateDegIfDirty();
821 int nz=0;
822 int notfirst=0;
823 for (int dx = degX; dx>=0; dx--)
824 for (int dy= degY; dy>=0; dy--) {
825 double c = Coef(dx,dy);
826 if (c != 0) {
827 nz = 1;
828 if (notfirst && c > 0) {
829 s << "+";
830 notfirst = 1;
831 }
832 s << c << " ";
833 if (dx == 1) s << "* X ";
834 if (dx > 1) s << "* X^" << dx << " ";
835 if (dy == 1) s << "* Y ";
836 if (dy > 1) s << "* Y^" << dy << " ";
837 s << endl;
838 }
839 }
840 if (!nz) s << " 0 ";
841}
842
843//++
844ostream& operator << (ostream& s, const Poly2& a)
845//
846// Impression sur stream s.
847//--
848{
849 a.Print(s);
850 return s;
851}
852
853
854//++
855// Titre Opérations
856//--
857
858//++
859Poly2& Poly2::operator += (Poly2 const& b)
860//
861//--
862{
863 if (maxDegX < b.DegX() || maxDegY < b.DegY())
864 Realloc(b.DegX(),b.DegY());
865
866 UpdateDegIfDirty();
867
868 int mx = b.DegX();
869 int my = b.DegY();
870 for (int i=0; i<= mx; i++)
871 for (int j=0; j<= my; j++)
872 Coef(i,j) += b.Coef(i,j);
873
874 UpdateDeg();
875 return *this;
876}
877
878//++
879Poly2& Poly2::operator -= (Poly2 const& b)
880//
881//--
882{
883 if (maxDegX < b.DegX() || maxDegY < b.DegY())
884 Realloc(b.DegX(),b.DegY());
885
886 UpdateDegIfDirty();
887
888 int mx = b.DegX();
889 int my = b.DegY();
890 for (int i=0; i<= mx; i++)
891 for (int j=0; j<= my; j++)
892 Coef(i,j) -= b.Coef(i,j);
893
894 UpdateDeg();
895 return *this;
896}
897
898//++
899Poly2 operator+ (Poly2 const& a, Poly2 const& b)
900//
901//--
902#if HAS_NAMED_RETURN
903 return c(a)
904#endif
905{
906#if !HAS_NAMED_RETURN
907Poly2 c(a);
908#endif
909 c += b;
910#if !HAS_NAMED_RETURN
911return c;
912#endif
913}
914
915//++
916Poly2 operator- (Poly2 const& a, Poly2 const& b)
917//
918//--
919#if HAS_NAMED_RETURN
920 return c(a)
921#endif
922{
923#if !HAS_NAMED_RETURN
924Poly2 c(a);
925#endif
926 c -= b;
927#if !HAS_NAMED_RETURN
928return c;
929#endif
930}
931
932//++
933Poly2& Poly2::operator *= (double a)
934//
935//--
936{
937 for (int i=0; i<NElts(); i++)
938 data[i] *= a;
939
940 return *this;
941}
942
943//++
944Poly2 operator * (double a, Poly2 const& b)
945//
946//--
947#if HAS_NAMED_RETURN
948 return c(b)
949#endif
950{
951#if !HAS_NAMED_RETURN
952Poly2 c(b);
953#endif
954 c *= a;
955#if !HAS_NAMED_RETURN
956return c;
957#endif
958}
959
960//++
961Poly2 operator* (Poly2 const& a, Poly2 const& b)
962//
963//--
964{
965 Poly2 c(a.DegX() + b.DegX(), a.DegY() + b.DegY());
966 a.UpdateDegIfDirty();
967 b.UpdateDegIfDirty();
968
969 for (int i=0; i<=a.DegX(); i++)
970 for (int j=0; j<=a.DegY(); j++)
971 for (int k=0; k<=b.DegX(); k++)
972 for (int l=0; l<=b.DegY(); l++)
973 c.Coef(i+k,j+l) += a.Coef(i,j)*b.Coef(k,l);
974 return c;
975}
976
977//++
978Poly2 Poly2::power(int n) const
979//
980// Calcule le polynôme P(x,y)^n
981//--
982{
983 if (n < 0) THROW(rangeCheckErr);
984 if (n == 0) { Poly2 r(0); r.Coef(0,0) = 1; return r;}
985 if (n == 1) { return *this; }
986 return *this * power(n-1);
987}
988
989
990//++
991Poly2 Poly2::operator() (Poly const& a, Poly const& b) const
992//
993// Substitution de deux polynômes en X et Y,
994// P2(pa(x), pb(y)).
995//--
996{
997 UpdateDegIfDirty();
998 Poly2 c(maxDegX*a.Degre(), maxDegY*b.Degre());
999
1000 for (int i=0; i<= degX; i++)
1001 for (int j=0; j<= degY; j++) {
1002 Poly2 d(a.power(i), b.power(j));
1003 c += Coef(i,j) * d;
1004 }
1005
1006 return c;
1007}
1008
1009//++
1010Poly2 Poly::operator() (Poly2 const& a) const
1011//
1012// Substitution d'un polynôme à deux variables dans
1013// un polynôme à une variable, P(P2(x,y)).
1014//--
1015{
1016 Poly2 c(a.MaxDegX()*Degre(), a.MaxDegY()*Degre());
1017
1018 for (int i=0; i<= Degre(); i++)
1019 c += (*this)[i] * a.power(i);
1020 return c;
1021}
1022
1023
Note: See TracBrowser for help on using the repository browser.