FE_polynomial.h
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:21k
- ///////////////////////////////////////////////////////////////////////////////
- // This is a part of the Feature program.
- // Version: 1.0
- // Date: February 22, 2003
- // Programmer: Oh-Wook Kwon
- // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
- ///////////////////////////////////////////////////////////////////////////////
- #ifndef _FE_POLYNOMIAL_H_
- #define _FE_POLYNOMIAL_H_
- #include <cstdio>
- #include <cstdarg>
- #include <cmath>
- #include <cstring>
- #include <cstdlib>
- #include <typeinfo>
- #include <vector>
- using namespace std;
- #pragma warning(disable:4786)
- #include "FE_complex.h"
- template <typename T> class CPolynomial;
- // friend template functions
- template <typename T> CPolynomial<T> poly_plus(const CPolynomial<T>& A, const CPolynomial<T>& B);
- template <typename T> CPolynomial<T> poly_plus(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_plus(const double b, const CPolynomial<T>& A);
- template <typename T> CPolynomial<T> poly_minus(const CPolynomial<T>& A, const CPolynomial<T>& B);
- template <typename T> CPolynomial<T> poly_minus(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_minus(const double b, const CPolynomial<T>& A);
- template <typename T> CPolynomial<T> poly_times(const CPolynomial<T>& A, const CPolynomial<T>& B);
- template <typename T> CPolynomial<T> poly_times(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_times(const double b, const CPolynomial<T>& A);
- template <typename T> CPolynomial<T> poly_divide(const CPolynomial<T>& A, const CPolynomial<T>& B);
- template <typename T> CPolynomial<T> poly_divide(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_divide(const double b, const CPolynomial<T>& A);
- template <typename T> CPolynomial<T> poly_modulo(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_modulo(const CPolynomial<T>& A, const double b);
- template <typename T> CPolynomial<T> poly_modulo(const double b, const CPolynomial<T>& A);
- // GNU compiler gcc-2.95.2 cannot handle operator overloading with user-defined class type.
- #if 0
- template <typename T> CPolynomial<T> poly_plus(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- template <typename T> CPolynomial<T> poly_minus(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- template <typename T> CPolynomial<T> poly_times(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- template <typename T> CPolynomial<T> poly_divide(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- #endif
- template<typename T>
- class CPolynomial
- {
- typedef Complex<T> CComplex;
- public:
- CPolynomial();
- CPolynomial(const int v0) { v.resize(1); v[0]=(T)v0; }
- CPolynomial(const double v0) { v.resize(1); v[0]=(T)v0; }
- CPolynomial(int m, const T* a);
- CPolynomial(const char* a);
- CPolynomial(const CPolynomial<T>& a) : v(a.v) {}
- virtual ~CPolynomial();
- void Print() const;
- T Eval(T x, T* pd = NULL, int nd = 0) const;
- void Roots(CComplex* roots) const;
- void zroots(CComplex* a, int m, CComplex* roots, int polish) const;
- void laguer(CComplex* a, int m, CComplex* x, int *its) const;
- public:
- vector<T> v;
- CPolynomial<T> operator+();
- CPolynomial<T> operator-();
- CPolynomial<T>& operator=(const CPolynomial<T>& a);
- CPolynomial<T>& operator+=(const CPolynomial<T>& a);
- CPolynomial<T>& operator-=(const CPolynomial<T>& a);
- CPolynomial<T>& operator*=(const CPolynomial<T>& a);
- CPolynomial<T>& operator/=(const CPolynomial<T>& a);
- // GCC-2.95-2 did not allow friend operator overloading definition outside class declaration.
- friend CPolynomial<T> operator+(const CPolynomial<T>& A, const CPolynomial<T>& B) {
- return poly_plus(A,B);
- }
- friend CPolynomial<T> operator+(const CPolynomial<T>& A, const double b) {
- return poly_plus(A,b);
- }
- friend CPolynomial<T> operator+(const double b, const CPolynomial<T>& A) {
- return poly_plus(b,A);
- }
- friend CPolynomial<T> operator-(const CPolynomial<T>& A, const CPolynomial<T>& B) {
- return poly_minus(A,B);
- }
- friend CPolynomial<T> operator-(const CPolynomial<T>& A, const double b) {
- return poly_minus(A,b);
- }
- friend CPolynomial<T> operator-(const double b, const CPolynomial<T>& A) {
- return poly_minus(b,A);
- }
- friend CPolynomial<T> operator*(const CPolynomial<T>& A, const CPolynomial<T>& B) {
- return poly_times(A,B);
- }
- friend CPolynomial<T> operator*(const CPolynomial<T>& A, const double b) {
- return poly_times(A,b);
- }
- friend CPolynomial<T> operator*(const double b, const CPolynomial<T>& A) {
- return poly_times(b,A);
- }
- friend CPolynomial<T> operator/(const CPolynomial<T>& A, const CPolynomial<T>& B) {
- return poly_divide(A,B);
- }
- friend CPolynomial<T> operator/(const CPolynomial<T>& A, const double b) {
- return poly_divide(A,b);
- }
- friend CPolynomial<T> operator/(const double b, const CPolynomial<T>& A) {
- return poly_divide(b,A);
- }
- friend CPolynomial<T> operator%(const CPolynomial<T>& A, const CPolynomial<T>& B) {
- return poly_modulo(A,B);
- }
- friend CPolynomial<T> operator%(const CPolynomial<T>& A, const double b) {
- return poly_modulo(A,b);
- }
- friend CPolynomial<T> operator%(const double b, const CPolynomial<T>& A) {
- return poly_modulo(b,A);
- }
- #if 0
- friend CPolynomial<T> operator+(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B) {
- return poly_plus(A,B);
- }
- friend CPolynomial<T> operator+(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B) {
- return poly_minus(A,B);
- }
- friend CPolynomial<T> operator+(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B) {
- return poly_times(A,B);
- }
- friend CPolynomial<T> operator+(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B) {
- return poly_divide(A,B);
- }
- #endif
- #ifdef __GNUC__
- friend CPolynomial<T> poly_plus<T>(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_plus<T>(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_plus<T>(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_minus<T>(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_minus<T>(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_minus<T>(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_times<T>(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_times<T>(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_times<T>(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_divide<T>(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_divide<T>(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_divide<T>(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_modulo<T>(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_modulo<T>(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_modulo<T>(const double b, const CPolynomial<T>& A);
- #if 0
- friend CPolynomial<T> poly_plus<T>(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_minus<T>(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_times<T>(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_divide<T>(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- #endif
- #else
- friend CPolynomial<T> poly_plus(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_plus(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_plus(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_minus(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_minus(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_minus(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_times(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_times(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_times(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_divide(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_divide(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_divide(const double b, const CPolynomial<T>& A);
- friend CPolynomial<T> poly_modulo(const CPolynomial<T>& A, const CPolynomial<T>& B);
- friend CPolynomial<T> poly_modulo(const CPolynomial<T>& A, const double b);
- friend CPolynomial<T> poly_modulo(const double b, const CPolynomial<T>& A);
- #if 0
- friend CPolynomial<T> poly_plus(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_minus(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_times(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- friend CPolynomial<T> poly_divide(const CPolynomial<Complex<T> >& A, const CPolynomial<Complex<T> >& B);
- #endif
- #endif
- #if 0
- friend CPolynomial<T> operator+(const CPolynomial<T>& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator+(const CPolynomial<T>& a, const double& b);
- friend CPolynomial<T> operator+(const double& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator+(const CPolynomial<T>& a);
- friend CPolynomial<T> operator-(const CPolynomial<T>& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator-(const CPolynomial<T>& a, const double& b);
- friend CPolynomial<T> operator-(const double& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator-(const CPolynomial<T>& a);
- friend CPolynomial<T> operator*(const CPolynomial<T>& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator*(const CPolynomial<T>& a, const double& b);
- friend CPolynomial<T> operator*(const double& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator/(const CPolynomial<T>& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator/(const CPolynomial<T>& a, const double& b);
- friend CPolynomial<T> operator/(const double& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator%(const CPolynomial<T>& a, const CPolynomial<T>& b);
- friend CPolynomial<T> operator%(const CPolynomial<T>& a, const double& b);
- friend CPolynomial<T> operator%(const double& a, const CPolynomial<T>& b);
- #endif
- };
- template<typename T>
- inline void PolynomialDivision(const CPolynomial<T>& a, const CPolynomial<T>& b, CPolynomial<T>& q, CPolynomial<T>& r)
- {
- int an = a.v.size() - 1;
- int bn = a.v.size() - 1;
- int qn = ((an >= bn) ? an-bn : 0);
- int rn = ((bn >= 1) ? ((an <bn-1) ? an : bn-1) : 0);
- q.v.resize(qn+1);
- r.v.resize(rn+1);
- int k,j;
- for(j=0;j<=an;j++){
- r.v[j] = a.v[j];
- q.v[j] = 0;
- }
- for(k=an-bn;k>=0;k--){
- q.v[k] = r.v[bn+k]/b.v[bn];
- for(j=bn+k-1;j>=k;j--) r.v[j] -= q.v[k]*b.v[j-k];
- }
- for(j=bn;j<=an;j++) r.v[j] = 0;
- }
- template<typename T>
- inline CPolynomial<T> poly_plus(const CPolynomial<T>& a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c = a;
- c += b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_plus(const CPolynomial<T>& a, const double b)
- {
- CPolynomial<T> c = a;
- c += CPolynomial<T>((T)b);
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_plus(const double a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c((T)a);
- c += b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> operator+(const CPolynomial<T>& a)
- {
- CPolynomial<T> c = a;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_minus(const CPolynomial<T>& a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c = a;
- c -= b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_minus(const CPolynomial<T>& a, const double b)
- {
- CPolynomial<T> c = a;
- c -= CPolynomial<T>((T)b);
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_minus(const double a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c((T)a);
- c -= b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> operator-(const CPolynomial<T>& a)
- {
- CPolynomial<T> c = 0;
- c -= a;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_times(const CPolynomial<T>& a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c = a;
- c *= b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_times(const CPolynomial<T>& a, const double b)
- {
- CPolynomial<T> c = a;
- c *= CPolynomial<T>((T)b);
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_times(const double a, const CPolynomial<T>& b)
- {
- CPolynomial<T> c((T)a);
- c *= b;
- return c;
- }
- template<typename T>
- inline CPolynomial<T> poly_divide(const CPolynomial<T>& a, const CPolynomial<T>& b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(a,b,q,r);
- return q;
- }
- template<typename T>
- inline CPolynomial<T> poly_divide(const CPolynomial<T>& a, const double b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(a,CPolynomial<T>((T)b),q,r);
- return q;
- }
- template<typename T>
- inline CPolynomial<T> poly_divide(const double a, const CPolynomial<T>& b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(CPolynomial<T>((T)a),b,q,r);
- return q;
- }
- template<typename T>
- inline CPolynomial<T> poly_modulo(const CPolynomial<T>& a, const CPolynomial<T>& b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(a,b,q,r);
- return r;
- }
- template<typename T>
- inline CPolynomial<T> poly_modulo(const CPolynomial<T>& a, const double b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(a,CPolynomial<T>((T)b),q,r);
- return r;
- }
- template<typename T>
- inline CPolynomial<T> poly_modulo(const double a, const CPolynomial<T>& b)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(CPolynomial<T>((T)a),b,q,r);
- return r;
- }
- #if 0
- template<typename T> inline CPolynomial<T> poly_plus(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
- {
- CPolynomial<T> c = a; c += b; return c;
- }
- template<typename T> inline CPolynomial<T> poly_minus(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
- {
- CPolynomial<T> c = a; c -= b; return c;
- }
- template<typename T> inline CPolynomial<T> poly_times(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
- {
- CPolynomial<T> c = a; c *= b; return c;
- }
- template<typename T> inline CPolynomial<T> poly_divide(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
- {
- CPolynomial<T> c = a; c /= b; return c;
- }
- #endif
- template<typename T>
- CPolynomial<T>::CPolynomial(int m, const T* a)
- {
- for(int i=0; i<=m; i++){
- v.push_back(a[i]);
- }
- }
- #if 0
- // do not use <cstdarg> and <typeinfo> because they are very fragile
- // and depend on compilers
- template<typename T>
- CPolynomial<T>::CPolynomial(int m, const T v0, ...)
- {
- va_list args;
- va_start (args, m); // Although GNU compiler warns here, we can ignore it.
- const type_info& a = typeid(v0);
- if(strcmp(a.name(),"float")==0 || strcmp(a.name(),"double")==0){
- for(int i=1; i<=m; i++){
- v.push_back((T)va_arg(args, double));
- }
- }
- else{
- printf("Unsupported Polynomial type (%s)!n", a.name());
- exit(1);
- }
- va_end (args);
- }
- #endif
- template<typename T>
- CPolynomial<T>::CPolynomial(const char* a)
- {
- char *t = strdup(a);
- char *p = strtok(t, " trn");
- v.push_back((T)atof(p));
- while((p = strtok(NULL, " trn"))){
- v.push_back((T)atof(p));
- }
- free(t);
- }
- template<typename T>
- CPolynomial<T>::CPolynomial()
- {
- v.push_back((T)0);
- }
- template<typename T>
- CPolynomial<T>::~CPolynomial()
- {
- }
- #define EPS 2.0e-6
- #define MAXM 100
- /* Roots() yields n roots into roots[1]...roots[n] */
- template<typename T>
- void CPolynomial<T>::Roots(CComplex* roots) const
- {
- int n = v.size()-1;
- vector<CComplex> a(n+1);
- for(int i=0;i<=n;i++) a[i] = CComplex(v[i],0);
- zroots(&a[0], n, roots, 1);
- }
- #define EPSS 1.0e-7
- #define MR 8
- #define MT 10
- #define MAXIT (MT*MR)
- #ifndef my_max
- #define my_max(a, b) (((a) > (b)) ? (a) : (b))
- #endif
- #ifndef my_min
- #define my_min(a, b) (((a) < (b)) ? (a) : (b))
- #endif
- template<typename T>
- void CPolynomial<T>::zroots(CComplex* a, int m, CComplex* roots, int polish) const
- {
- int i,its,j,jj;
- CComplex x,b,c,ad[MAXM];
- for(j=0;j<=m;j++) ad[j] = a[j];
- for(j=m;j>=1;j--){
- //x = 0;
- x = roots[j];
- laguer(ad,j,&x,&its);
- if(fabs(imag(x)) <= 2.0*EPS*fabs(real(x))) x=CComplex(real(x), 0);
- roots[j] = x;
- b = ad[j];
- for(jj=j-1;jj>=0;jj--){
- c = ad[jj];
- ad[jj] = b;
- b = x*b+c;
- }
- }
- if(polish)
- for(j=1;j<=m;j++)
- laguer(a,m,&roots[j],&its);
- for(j=2;j<=m;j++){
- x = roots[j];
- for(i=j-1;i>=1;i--){
- if(real(roots[i]) <= real(x)) break;
- roots[i+1] = roots[i];
- }
- roots[i+1] = x;
- }
- }
- template<typename T>
- void CPolynomial<T>::laguer(CComplex* a, int m, CComplex* x, int *its) const
- {
- int iter,j;
- T abx,abp,abm,err;
- CComplex dx,x1,b,d,f,g,h,sq,gp,gm,g2;
- static T frac[MR+1]={
- (T)0.00,(T)0.50,(T)0.25,
- (T)0.75,(T)0.13,(T)0.38,
- (T)0.62,(T)0.88,(T)1.00
- };
- for(iter=1;iter<=MAXIT;iter++){
- *its = iter;
- b = a[m];
- err = (T)abs(b);
- d = f = 0;
- abx = (T)abs(*x);
- for(j=m-1;j>=0;j--){
- f = (*x)*f+d;
- d = (*x)*d+b;
- b = (*x)*b+a[j];
- err = (T)abs(b)+abx*err;
- }
- err *= (T)EPSS;
- if(abs(b) <= err) return;
- g = d/b;
- g2 = g*g;
- h = g2 - (T)2*(f/b);
- sq = sqrt((T)(m-1)*(((T)m*h)-g2));
- gp = g+sq;
- gm = g-sq;
- abp = (T)abs(gp);
- abm = (T)abs(gm);
- if(abp < abm) gp = gm;
- dx = ((my_max(abp,abm) > 0.0 ? CComplex(m,0)/gp
- : ((T)exp(log(1+abx))*CComplex(cos(iter),sin(iter)))));
- x1 = (*x)-dx;
- if(real(*x) == real(x1) && imag(*x) == imag(x1)) return;
- if(iter%MT) *x = x1;
- else *x = (*x)-frac[iter/MT]*dx;
- }
- printf("too many iteration in laguer");
- return;
- }
- template<typename T>
- T CPolynomial<T>::Eval(T x, T* pd, int nd) const
- {
- int nnd, j, i;
- T cnst = 1;
- T ftmp;
- if(!pd){
- nd = 0;
- }
- int n = v.size()-1;
- ftmp = v[n];
- if(pd) pd[0] = v[n];
- for(j=1;j<=nd;j++) pd[j] = 0;
- for(i=n-1;i>=0;i--){
- nnd = (nd < (n-i) ? nd : n-i);
- for(j=nnd;j>=1;j--)
- pd[j] = (T)(pd[j]*x+pd[j-1]);
- ftmp = (T)(ftmp*x+v[i]);
- if(pd) pd[0] = (T)(pd[0]*x+v[i]);
- }
- for(i=2;i<=nd;i++){
- cnst *= i;
- pd[i] *= cnst;
- }
- return ftmp;
- }
- template<typename T>
- void CPolynomial<T>::Print() const
- {
- int n=v.size()-1;
- int bAllZero = 1;
- for(int i=n;i>=0;i--){
- if(fabs(v[i]) < 1e-37){
- if(i==0 && bAllZero) printf("0");
- continue;
- }
- bAllZero = 0;
- if(v[i] > 0 && i != n) printf(" + ");
- else if(v[i] < 0) printf(" - ");
- if(fabs(fabs(v[i])-1) > 1e-37){
- printf("%gx(%d)",fabs(v[i]),i);
- }
- else{
- printf("x(%d)",i);
- }
- }
- printf("n");
- }
- template<typename T>
- CPolynomial<T>& CPolynomial<T>::operator=(const CPolynomial<T>& a)
- {
- int an = a.v.size()-1;
- int n = an;
- v.resize(n+1);
- int m = 0;
- for(int i=0; i<=n; i++){
- v[i] = a.v[i];
- if(v[i] != 0.0)
- m = i;
- }
- if(m != n) v.resize(m+1);
- return *this;
- }
- template<typename T>
- CPolynomial<T>& CPolynomial<T>::operator+=(const CPolynomial<T>& a)
- {
- int m = v.size()-1;
- int an = a.v.size()-1;
- int n = my_max(m,an);
- v.resize(n+1);
- for(int i=0; i<=n; i++)
- v[i] = ((i<=m)? v[i]: 0) + ((i<=an)? a.v[i]: 0);
- return *this;
- }
- template<typename T>
- CPolynomial<T>& CPolynomial<T>::operator-=(const CPolynomial<T>& a)
- {
- int m = v.size()-1;
- int an = a.v.size()-1;
- int n = my_max(m,an);
- v.resize(n+1);
- for(int i=0; i<=n; i++)
- v[i] = ((i<=m)? v[i]: 0) - ((i<=an)? a.v[i]: 0);
- return *this;
- }
- template<typename T>
- CPolynomial<T>& CPolynomial<T>::operator*=(const CPolynomial<T>& a)
- {
- int p,i;
- int m = v.size()-1;
- int an = a.v.size()-1;
- int n = m + an;
- v.resize(n+1);
- for(p=n;p>m;p--) v[p] = 0;
- for(p=n; p>=0; p--){
- T sum = 0;
- for(i=my_min(p,m); i>=0 && p-i<=an; i--){
- sum += v[i] * a.v[p-i];
- }
- v[p] = sum;
- }
- return *this;
- }
- template<typename T>
- CPolynomial<T>& CPolynomial<T>::operator/=(const CPolynomial<T>& a)
- {
- CPolynomial<T> q,r;
- PolynomialDivision(*this,a,q,r);
- return q;
- }
- #endif