polynomial.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLRNUMERIC_POLYNOMIAL_H_
00016 #define _DLRNUMERIC_POLYNOMIAL_H_
00017 
00018 #include <dlrNumeric/array1D.h>
00019 
00020 namespace dlr {
00021 
00022   namespace numeric {
00023 
00024 
00033     template <class Type>
00034     class Polynomial {
00035     public:
00036 
00040       Polynomial();
00041 
00042 
00051       explicit
00052       Polynomial(Type coefficient0);
00053 
00054 
00066       Polynomial(Type coefficient1, Type coefficient0);
00067 
00068 
00083       Polynomial(Type coefficient2, Type coefficient1, Type coefficient0);
00084 
00085 
00098       explicit
00099       Polynomial(const Array1D<Type> coefficients);
00100 
00101 
00107       Polynomial(const Polynomial<Type>& other);
00108 
00109 
00118       Array1D<Type>
00119       getCoefficientArray() const;
00120 
00121 
00128       size_t
00129       getOrder() const {return m_coefficientArray.size() - 1;}
00130       
00131 
00139       Polynomial<Type>&
00140       operator=(const Polynomial<Type> other);
00141       
00142 
00151       Type
00152       operator()(Type xValue) const;
00153 
00154 
00168       Polynomial&
00169       operator*=(const Polynomial& other);
00170 
00171 
00184       Polynomial&
00185       operator+=(const Polynomial& other);
00186 
00187 
00201       Polynomial&
00202       operator-=(const Polynomial& other);
00203       
00204     private:
00205 
00206       Array1D<Type> m_coefficientArray;
00207       
00208     };
00209 
00210     
00211     /* ============ Non-member function declarations ============ */
00212 
00213   
00228     template<class Type>
00229     Polynomial<Type>
00230     operator*(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1);
00231 
00232 
00247     template<class Type>
00248     Polynomial<Type>
00249     operator+(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1);
00250   
00251 
00266     template<class Type>
00267     Polynomial<Type>
00268     operator-(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1);
00269 
00270 
00271   } // namespace numeric
00272 
00273 } // namespace dlr
00274 
00275 
00276 /* =============================================================== */
00277 /* Implementation follows.                                         */
00278 /* =============================================================== */
00279 
00280 
00281 
00282 namespace dlr {
00283 
00284   namespace numeric {
00285 
00286 
00287     // The default constructor makes a constant polynomial: p(x) = 1.
00288     template <class Type>
00289     Polynomial<Type>::
00290     Polynomial()
00291       : m_coefficientArray(1)
00292     {
00293       m_coefficientArray[0] = Type(1.0);
00294     }
00295 
00296 
00297     // This constructor makes a constant polynomial:
00298     template <class Type>
00299     Polynomial<Type>::
00300     Polynomial(Type coefficient0)
00301       : m_coefficientArray(1)
00302     {
00303       m_coefficientArray[0] = coefficient0;
00304     }
00305 
00306 
00307     // This constructor makes a first order polynomial:
00308     template <class Type>
00309     Polynomial<Type>::
00310     Polynomial(Type coefficient1, Type coefficient0)
00311       : m_coefficientArray(2)
00312     {
00313       m_coefficientArray[0] = coefficient0;
00314       m_coefficientArray[1] = coefficient1;
00315     }
00316 
00317 
00318     // This constructor makes a first order polynomial:
00319     template <class Type>
00320     Polynomial<Type>::
00321     Polynomial(Type coefficient2, Type coefficient1, Type coefficient0)
00322       : m_coefficientArray(3)
00323     {
00324       m_coefficientArray[0] = coefficient0;
00325       m_coefficientArray[1] = coefficient1;
00326       m_coefficientArray[2] = coefficient2;
00327     }
00328 
00329 
00330     // This constructor makes a polynomial of arbitrary order.
00331     template <class Type>
00332     Polynomial<Type>::
00333     Polynomial(const Array1D<Type> coefficients)
00334       : m_coefficientArray(coefficients.copy())
00335     {
00336       // Empty.
00337     }
00338 
00339 
00340     // The copy constructor does a deep copy.
00341     template <class Type>
00342     Polynomial<Type>::
00343     Polynomial(const Polynomial<Type>& other)
00344       : m_coefficientArray(other.m_coefficientArray.copy())
00345     {
00346       // Empty.
00347     }
00348 
00349     
00350     // This member function returns the coefficients of the
00351     // polynomial.
00352     template <class Type>
00353     Array1D<Type>
00354     Polynomial<Type>::
00355     getCoefficientArray() const
00356     {
00357       return m_coefficientArray.copy();
00358     }
00359       
00360 
00361     // The assigment operator does a deep copy.
00362     template <class Type>
00363     Polynomial<Type>&
00364     Polynomial<Type>::
00365     operator=(const Polynomial<Type> other)
00366     {
00367       if(&other != this) {
00368         m_coefficientArray = other.m_coefficientArray.copy();
00369       }
00370       return *this;
00371     }
00372 
00373     
00374     // This operator evaluates the polynomial.
00375     template <class Type>
00376     Type
00377     Polynomial<Type>::
00378     operator()(Type xValue) const
00379     {
00380       Type result = m_coefficientArray[0];
00381       if(m_coefficientArray.size() > 1) {
00382         result += xValue * m_coefficientArray[1];
00383       }
00384       Type xToTheN = xValue;
00385       for(size_t index0 = 2; index0 < m_coefficientArray.size(); ++index0) {
00386         xToTheN *= xValue;
00387         result += xToTheN * m_coefficientArray[index0];
00388       }
00389       return result;
00390     }
00391 
00392 
00393     // This operator multiplies the polynomial by another polynomial.
00394     template <class Type>
00395     Polynomial<Type>&
00396     Polynomial<Type>::
00397     operator*=(const Polynomial& other)
00398     {
00399       size_t oldOrder = this->getOrder();
00400       size_t otherOrder = other.getOrder();
00401       size_t newOrder = oldOrder + otherOrder;
00402       Array1D<Type> newCoefficientArray(newOrder + 1);
00403       newCoefficientArray = Type(0);
00404 
00405       // We're going to use oldOrder and otherOrder as bounds for the
00406       // loops which calculate the new coefficients.  Increment them
00407       // now to avoid writing "oldOrder + 1" in the loop termination
00408       // condition.
00409       ++oldOrder;
00410       ++otherOrder;
00411       for(size_t index0 = 0; index0 < oldOrder; ++index0) {
00412         for(size_t index1 = 0; index1 < otherOrder; ++index1) {
00413           newCoefficientArray[index0 + index1] +=
00414             m_coefficientArray[index0] * other.m_coefficientArray[index1];
00415         }
00416       }
00417       m_coefficientArray = newCoefficientArray;
00418       return *this;
00419     }
00420 
00421 
00422     // This operator adds another polynomial to *this.
00423     template <class Type>
00424     Polynomial<Type>&
00425     Polynomial<Type>::
00426     operator+=(const Polynomial& other)
00427     {
00428       size_t largerSize = m_coefficientArray.size();
00429       size_t smallerSize = other.m_coefficientArray.size();
00430       if(smallerSize > largerSize) {
00431         std::swap(smallerSize, largerSize);
00432       }
00433       Array1D<Type> newCoefficientArray(largerSize);
00434 
00435       size_t index0 = 0;
00436       while(index0 < smallerSize) {
00437         newCoefficientArray[index0] =
00438           m_coefficientArray[index0] + (other.m_coefficientArray)[index0];
00439         ++index0;
00440       }
00441       while(index0 < m_coefficientArray.size()) {
00442         newCoefficientArray[index0] = m_coefficientArray[index0];
00443         ++index0;
00444       }
00445       while(index0 < other.m_coefficientArray.size()) {
00446         newCoefficientArray[index0] = other.m_coefficientArray[index0];
00447         ++index0;
00448       }
00449       m_coefficientArray = newCoefficientArray;
00450       return *this;
00451     }
00452 
00453 
00454     // This operator subtracts another polynomial from *this.
00455     template <class Type>
00456     Polynomial<Type>&
00457     Polynomial<Type>::
00458     operator-=(const Polynomial& other)
00459     {
00460       size_t largerSize = m_coefficientArray.size();
00461       size_t smallerSize = other.m_coefficientArray.size();
00462       if(smallerSize > largerSize) {
00463         std::swap(smallerSize, largerSize);
00464       }
00465       Array1D<Type> newCoefficientArray(largerSize);
00466 
00467       size_t index0 = 0;
00468       while(index0 < smallerSize) {
00469         newCoefficientArray[index0] =
00470           m_coefficientArray[index0] - (other.m_coefficientArray)[index0];
00471         ++index0;
00472       }
00473       while(index0 < m_coefficientArray.size()) {
00474         newCoefficientArray[index0] = m_coefficientArray[index0];
00475         ++index0;
00476       }
00477       while(index0 < other.m_coefficientArray.size()) {
00478         newCoefficientArray[index0] = -(other.m_coefficientArray[index0]);
00479         ++index0;
00480       }
00481       m_coefficientArray = newCoefficientArray;
00482       return *this;
00483     }
00484       
00485 
00486 
00487     /* ============ Non-member function definitions ============ */
00488 
00489     // This operator multiplies two Polynomial instances.
00490     template<class Type>
00491     Polynomial<Type>
00492     operator*(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1)
00493     {
00494       Polynomial<Type> result = arg0;
00495       result *= arg1;
00496       return result;
00497     }
00498 
00499 
00500     // This operator adds two Polynomial instances.
00501     template<class Type>
00502     Polynomial<Type>
00503     operator+(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1)
00504     {
00505       Polynomial<Type> result = arg0;
00506       result += arg1;
00507       return result;
00508     }
00509   
00510 
00511     // This operator subtracts two Polynomial instances.
00512     template<class Type>
00513     Polynomial<Type>
00514     operator-(const Polynomial<Type>& arg0, const Polynomial<Type>& arg1)
00515     {
00516       Polynomial<Type> result = arg0;
00517       result -= arg1;
00518       return result;
00519     }
00520     
00521     
00522   } // namespace numeric
00523   
00524 } // namespace dlr
00525 
00526 #endif /* #ifndef _DLRNUMERIC_POLYNOMIAL_H_ */

Generated on Wed Nov 25 00:42:42 2009 for dlrUtilities Utility Library by  doxygen 1.5.8