| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <float.h> |
| | #include <math.h> |
| | #include <algorithm> |
| | #include "Factor.h" |
| |
|
| | |
| | |
| | |
| | template<int Degree> |
| | Polynomial<Degree>::Polynomial(void){memset(coefficients,0,sizeof(double)*(Degree+1)) |
| | template<int Degree> |
| | template<int Degree2> |
| | Polynomial<Degree>::Polynomial(const Polynomial<Degree2>& P){ |
| | memset(coefficients,0,sizeof(double)*(Degree+1)) |
| | for(int i=0 |
| | } |
| |
|
| |
|
| | template<int Degree> |
| | template<int Degree2> |
| | Polynomial<Degree>& Polynomial<Degree>::operator = (const Polynomial<Degree2> &p){ |
| | int d=Degree<Degree2?Degree:Degree2 |
| | memset(coefficients,0,sizeof(double)*(Degree+1)) |
| | memcpy(coefficients,p.coefficients,sizeof(double)*(d+1)) |
| | return *this |
| | } |
| |
|
| | template<int Degree> |
| | Polynomial<Degree-1> Polynomial<Degree>::derivative(void) const{ |
| | Polynomial<Degree-1> p |
| | for(int i=0 |
| | return p |
| | } |
| |
|
| | template<int Degree> |
| | Polynomial<Degree+1> Polynomial<Degree>::integral(void) const{ |
| | Polynomial<Degree+1> p |
| | p.coefficients[0]=0 |
| | for(int i=0 |
| | return p |
| | } |
| | template<> double Polynomial< 0 >::operator() ( double t ) const { return coefficients[0] |
| | template<> double Polynomial< 1 >::operator() ( double t ) const { return coefficients[0]+coefficients[1]*t |
| | template<> double Polynomial< 2 >::operator() ( double t ) const { return coefficients[0]+(coefficients[1]+coefficients[2]*t)*t |
| | template<int Degree> |
| | double Polynomial<Degree>::operator() ( double t ) const{ |
| | double v=coefficients[Degree] |
| | for( int d=Degree-1 |
| | return v |
| | } |
| | template<int Degree> |
| | double Polynomial<Degree>::integral( double tMin , double tMax ) const |
| | { |
| | double v=0 |
| | double t1,t2 |
| | t1=tMin |
| | t2=tMax |
| | for(int i=0 |
| | v+=coefficients[i]*(t2-t1)/(i+1) |
| | if(t1!=-DBL_MAX && t1!=DBL_MAX){t1*=tMin |
| | if(t2!=-DBL_MAX && t2!=DBL_MAX){t2*=tMax |
| | } |
| | return v |
| | } |
| | template<int Degree> |
| | int Polynomial<Degree>::operator == (const Polynomial& p) const{ |
| | for(int i=0 |
| | return 1 |
| | } |
| | template<int Degree> |
| | int Polynomial<Degree>::operator != (const Polynomial& p) const{ |
| | for(int i=0 |
| | return 1 |
| | } |
| | template<int Degree> |
| | int Polynomial<Degree>::isZero(void) const{ |
| | for(int i=0 |
| | return 1 |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::setZero(void){memset(coefficients,0,sizeof(double)*(Degree+1)) |
| |
|
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::addScaled(const Polynomial& p,double s){ |
| | for(int i=0 |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator += (const Polynomial<Degree>& p){ |
| | for(int i=0 |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator -= (const Polynomial<Degree>& p){ |
| | for(int i=0 |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator + (const Polynomial<Degree>& p) const{ |
| | Polynomial q |
| | for(int i=0 |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator - (const Polynomial<Degree>& p) const{ |
| | Polynomial q |
| | for(int i=0 |
| | return q |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::Scale(const Polynomial& p,double w,Polynomial& q){ |
| | for(int i=0 |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,double w2,Polynomial& q){ |
| | for(int i=0 |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,Polynomial& q){ |
| | for(int i=0 |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::AddScaled(const Polynomial& p1,const Polynomial& p2,double w2,Polynomial& q){ |
| | for(int i=0 |
| | } |
| |
|
| | template<int Degree> |
| | void Polynomial<Degree>::Subtract(const Polynomial &p1,const Polynomial& p2,Polynomial& q){ |
| | for(int i=0 |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::Negate(const Polynomial& in,Polynomial& out){ |
| | out=in |
| | for(int i=0 |
| | } |
| |
|
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator - (void) const{ |
| | Polynomial q=*this |
| | for(int i=0 |
| | return q |
| | } |
| | template<int Degree> |
| | template<int Degree2> |
| | Polynomial<Degree+Degree2> Polynomial<Degree>::operator * (const Polynomial<Degree2>& p) const{ |
| | Polynomial<Degree+Degree2> q |
| | for(int i=0 |
| | return q |
| | } |
| |
|
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator += ( double s ) |
| | { |
| | coefficients[0]+=s |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator -= ( double s ) |
| | { |
| | coefficients[0]-=s |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator *= ( double s ) |
| | { |
| | for(int i=0 |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree>& Polynomial<Degree>::operator /= ( double s ) |
| | { |
| | for(int i=0 |
| | return *this |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator + ( double s ) const |
| | { |
| | Polynomial<Degree> q=*this |
| | q.coefficients[0]+=s |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator - ( double s ) const |
| | { |
| | Polynomial q=*this |
| | q.coefficients[0]-=s |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator * ( double s ) const |
| | { |
| | Polynomial q |
| | for(int i=0 |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::operator / ( double s ) const |
| | { |
| | Polynomial q |
| | for( int i=0 |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::scale( double s ) const |
| | { |
| | Polynomial q=*this |
| | double s2=1.0 |
| | for(int i=0 |
| | q.coefficients[i]*=s2 |
| | s2/=s |
| | } |
| | return q |
| | } |
| | template<int Degree> |
| | Polynomial<Degree> Polynomial<Degree>::shift( double t ) const |
| | { |
| | Polynomial<Degree> q |
| | for(int i=0 |
| | double temp=1 |
| | for(int j=i |
| | q.coefficients[j]+=coefficients[i]*temp |
| | temp*=-t*j |
| | temp/=(i-j+1) |
| | } |
| | } |
| | return q |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::printnl(void) const{ |
| | for(int j=0 |
| | printf("%6.4f x^%d ",coefficients[j],j) |
| | if(j<Degree && coefficients[j+1]>=0){printf("+") |
| | } |
| | printf("\n") |
| | } |
| | template<int Degree> |
| | void Polynomial<Degree>::getSolutions(double c,std::vector<double>& roots,double EPS) const |
| | { |
| | double r[4][2] |
| | int rCount=0 |
| | roots.clear() |
| | switch(Degree){ |
| | case 1: |
| | rCount=Factor(coefficients[1],coefficients[0]-c,r,EPS) |
| | break |
| | case 2: |
| | rCount=Factor(coefficients[2],coefficients[1],coefficients[0]-c,r,EPS) |
| | break |
| | case 3: |
| | rCount=Factor(coefficients[3],coefficients[2],coefficients[1],coefficients[0]-c,r,EPS) |
| | break |
| | |
| | |
| | |
| | default: |
| | printf("Can't solve polynomial of degree: %d\n",Degree) |
| | } |
| | for(int i=0 |
| | if(fabs(r[i][1])<=EPS){ |
| | roots.push_back(r[i][0]) |
| | } |
| | } |
| | } |
| | template< int Degree > |
| | int Polynomial<Degree>::getSolutions( double c , double* roots , double EPS ) const |
| | { |
| | double _roots[4][2] |
| | int _rCount=0 |
| | switch( Degree ) |
| | { |
| | case 1: _rCount = Factor( coefficients[1] , coefficients[0]-c , _roots , EPS ) |
| | case 2: _rCount = Factor( coefficients[2] , coefficients[1] , coefficients[0]-c , _roots , EPS ) |
| | case 3: _rCount = Factor( coefficients[3] , coefficients[2] , coefficients[1] , coefficients[0]-c , _roots , EPS ) |
| | |
| | default: printf( "Can't solve polynomial of degree: %d\n" , Degree ) |
| | } |
| | int rCount = 0 |
| | for( int i=0 |
| | return rCount |
| | } |
| | |
| | template< > |
| | Polynomial< 0 > Polynomial< 0 >::BSplineComponent( int i ) |
| | { |
| | Polynomial p |
| | p.coefficients[0] = 1. |
| | return p |
| | } |
| |
|
| | |
| | template< int Degree > |
| | Polynomial< Degree > Polynomial< Degree >::BSplineComponent( int i ) |
| | { |
| | |
| | |
| | Polynomial p |
| | if( i<Degree ) |
| | { |
| | Polynomial< Degree > _p = Polynomial< Degree-1 >::BSplineComponent( i ).integral() |
| | p -= _p |
| | p.coefficients[0] += _p(1) |
| | } |
| | if( i>0 ) |
| | { |
| | Polynomial< Degree > _p = Polynomial< Degree-1 >::BSplineComponent( i-1 ).integral() |
| | p += _p |
| | } |
| | return p |
| | } |
| |
|
| |
|
| | |
| | template< > void Polynomial< 0 >::BSplineComponentValues( double x , double* values ){ values[0] = 1. |
| | |
| | template< int Degree > void Polynomial< Degree >::BSplineComponentValues( double x , double* values ) |
| | { |
| | const double Scale = 1./Degree |
| | Polynomial< Degree-1 >::BSplineComponentValues( x , values+1 ) |
| | values[0] = values[1] * (1.-x) * Scale |
| | for( int i=1 |
| | { |
| | double x1 = (x-i+Degree) , x2 = (-x+i+1) |
| | values[i] = ( values[i]*x1 + values[i+1]*x2 ) * Scale |
| | } |
| | values[Degree] *= x * Scale |
| | } |
| |
|
| | |
| | template< > void Polynomial< 0 >::BinomialCoefficients( int bCoefficients[1] ){ bCoefficients[0] = 1 |
| | template< int Degree > void Polynomial< Degree >::BinomialCoefficients( int bCoefficients[Degree+1] ) |
| | { |
| | Polynomial< Degree-1 >::BinomialCoefficients( bCoefficients ) |
| | int leftValue = 0 |
| | for( int i=0 |
| | { |
| | int temp = bCoefficients[i] |
| | bCoefficients[i] += leftValue |
| | leftValue = temp |
| | } |
| | bCoefficients[Degree] = 1 |
| | } |
| |
|