polynom.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  File:       polynom.hpp
00004 //  Created:    2005/9/30    8:38
00005 //
00006 //  Author: Andrey Somsikov
00007 */
00008 
00015 #ifndef __ARAGELI_polynom_hpp__
00016 #define __ARAGELI_polynom_hpp__
00017 
00018 #include <cstddef>
00019 #include <iostream>
00020 #include <vector>
00021 #include <iomanip>
00022 #include <algorithm>
00023 #include <cmath>
00024 
00025 /*
00026 #include <stdlib.h>
00027 #include <ios>
00028 #include <vector>
00029 #include "arageli_defs.h"
00030 #include "matrices.h"
00031 */
00032 
00033 #include "config.hpp"
00034 #include "refcntr.hpp"
00035 #include "iteradapt.hpp"
00036 #include "factory.hpp"
00037 #include "powerest.hpp"
00038 #include "exception.hpp"
00039 #include "_utility.hpp"
00040 
00041 namespace Arageli
00042 {
00043 
00048 template <typename F>
00049 class polynom
00050 {
00051 public:
00053     typedef F coef_type;
00055     typedef std::pair<polynom<F>, polynom<F> > div_result_type;
00056 protected:
00057     template <typename F>
00058     void fixLeadingZeroes()
00059     {
00060         std::size_t k = c.size()-1;
00061         while (c[k] == factory<coef_type>::null() && k > 0)
00062             k--;
00063         c.resize(k+1);
00064     }
00065 
00066 public:
00068     std::size_t size() const { return c.size(); }
00070     std::size_t deg() const { return size()-1; }
00071 
00072     void setLe(const std::vector<F> &coefficients)
00073     {
00074         std::size_t k = coefficients.size()-1;
00075         while (coefficients[k] == factory<coef_type>::null() && k > 0)
00076             k--;
00077         c.reserve(k + 1);
00078         for (std::size_t i = 0; i <= k; i++)
00079             c.push_back(coefficients[i]);
00080     }
00081 
00082     void setLe(const vector<F> &coefficients)
00083     {
00084         std::size_t k = coefficients.get_n()-1;
00085         while (coefficients[k] == factory<coef_type>::null() && k > 0)
00086             k--;
00087         c.reserve(k + 1);
00088         for (std::size_t i = 0; i <= k; i++)
00089             c.push_back(coefficients[i]);
00090     }
00091 
00092     void setBe(const std::vector<F> &coefficients)
00093     {
00094 
00095         int k = 0;
00096         while (coefficients[k] == factory<coef_type>::null() && k < (int)coefficients.size()-1)
00097             k++;
00098         c.reserve((int)coefficients.size() - k);
00099         for (int i = (int)coefficients.size() - 1; i >= k; i--)
00100             c.push_back(coefficients[i]);
00101     }
00102 
00103     void setBe(const vector<F> &coefficients)
00104     {
00105 
00106         int k = 0;
00107         while (coefficients[k] == factory<coef_type>::null() && k < (int)coefficients.get_n()-1)
00108             k++;
00109         c.reserve((int)coefficients.get_n() - k);
00110         for (int i = (int)coefficients.get_n() - 1; i >= k; i--)
00111             c.push_back(coefficients[i]);
00112     }
00113 
00114     const std::vector<F> &getData() const
00115     {
00116         return c;
00117     }
00118 
00124     div_result_type div (const polynom<F>& a) const
00125     {
00126         if ((*this).size() < a.size())
00127             return div_result_type(polynom<F>(), *this);
00128         polynom<F> q;
00129         q.c.resize((*this).size() - a.size() + 1, factory<coef_type>::null());
00130         polynom<F> r;
00131         r.c = (*this).c;
00132         std::size_t rSize = r.size();
00133 
00134         while (rSize >= a.size())
00135         {
00136             F qValue = r.c[rSize - 1] / a[a.size()-1];
00137             q.c[rSize - a.size()] = qValue;
00138             for (std::size_t i = 0, j = rSize - a.size(); i < a.size(); i++, j++)
00139                 r.c[j] -= qValue * a[i];
00140             if (factory<coef_type>::null() != r.c[rSize - 1])
00141                 throw "can't divide";
00142             rSize--;
00143         }
00144         q.fixLeadingZeroes<F>();
00145         r.fixLeadingZeroes<F>();
00146 
00147         return div_result_type(q, r);
00148     }
00149 
00150     polynom<F>& operator = (const polynom<F>& copy) 
00151     { 
00152         c = copy.c;
00153         return *this; 
00154     }
00155 
00156     F& operator [] (std::size_t i)
00157     {
00158         return c[i];
00159     }
00160 
00161     const F& operator [] (std::size_t i) const
00162     {
00163         return c[i];
00164     }
00165 
00166     polynom<F> operator - ( ) const
00167     {
00168         polynom<F> res(*this);
00169         for (std::size_t i = 0; i < res.size(); i++)
00170             res[i] = -res[i];
00171         return res;
00172     }
00173 
00174     template <typename F>
00175         bool operator < (const polynom<F>& a) const
00176     {
00177         if ((*this).size() < a.size())
00178             return true;
00179         if ((*this).size() == a.size())
00180             return (*this)[(*this).size() - 1] < a[a.size()-1];
00181         return false;
00182     }
00183 
00184     template <typename F>
00185         bool operator <= (const polynom<F>& a) const
00186     {
00187         if ((*this).size() < a.size())
00188             return true;
00189         if ((*this).size() == a.size())
00190             return (*this)[(*this).size() - 1] <= a[a.size()-1];
00191         return false;
00192     }
00193 
00194     template <typename F>
00195         bool operator > (const polynom<F>& a) const
00196     {
00197         if ((*this).size() > a.size())
00198             return true;
00199         if ((*this).size() == a.size())
00200             return (*this)[(*this).size() - 1] > a[a.size()-1];
00201         return false;
00202     }
00203 
00204     template <typename F>
00205         bool operator >= (const polynom<F>& a) const
00206     {
00207         if ((*this).size() > a.size())
00208             return true;
00209         if ((*this).size() == a.size())
00210             return (*this)[(*this).size() - 1] >= a[a.size()-1];
00211         return false;
00212     }
00213 
00214     template <typename F>
00215         polynom<F> operator + (const polynom<F>& a) const
00216     {
00217         polynom<F> res;
00218         const polynom<F> *op;
00219 
00220         if (a.size() > (*this).size())
00221         {
00222             res = polynom<F>(a);
00223             op = this;
00224         }
00225         else
00226         {
00227             res = polynom<F>(*this);
00228             op = &a;
00229         }
00230 
00231         for (std::size_t i = 0; i < op->size(); i++)
00232             res[i] += (*op)[i];
00233 
00234         res.fixLeadingZeroes<F>();
00235         return res;
00236     }
00237 
00238     template <typename F>
00239         polynom<F> operator - (const polynom<F>& a) const
00240     {
00241         return *this + (-a);
00242     }
00243 
00244     template <typename F>
00245         polynom<F> operator * (const polynom<F>& a) const
00246     {
00247         std::size_t i, j;
00248         std::vector<F> res(a.size() + (*this).size() - 1, factory<coef_type>::null());
00249 
00250         for (i = 0; i < a.size(); i++)
00251             for (j = 0; j < (*this).size(); j++)
00252             {
00253                 res[i+j] += a[i] * (*this)[j];
00254             }
00255 
00256             std::size_t k = res.size() - 1;
00257             while (res[k] == factory<coef_type>::null() && k > 0)
00258                 k--;
00259             res.resize(k + 1);
00260 
00261             for (i = 0; i < res.size()/2; i++)
00262                 std::swap(res[i], res[res.size() - i - 1]);
00263 
00264             return polynom<F>(res);
00265     }
00266 
00267     template <typename F>
00268         polynom<F> operator / (const polynom<F>& a) const
00269     {
00270         return div(a).first;
00271     }
00272 
00273     template <typename F>
00274         polynom<F> operator % (const polynom<F>& a) const
00275     {
00276         return div(a).second;
00277     }
00278 
00279     polynom<F>& operator += (const polynom<F>& a)
00280     {
00281         *this = *this + a;
00282         return *this;
00283     }
00284 
00285     polynom<F>& operator -= (const polynom<F>& a)
00286     {
00287         *this = *this - a;
00288         return *this;
00289     }
00290 
00291     polynom<F>& operator *= (const polynom<F>& a)
00292     {
00293         *this = *this * a;
00294         return *this;
00295     }
00296 
00297     polynom<F>& operator /= (const polynom<F>& a)
00298     {
00299         *this = *this / a;
00300         return *this;
00301     }
00302 
00303     int operator == (const polynom<F>& a) const
00304     {
00305         return (*this).c == a.c;
00306     }
00307 
00308     int operator != (const polynom<F>& a) const
00309     {
00310         return !((*this) == a);
00311     }
00312 
00313 protected:
00314     std::vector<F> c;
00315 public:
00317     polynom<F>()
00318     {
00319         c.push_back(factory<coef_type>::null());
00320     }
00321 
00327     polynom<F>(const F& value, std::size_t deg = 0)
00328     {
00329         c.resize(deg+1, factory<coef_type>::null());
00330         c[deg] = value;
00331     }
00332 
00337     polynom<F>(const polynom<F>& copy)
00338     {
00339         c = copy.c;
00340     }
00341 
00347     polynom<F>(const std::vector<F> &coeff, bool le = false)
00348     {
00349         if (le)
00350             setLe(coeff);
00351         else
00352             setBe(coeff);
00353     }
00354 
00355     polynom<F>(const vector<F> &coefficients, bool le = false)
00356     {
00357         if (le)
00358             setLe(coefficients);
00359         else
00360             setBe(coefficients);
00361     }
00362 
00363     polynom<F>(const F *coefficients, std::size_t count, bool le = false)
00364     {
00365         std::vector<F> vCoeff;
00366         vCoeff.reserve(count);
00367         for (std::size_t i = 0; i < count; i++)
00368             vCoeff.push_back(coefficients[i]);
00369         if (le)
00370             setLe(vCoeff);
00371         else
00372             setBe(vCoeff);
00373     }
00374 
00375 /*
00376     polynom<T> (const char* s)
00377     {
00378         std::istringstream buf(s);
00379         // WARNING. Correct if there are no virtual function.
00380         buf >> *this;
00381     }
00382 */
00383 
00385     ~polynom<F>()
00386     {
00387     }
00388 public:
00389     static polynom<F> constant(const F& value)
00390     {
00391         return polynom<F>(value, 0);
00392     }
00393 };
00394 
00395 /*
00396 
00397 template <typename F, typename FT>
00398 std::istream& input_list
00399 (
00400     std::istream& in,
00401     polynom<F>& x,
00402     const char* first_bracket = "(",
00403     const char* second_bracket = ")",
00404     const char* separator = ","
00405 );
00406 
00407 template <typename T, typename FT>
00408 std::istream& operator>> (std::istream& out, polynom<T>& x)
00409 { return input_list(out, x); }
00410 */
00411 
00412 template <typename F, typename FT>
00413 std::ostream& operator << (std::ostream & s, const polynom<F> &v)
00414 {
00415     std::size_t i = v.deg() + 1;
00416     s << "(";
00417     do {
00418         i--;
00419         s << v[i] << ", ";              
00420     } while(i != 0);
00421     s << ")";
00422     /*
00423     if (s.fail ())
00424     matrix_error (st_output_error, "polynom::output error");
00425     */
00426     return s;
00427 }
00428 
00429 template <typename F, typename FT>
00430 polynom<F> abs(const polynom<F> &maxVal)
00431 {
00432     polynom<F> res(factory<coef_type>::unit(), maxVal.deg());
00433     for (std::size_t i = 0; i < res.size(); i++)
00434         res[i] = abs(maxVal[i]);
00435     return res;
00436 }
00437 
00444 template <typename F, typename FT>
00445 polynom<F> normalize(const polynom<F> &val)
00446 {
00447     polynom<F> res(val);
00448     F d = val[val.size()-1];
00449     for (std::size_t i = 0; i < val.size(); i++)
00450         res[i] = val[i] / d;
00451     return res;
00452 }
00453 
00454 
00455 } // namespace Arageli
00456 
00457 
00458 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00459 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_POLYNOM
00460 #include "polynom.cpp"
00461 #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_POLYNOM
00462 #endif
00463 
00464 #endif /*__ARAGELI_polynom_hpp__*/
00465 /* End of file polynom.hpp */

Generated on Thu Aug 31 17:38:08 2006 for Arageli by  doxygen 1.4.7