// This may look like C code, but it is really -*- C++ -*- // // $Id: poly.h,v 1.11 2004-03-15 16:46:56 ansari Exp $ // // Des polynomes avec des operations de bases et surtout des fits. #ifndef POLY_SEEN #define POLY_SEEN #include "objfio.h" #include #include "peida.h" #include "tvector.h" #include "ppersist.h" #include "anydataobj.h" namespace SOPHYA { class Poly2; ////////////////////////////////////////////////////////////////////////// //! Class of 1 dimension polynomials P(x) class Poly : public TVector { friend class ObjFileIO; public: Poly(int degre = 0); Poly(Poly const& a); //! Return degre of polynomials inline int Degre() const {UpdateDegIfDirty(); return deg;} //! Return space for a \b n degre polynomial /*! \param \b n : degre of new polynomial \param \b force : force re-allocation if true,\ if not allocation occurs only if space needed is greater than the old one */ inline void Realloc(int n, bool force=false) {TVector::Realloc(n+1,force);} // Pour compatibilite PEIDA - Reza 03/2000 //! Return coefficient of degre \b i inline double Element(int i) const { return Elem(i,0,0,0,0); } //! Return coefficient of degre \b i inline double & Element(int i) { return Elem(i,0,0,0,0); } //! Return coefficient of degre \b i inline double operator[](int i) const {return Elem(i,0,0,0,0);} //! Return coefficient of degre \b i inline double& operator[](int i) {dirty = 1; return Elem(i,0,0,0,0);} // Retourne le coefficient de degre i double operator()(double x) const; // Retourne la valeur prise en x. void Derivate(); // Derive le polynome en place void Derivate(Poly& der) const; // Derive le polynome dans un autre int Roots(TVector& roots) const; // retourne les racines si on peut les calculer... int Root1(double& r) const; // special degre 1 int Root2(double& r1, double& r2) const; // special degre 2 Poly& operator = (Poly const& b); Poly& operator += (Poly const& b); Poly& operator -= (Poly const& b); Poly& operator *= (double a); Poly Mult(Poly const& b) const; Poly power(int n) const; Poly operator() (Poly const& b) const; Poly2 operator() (Poly2 const& b) const; void Print(ostream& s, sa_size_t maxprt=-1, bool si=false, bool ascd=false) const ; double Fit(TVector const& x, TVector const& y, int degre); // Fit d'un polynome de degre donne sur les x et y. double Fit(TVector const& x, TVector const& y, TVector const& erry2, int degre, TVector& errCoef); // En plus, on fournit les carres des erreurs sur y et on a les erreurs // sur les coefficients dans un vecteur. private: int dirty; int_4 deg; void UpdateDeg() const; void UpdateDegIfDirty() const {if (dirty) UpdateDeg();} }; /*! \ingroup NTools \fn operator*(Poly const&,Poly const&) \brief perform and return P(X) = a(x) * b(x) */ inline Poly operator* (Poly const& a, Poly const& b) { return a.Mult(b); } /*! \ingroup NTools \fn operator+(Poly const&,Poly const&) \brief perform and return P(X) = a(x) + b(x) */ inline Poly operator+ (Poly const& a, Poly const& b) { Poly c((a.Degre() > b.Degre())?(a.Degre()+1):(b.Degre()+1)); c = a; c += b; return c; } /*! \ingroup NTools \fn operator-(Poly const&,Poly const&) \brief perform and return P(X) = a(x) - b(x) */ inline Poly operator- (Poly const& a, Poly const& b) { Poly c((a.Degre() > b.Degre())?(a.Degre()+1):(b.Degre()+1)); c = a; c -= b; return c; } /*! \ingroup NTools \fn operator*(double,Poly const&) \brief perform and return P(X) = a * b(x) */ inline Poly operator* (double a, Poly const& b) { Poly c(b); c *= a; return c; } /*! \ingroup NTools \fn operator<<(ostream&,const Poly&) \brief Print a(x) on stream \b s */ inline ostream& operator << (ostream& s, const Poly& a) { a.Print(s); return s; } ////////////////////////////////////////////////////////////////////////// /*! \ingroup NTools \fn operator<<(POutPersist&,Poly&) \brief For persistance management */ inline POutPersist& operator << (POutPersist& os, Poly & obj) { ObjFileIO fio(&obj); fio.Write(os); return(os); } /*! \ingroup NTools \fn operator<<(PInPersist&,,Poly&) \brief For persistance management */ inline PInPersist& operator >> (PInPersist& is, Poly & obj) { ObjFileIO fio(&obj); fio.Read(is); return(is); } // Classe pour la gestion de persistance // ObjFileIO ////////////////////////////////////////////////////////////////////////// int binomial(int n, int p); ////////////////////////////////////////////////////////////////////////// //! Class of 2 dimensions polynomials P(x,y) class Poly2 : public TVector { friend class ObjFileIO; public: Poly2(int degreX=0, int degreY=0); // degres alloues. Poly2(Poly const& polX, Poly const& polY); Poly2(Poly2 const& a); //! Return polynomial partial degre for X inline int DegX() const {UpdateDegIfDirty(); return degX;} //! Return polynomial partial degre for Y inline int DegY() const {UpdateDegIfDirty(); return degY;} //! Return polynomial maximum partial degre for X inline int MaxDegX() const {return maxDegX;} //! Return polynomial maximum partial degre for Y inline int MaxDegY() const {return maxDegY;} //! Return polynomial total degre for X inline int Deg() const {UpdateDegIfDirty(); return deg;} // les degres partiels en x et y, et totaux. // Pour compatibilite PEIDA - Reza 03/2000 //! Return coefficient of degre \b i inline double Element(int i) const { return Elem(i,0,0,0,0); } //! Return coefficient of degre \b i inline double & Element(int i) { return Elem(i,0,0,0,0); } double operator()(double x, double y) const; // retourne la valeur en (x,y) //! Return index of coefficient of X^dx * Y^dy in the vector inline int IndCoef(int dx, int dy) const { if (dx>maxDegX || dy>maxDegY) throw RangeCheckError("Poly2::IndCoef()"); return dx + (maxDegX+1)*dy; } // l'indice du coefficient dans le vecteur. Public uniquement parce // que ca sert a recuperer les erreurs sur les coefficients lors // d'un fit... //! Return coefficient of X^dx * Y^dy inline double Coef(int dx, int dy) const { return (dx>maxDegX || dy>maxDegY) ? 0 : Element(IndCoef(dx,dy)); } //! Return coefficient of X^dx * Y^dy inline double& Coef(int dx, int dy) { if (dx>maxDegX || dy>maxDegY) throw RangeCheckError("Poly2::Coef() "); dirty = 1; return Element(IndCoef(dx,dy)); } // retourne le coefficient de degre (dx,dy) double Fit(TVector const& x, TVector const& y, TVector const& z, int degreX, int degreY); double Fit(TVector const& x, TVector const& y, TVector const& z, TVector const& errz2, int degreX, int degreY, TVector& errCoef); // degres partiels imposes. cf Poly::Fit sinon double Fit(TVector const& x, TVector const& y, TVector const& z, int degre); double Fit(TVector const& x, TVector const& y, TVector const& z, TVector const& errz2, int degre, TVector& errCoef); // degre total impose. cf Poly::Fit sinon Poly2& operator = (Poly2 const& b); Poly2& operator += (Poly2 const& b); Poly2& operator -= (Poly2 const& b); Poly2& operator *= (double a); Poly2 Mult(Poly2 const& b) const; Poly2 power(int n) const; Poly2 operator() (Poly const& px, Poly const& py) const; // Poly2 operator() (Poly2 const& px, Poly2 const& py) const; void Realloc(int degreX, int degreY); void Print(ostream& s, sa_size_t maxprt=-1, bool si=false, bool ascd=false) const ; private: int dirty; int_4 maxDegX; int_4 maxDegY; int degX; int degY; int deg; void UpdateDeg() const; void UpdateDegIfDirty() const {if (dirty) UpdateDeg();} }; /*! \ingroup NTools \fn operator*(Poly2 const&,Poly2 const&) \brief Perform P(x,y) = a(x,y) * b(x,y) */ inline Poly2 operator* (Poly2 const& a, Poly2 const& b) { return a.Mult(b); } /*! \ingroup NTools \fn operator+(Poly2 const&,Poly2 const&) \brief Perform P(x,y) = a(x,y) + b(x,y) */ inline Poly2 operator+ (Poly2 const& a, Poly2 const& b) { Poly2 c(a); c += b; return c; } /*! \ingroup NTools \fn operator-(Poly2 const&,Poly2 const&) \brief Perform P(x,y) = a(x,y) - b(x,y) */ inline Poly2 operator- (Poly2 const& a, Poly2 const& b) { Poly2 c(a); c -= b; return c; } /*! \ingroup NTools \fn operator-(double,Poly2 const&) \brief Perform P(x,y) = a * b(x,y) */ inline Poly2 operator * (double a, Poly2 const& b) { Poly2 c(b); c *= a; return c; } /*! \ingroup NTools \fn operator<<(ostream&,const Poly2&) \brief Print a(x,y) on stream \b s */ inline ostream& operator << (ostream& s, const Poly2& a) { a.Print(s); return s; } ////////////////////////////////////////////////////////////////////////// /*! \ingroup NTools \fn operator<<(POutPersist&,Poly2&) \brief For persistance management */ inline POutPersist& operator << (POutPersist& os, Poly2 & obj) { ObjFileIO fio(&obj); fio.Write(os); return(os); } /*! \ingroup NTools \fn operator<<(POutPersist&,Poly2&) \brief For persistance management */ inline PInPersist& operator >> (PInPersist& is, Poly2 & obj) { ObjFileIO fio(&obj); fio.Read(is); return(is); } // Classe pour la gestion de persistance // ObjFileIO } // Fin du namespace #endif // POLY_SEEN