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

Last change on this file since 2384 was 2344, checked in by ansari, 23 years ago

Compilation (fin ?) avec SGI-CC -LANG:std - Reza 10/03/2003

File size: 18.8 KB
Line 
1#include "machdefs.h"
2#include "poly.h"
3#include "linfit.h"
4#include "fioarr.h"
5
6////////////////////////////////////////////////////////////
7////////////////////////////////////////////////////////////
8////////////////////////////////////////////////////////////
9////////////////////////////////////////////////////////////
10////////////////////////////////////////////////////////////
11/*!
12 \class SOPHYA::Poly
13 \ingroup NTools
14 One dimensional polynomials class.
15*/
16
17//! Constructor
18/*! Create a 1D polynomial of degre \b degre */
19Poly::Poly(int degre)
20: TVector<r_8>(degre+1), dirty(0), deg(0)
21{
22 END_CONSTRUCTOR
23}
24
25//! Constructor by copy
26Poly::Poly(Poly const& a)
27:TVector<r_8>(a), dirty(a.dirty), deg(a.deg)
28{
29 END_CONSTRUCTOR
30}
31
32//! update degre
33/*! update degre (that could be changed after operations) */
34void Poly::UpdateDeg() const
35{
36 int i = NElts()-1;
37 while (Element(i) == 0 && i>0) i--;
38
39 (int&) deg = i; // bientot mutable dans ANSI C++
40 (int&) dirty = 0;
41}
42
43//! compute value P(\b x)
44double Poly::operator()(double x) const
45{
46 UpdateDegIfDirty();
47 double res = Element(deg);
48 for (int i=deg-1; i>=0; i--) {
49 res *= x;
50 res += Element(i);
51 }
52 return res;
53}
54
55//! Replace p(x) by its derivate
56void Poly::Derivate()
57{
58 UpdateDegIfDirty();
59 if (deg == 0) { Element(0) = 0; return;}
60 for (int i=1; i<=deg; i++)
61 Element(i-1) = Element(i)*i;
62 Element(deg) = 0;
63 deg--;
64}
65
66
67//! Return the derivate in \b der(x)
68void Poly::Derivate(Poly& der) const
69{
70 UpdateDegIfDirty();
71 der.Realloc(deg);
72// der.Zero(); // on sait que Realloc met a zero le reste.
73 for (int i=1; i<=deg; i++)
74 der.Element(i-1) = Element(i)*i;
75}
76
77
78//! Return the roots of the polynomial into \b roots
79/*!
80 This works until degre 2
81 \return the number of roots
82*/
83int Poly::Roots(TVector<r_8>& roots) const
84{
85 UpdateDegIfDirty();
86
87 switch (deg)
88 {
89 case 0 : // degre 0
90 return 0;
91 case 1 : // degre 1
92 roots.Realloc(1);
93 return Root1(roots(0));
94 case 2 : // degre 2
95 roots.Realloc(2);
96 return Root2(roots(0),roots(1));
97 default :
98 THROW(parmErr);
99 }
100}
101
102
103//! Return root \b r for a degre 1 polynomial
104/*! \return return 1 if succes, 0 if not */
105int Poly::Root1(double& r) const
106{
107 UpdateDegIfDirty();
108 if (deg != 1) THROW(sizeMismatchErr);
109
110 if (Element(1) == 0) return 0;
111 r = -Element(0)/Element(1);
112 return 1;
113}
114
115//! Return roots \b r1 and \b r2 for a degre 2 polynomial
116/*! \return return the number of roots found */
117int Poly::Root2(double& r1, double& r2) const
118{
119 UpdateDegIfDirty();
120 if (deg != 2) THROW(sizeMismatchErr);
121
122 double delta = Element(1)*Element(1) - 4*Element(0)*Element(2);
123 if (delta < 0) return 0;
124 if (delta == 0) {
125 r1 = r2 = -Element(1)/2/Element(0);
126 return 1;
127 }
128 r1 = (-Element(1) - sqrt(delta))/2/Element(0);
129 r2 = (-Element(1) + sqrt(delta))/2/Element(0);
130 return 2;
131}
132
133//! Operator P(x) = a(x)
134Poly& Poly::operator = (Poly const& a)
135{
136 if (this == &a) return *this;
137 TVector<r_8>::operator=(a);
138
139 UpdateDeg();
140 return *this;
141}
142
143//! Perform P(x) += b(x)
144Poly& Poly::operator += (Poly const& b)
145{
146 UpdateDegIfDirty();
147 b.UpdateDegIfDirty();
148
149 if (b.deg > deg) Realloc(b.deg);
150
151 int n = (deg > b.deg) ? deg : b.deg;
152 for (int i=0; i<=n; i++) Element(i) += b.Element(i);
153
154 UpdateDeg();
155 return *this;
156}
157
158//! Perform P(x) -= b(x)
159Poly& Poly::operator -= (Poly const& b)
160{
161 UpdateDegIfDirty();
162 b.UpdateDegIfDirty();
163
164 if (b.deg > deg) Realloc(b.deg);
165
166 int n = (deg > b.deg) ? deg : b.deg;
167 for (int i=0; i<=n; i++) Element(i) -= b.Element(i);
168
169 UpdateDeg();
170 return *this;
171}
172
173//! Perform P(x) *= b(x)
174Poly& Poly::operator *= (double a)
175{
176 UpdateDegIfDirty();
177 for (int i=0; i<=deg; i++) Element(i) *= a;
178 return *this;
179}
180
181//! Return P(x) = *this(x) * b(x)
182Poly Poly::Mult(Poly const& b) const
183{
184Poly c(deg + b.deg);
185 UpdateDegIfDirty();
186 b.UpdateDegIfDirty();
187
188 c.deg = deg + b.deg;
189
190 for (int i=0; i<=c.deg; i++) {
191 c[i] = 0;
192 int kmin = (i <= deg) ? 0 : i - deg;
193 int kmax = (i <= deg) ? i : deg;
194 for (int k=kmin; k<=kmax; k++)
195 c[i] += (*this)[k] * b[i-k];
196 }
197return c;
198}
199
200//! Print on stream \b s
201void Poly::Print(ostream& s, sa_size_t , bool, bool ) const
202{
203 UpdateDegIfDirty();
204 int nz=0;
205 for (int i = deg; i>=0; i--) {
206 if ((*this)[i] != 0) {
207 nz = 1;
208 if (i < deg && (*this)[i] > 0) s << "+";
209 s << (*this)[i];
210 if (i == 1) s << "*X ";
211 if (i > 1) s << "*X^" << i << " ";
212 }
213 }
214 if (!nz) s << " 0 ";
215}
216
217//! Fit datas by a polynomial
218/*!
219 Fit y(x) by a polynimial P(x)
220 \param x : x datas
221 \param y : y datas
222 \param degre : degre of the polynomial P(x) to be fitted
223 \warning result is stored in the current object
224 \return return chisquare
225*/
226double Poly::Fit(TVector<r_8> const& x, TVector<r_8> const& y, int degre)
227{
228 int n = x.NElts();
229 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
230
231 Realloc(degre);
232
233 TMatrix<r_8> a(degre+1, n);
234
235 for (int c=0; c<n; c++) {
236 double xpow = 1.0;
237 for (int l=0; l<=degre; l++) {
238 a(l,c) = xpow;
239 xpow *= x(c);
240 }
241 }
242
243 LinFitter<r_8> lf;
244 double rc = lf.LinFit(a,y,(TVector<r_8>&)*this);
245 UpdateDeg();
246 return rc;
247}
248
249//! Fit datas with errors by a polynomial
250/*!
251 Fit y(x) by a polynimial P(x)
252 \param x : x datas
253 \param y : y datas
254 \param erry2 : errors squared on y
255 \param degre : degre of the polynomial P(x) to be fitted
256 \warning result is stored in the current object
257 \return \b errcoeff : errors on the coefficients
258 \return return chisquare
259*/
260double Poly::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
261 TVector<r_8> const& erry2, int degre,TVector<r_8>& errCoef)
262{
263 int n = x.NElts();
264 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
265 if (n != (int)erry2.NElts()) THROW(sizeMismatchErr);
266
267 Realloc(degre);
268 errCoef.Realloc(degre+1);
269
270 TMatrix<r_8> a(degre+1, n);
271
272 for (int c=0; c<n; c++) {
273 double xpow = 1.0;
274 for (int l=0; l<=degre; l++) {
275 a(l,c) = xpow;
276 xpow *= x(c);
277 }
278 }
279
280 LinFitter<r_8> lf;
281 double rc = lf.LinFit(a,y,erry2,(TVector<r_8>&)*this,errCoef);
282 UpdateDeg();
283 return rc;
284}
285
286
287//! Return the polynomial at power \b n : ( \f$ P(x)^n \f$ )
288Poly Poly::power(int n) const // a accelerer !!!
289{
290 if (n < 0) THROW(rangeCheckErr);
291 if (n == 0) { Poly r(0); r[0] = 1; return r;}
292 if (n == 1) { return *this; }
293 return *this * power(n-1);
294}
295
296//! Substitue polynomial and return P\f$ (b(x)) \f$
297Poly Poly::operator() (Poly const& b) const
298{
299 Poly c(b.Degre()*Degre());
300 for (int i=0; i<= Degre(); i++)
301 c += (*this)[i] * b.power(i);
302 return c;
303}
304
305
306//////////////////////////////////////////////////////////////////////////
307//! For persistance management
308DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
309void ObjFileIO<Poly>::ReadSelf(PInPersist& is)
310{
311if(dobj==NULL) dobj=new Poly;
312int_4 dg;
313is >> dg;
314dobj->Realloc(dg,true);
315is >> *((TVector<r_8> *) dobj);
316dobj->UpdateDeg();
317}
318
319//! For persistance management
320DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
321void ObjFileIO<Poly>::WriteSelf(POutPersist& os) const
322{
323if(dobj == NULL) return;
324dobj->UpdateDegIfDirty();
325dobj->Realloc(dobj->deg,true);
326os << dobj->deg;
327os << *((TVector<r_8> *) dobj);
328}
329
330//////////////////////////////////////////////////////////////////////////
331/*! \ingroup NTools
332 \fn binomial(int,int)
333 Return the binomial coefficient \f$ {C_n}^p \f$.
334*/
335int binomial(int n, int p)
336{
337 int c = 1;
338 for (int i=n-p+1; i<=n; i++) c *= i;
339 for (int j=2; j<=p; j++) c /= j;
340 return c;
341}
342
343
344////////////////////////////////////////////////////////////
345////////////////////////////////////////////////////////////
346////////////////////////////////////////////////////////////
347////////////////////////////////////////////////////////////
348////////////////////////////////////////////////////////////
349/*!
350 \class SOPHYA::Poly2
351 \ingroup NTools
352 Two dimensional polynomials class.
353*/
354
355//! Constructor of 2D polynomial of degres \b degreX \b degreY
356Poly2::Poly2(int degreX, int degreY)
357:TVector<r_8>((degreX+1)*(degreY+1)), dirty(0),
358 maxDegX(degreX), maxDegY(degreY), degX(0), degY(0), deg(0)
359{
360 END_CONSTRUCTOR
361}
362
363//! Constructor of 2D polynomial \f$ P(x,y) = px(x) * py(y) \f$
364Poly2::Poly2(Poly const& polX, Poly const& polY)
365:TVector<r_8>((polX.Degre()+1)*(polY.Degre()+1)), dirty(0),
366 maxDegX(polX.Degre()), maxDegY(polY.Degre()),
367 degX(polX.Degre()), degY(polY.Degre()), deg(degX+degY)
368{
369 for (int i=0; i<=degX; i++)
370 for (int j=0; j<=degY; j++)
371 Coef(i,j) = polX[i]*polY[j];
372 END_CONSTRUCTOR
373}
374
375//! Constructor by copy
376Poly2::Poly2(Poly2 const& a)
377:TVector<r_8>(a), dirty(a.dirty),
378 maxDegX(a.maxDegX), maxDegY(a.maxDegY),
379 degX(a.degX), degY(a.degY), deg(a.deg)
380{
381 END_CONSTRUCTOR
382}
383
384//! Operator P(x) = a(x)
385Poly2& Poly2::operator = (Poly2 const& a)
386{
387 if (this == &a) return *this;
388 if (maxDegX < a.DegX() || maxDegY < a.DegY())
389 Realloc(a.DegX(), a.DegY());
390
391
392 for (int i=0; i<= maxDegX; i++)
393 for (int j=0; j<= maxDegY; j++)
394 Coef(i,j) = a.Coef(i,j);
395
396 UpdateDeg();
397 return *this;
398}
399
400//! Re-allocate space for 2D polynomial with partial degres \b degreX \b degreY
401void Poly2::Realloc(int degreX, int degreY)
402{
403 UpdateDegIfDirty();
404 Poly2 tmp(*this);
405 TVector<r_8>::Realloc((degreX+1)*(degreY+1));
406 DataBlock().Reset();
407 maxDegX = degreX;
408 maxDegY = degreY;
409
410// Attention - Reza 30/09/99
411// il faut prendre le min en degre du polynome de depart et le nouveau
412 int cdegx = (tmp.degX < degreX) ? tmp.degX : degreX;
413 int cdegy = (tmp.degY < degreY) ? tmp.degY : degreY;
414 for (int i=0; i<= cdegx; i++)
415 for (int j=0; j<= cdegy; j++)
416 Coef(i,j) = tmp.Coef(i,j);
417}
418
419
420//! update degres
421/*! update degres (that could be changed after operations) */
422void Poly2::UpdateDeg() const
423{
424 (int&)degX=(int&)degY=(int&)deg=0;
425
426 for (int dx=0; dx<=maxDegX; dx++)
427 for (int dy=0; dy<=maxDegY; dy++)
428 if (Coef(dx,dy) != 0) {
429 if (dx > degX) (int&)degX = dx;
430 if (dy > degY) (int&)degY = dy;
431 if (dx+dy > deg) (int&)deg = dx+dy;
432 }
433
434 (int&)dirty = 0;
435}
436
437//! Return P(\b x, \b y)
438double Poly2::operator()(double x, double y) const
439{
440 UpdateDegIfDirty();
441 double res = 0;
442 double xPow = 1;
443 for (int dx=0; dx<=maxDegX; dx++) {
444 double yPow = 1;
445 for (int dy=0; dy<=maxDegY; dy++) {
446 res += Coef(dx,dy) * xPow * yPow;
447 yPow *= y;
448 }
449 xPow *= x;
450 }
451 return res;
452}
453
454//! Fit datas by a polynomial
455/*!
456 Fit z(x,y) by a polynimial P(x,y)
457 \param x : x datas
458 \param y : y datas
459 \param z : z datas
460 \param degreX : partial degre on X
461 \param degreY : partial degre on Y
462 \warning result is stored in the current object
463 \return return chisquare
464*/
465double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
466 TVector<r_8> const& z, int degreX, int degreY)
467{
468 int n = x.NElts();
469 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
470 if (n != (int)z.NElts()) THROW(sizeMismatchErr);
471
472 Realloc(degreX, degreY);
473
474 TMatrix<r_8> a((degreX+1)*(degreY+1), n);
475
476 for (int c=0; c<n; c++) {
477 double xPow = 1.0;
478 for (int dx = 0; dx <= degreX; dx++) {
479 double yPow = 1.0;
480 for (int dy = 0; dy <= degreY; dy++) {
481 a(IndCoef(dx,dy), c) = xPow*yPow;
482 yPow *= y(c);
483 }
484 xPow *= x(c);
485 }
486 }
487
488 LinFitter<r_8> lf;
489 double rc = lf.LinFit(a,z,(TVector<r_8>&)*this);
490 UpdateDeg();
491 return rc;
492}
493
494//! Fit datas with errors by a polynomial
495/*!
496 Fit z(x,y) by a polynimial P(x,y)
497 \param x : x datas
498 \param y : y datas
499 \param z : z datas
500 \param errz2 : errors squared on z
501 \param degreX : partial degre on X
502 \param degreY : partial degre on Y
503 \warning result is stored in the current object
504 \return \b errcoeff : errors on the coefficients
505 \return return chisquare
506*/
507double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
508 TVector<r_8> const& errz2, int degreX, int degreY,
509 TVector<r_8>& errCoef)
510{
511 int n = x.NElts();
512 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
513 if (n != (int)z.NElts()) THROW(sizeMismatchErr);
514 if (n != (int)errz2.NElts()) THROW(sizeMismatchErr);
515
516 Realloc(degreX, degreY);
517 errCoef.Realloc((degreX+1)*(degreY+1));
518
519 TMatrix<r_8> a((degreX+1)*(degreY+1), n);
520
521 for (int c=0; c<n; c++) {
522 double xPow = 1.0;
523 for (int dx = 0; dx <= degreX; dx++) {
524 double yPow = 1.0;
525 for (int dy = 0; dy <= degreY; dy++) {
526 a(IndCoef(dx,dy), c) = xPow*yPow;
527 yPow *= y(c);
528 }
529 xPow *= x(c);
530 }
531 }
532
533 LinFitter<r_8> lf;
534 double rc = lf.LinFit(a,z,errz2,(TVector<r_8>&)*this,errCoef);
535 UpdateDeg();
536 return rc;
537}
538
539//! Fit datas by a polynomial
540/*!
541 Fit z(x,y) by a polynimial P(x,y)
542 \param x : x datas
543 \param y : y datas
544 \param z : z datas
545 \param degre : total degre
546 \warning result is stored in the current object
547 \return return chisquare
548*/
549double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
550 TVector<r_8> const& z, int degre)
551{
552 int n = x.NElts();
553 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
554 if (n != (int)z.NElts()) THROW(sizeMismatchErr);
555
556 Realloc(degre, degre); // certains vaudront 0, impose.
557
558 TMatrix<r_8> a((degre+1)*(degre+2)/2, n);
559 TVector<r_8> cf((degre+1)*(degre+2)/2);
560#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
561
562 for (int c=0; c<n; c++) {
563 double xPow = 1.0;
564 for (int dx = 0; dx <= degre; dx++) {
565 double yPow = 1.0;
566 for (int dy = 0; dy <= degre; dy++) {
567 if (dy+dx <= degre)
568 a(C_INDEX(dx,dy), c) = xPow*yPow;
569 yPow *= y(c);
570 }
571 xPow *= x(c);
572 }
573 }
574
575 LinFitter<r_8> lf;
576 double rc = lf.LinFit(a,z,cf);
577
578 for (int dx = 0; dx <= degre; dx++)
579 for (int dy = 0; dy <= degre; dy++)
580 if (dx+dy <= degre)
581 Coef(dx,dy) = cf(C_INDEX(dx,dy));
582 else
583 Coef(dx,dy) = 0;
584
585 UpdateDeg();
586 return rc;
587}
588
589//! Fit datas with errors by a polynomial
590/*!
591 Fit z(x,y) by a polynimial P(x,y)
592 \param x : x datas
593 \param y : y datas
594 \param z : z datas
595 \param errz2 : errors squared on z
596 \param degre : total degre
597 \warning result is stored in the current object
598 \return \b errcoeff : errors on the coefficients
599 \return return chisquare
600*/
601double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
602 TVector<r_8> const& z,TVector<r_8> const& errz2,
603 int degre, TVector<r_8>& errCoef)
604{
605 int n = x.NElts();
606 if (n != (int)y.NElts()) THROW(sizeMismatchErr);
607 if (n != (int)z.NElts()) THROW(sizeMismatchErr);
608 if (n != (int)errz2.NElts()) THROW(sizeMismatchErr);
609
610 Realloc(degre, degre);
611 errCoef.Realloc((degre+1)*(degre+1));
612#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
613
614 TMatrix<r_8> a((degre+1)*(degre+2)/2, n);
615 TVector<r_8> cf((degre+1)*(degre+2)/2);
616 TVector<r_8> ecf((degre+1)*(degre+2)/2);
617
618 for (int c=0; c<n; c++) {
619 double xPow = 1.0;
620 for (int dx = 0; dx <= degre; dx++) {
621 double yPow = 1.0;
622 for (int dy = 0; dy <= degre; dy++) {
623 if (dy+dx <= degre)
624 a(C_INDEX(dx,dy), c) = xPow*yPow;
625 yPow *= y(c);
626 }
627 xPow *= x(c);
628 }
629 }
630
631 LinFitter<r_8> lf;
632 double rc = lf.LinFit(a,z,errz2,cf,ecf);
633
634
635 for (int dx = 0; dx <= degre; dx++)
636 for (int dy = 0; dy <= degre; dy++)
637 if (dx+dy <= degre) {
638 Coef(dx,dy) = cf(C_INDEX(dx,dy));
639 errCoef(IndCoef(dx,dy)) = ecf(C_INDEX(dx,dy));
640 } else {
641 Coef(dx,dy) = 0;
642 errCoef(IndCoef(dx,dy)) = 0;
643 }
644 UpdateDeg();
645 return rc;
646}
647
648//! Print on stream \b s
649void Poly2::Print(ostream& s, sa_size_t , bool, bool ) const
650{
651 UpdateDegIfDirty();
652 int nz=0;
653 int notfirst=0;
654 for (int dx = degX; dx>=0; dx--)
655 for (int dy= degY; dy>=0; dy--) {
656 double c = Coef(dx,dy);
657 if (c != 0) {
658 nz = 1;
659 if (notfirst && c > 0) {
660 s << "+";
661 notfirst = 1;
662 }
663 s << c << " ";
664 if (dx == 1) s << "* X ";
665 if (dx > 1) s << "* X^" << dx << " ";
666 if (dy == 1) s << "* Y ";
667 if (dy > 1) s << "* Y^" << dy << " ";
668 s << endl;
669 }
670 }
671 if (!nz) s << " 0 ";
672}
673
674//! Operator: return P(x) = *this(x) + b(x)
675Poly2& Poly2::operator += (Poly2 const& b)
676{
677 if (maxDegX < b.DegX() || maxDegY < b.DegY())
678 Realloc(b.DegX(),b.DegY());
679
680 UpdateDegIfDirty();
681
682 int mx = b.DegX();
683 int my = b.DegY();
684 for (int i=0; i<= mx; i++)
685 for (int j=0; j<= my; j++)
686 Coef(i,j) += b.Coef(i,j);
687
688 UpdateDeg();
689 return *this;
690}
691
692//! Operator: return P(x) = *this(x) - b(x)
693Poly2& Poly2::operator -= (Poly2 const& b)
694{
695 if (maxDegX < b.DegX() || maxDegY < b.DegY())
696 Realloc(b.DegX(),b.DegY());
697
698 UpdateDegIfDirty();
699
700 int mx = b.DegX();
701 int my = b.DegY();
702 for (int i=0; i<= mx; i++)
703 for (int j=0; j<= my; j++)
704 Coef(i,j) -= b.Coef(i,j);
705
706 UpdateDeg();
707 return *this;
708}
709
710//! Operator: return P(x) = *this(x) * a
711Poly2& Poly2::operator *= (double a)
712{
713 for (uint_4 i=0; i<NElts(); i++) Element(i) *= a;
714 return *this;
715}
716
717//! Operator: return P(x) = *this(x) * b(x)
718Poly2 Poly2::Mult(Poly2 const& b) const
719{
720 Poly2 c(DegX() + b.DegX(), DegY() + b.DegY());
721 UpdateDegIfDirty();
722 b.UpdateDegIfDirty();
723
724 for (int i=0; i<=DegX(); i++)
725 for (int j=0; j<=DegY(); j++)
726 for (int k=0; k<=b.DegX(); k++)
727 for (int l=0; l<=b.DegY(); l++)
728 c.Coef(i+k,j+l) += Coef(i,j)*b.Coef(k,l);
729 return c;
730}
731
732//! Return \f$ P(x,y)^n \f$
733Poly2 Poly2::power(int n) const
734{
735 if (n < 0) THROW(rangeCheckErr);
736 if (n == 0) { Poly2 r(0); r.Coef(0,0) = 1; return r;}
737 if (n == 1) { return *this; }
738 return *this * power(n-1);
739}
740
741
742//! substitute and return \f$ P(a(x),b(x)) \f$
743Poly2 Poly2::operator() (Poly const& a, Poly const& b) const
744{
745 UpdateDegIfDirty();
746 Poly2 c(maxDegX*a.Degre(), maxDegY*b.Degre());
747
748 for (int i=0; i<= degX; i++)
749 for (int j=0; j<= degY; j++) {
750 Poly2 d(a.power(i), b.power(j));
751 c += Coef(i,j) * d;
752 }
753
754 return c;
755}
756
757//! substitute and return 2D polynomial \f$ P(a(x,y)) \f$, P is a 1D polynomial
758Poly2 Poly::operator() (Poly2 const& a) const
759{
760 Poly2 c(a.MaxDegX()*Degre(), a.MaxDegY()*Degre());
761
762 for (int i=0; i<= Degre(); i++)
763 c += (*this)[i] * a.power(i);
764 return c;
765}
766
767//////////////////////////////////////////////////////////////////////////
768//! For persistance management
769DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
770void ObjFileIO<Poly2>::ReadSelf(PInPersist& is)
771{
772if(dobj==NULL) dobj=new Poly2;
773int_4 dgx, dgy;
774is >> dgx >> dgy;
775dobj->Realloc(dgx,dgy);
776is >> *((TVector<r_8> *) dobj);
777dobj->UpdateDeg();
778}
779
780//! For persistance management
781DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
782void ObjFileIO<Poly2>::WriteSelf(POutPersist& os) const
783{
784if(dobj == NULL) return;
785os << dobj->maxDegX << dobj->maxDegY;
786os << *((TVector<r_8> *) dobj);
787}
788
789
790//////////////////////////////////////////////////////////////////////////
791#ifdef __CXX_PRAGMA_TEMPLATES__
792#pragma define_template ObjFileIO<Poly>
793#pragma define_template ObjFileIO<Poly2>
794#endif
795
796#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
797template class ObjFileIO<Poly>;
798template class ObjFileIO<Poly2>;
799#endif
Note: See TracBrowser for help on using the repository browser.