BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/internal/Polynomial_impl.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Stanford University (USA).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Polynomial/internal/Polynomial_impl.h $
00016 // $Id: Polynomial_impl.h 41418 2008-01-03 14:50:13Z spion $
00017 // 
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_POLYNOMIAL_INTERNAL_POLYNOMIAL_CORE_H_
00022 #define CGAL_POLYNOMIAL_INTERNAL_POLYNOMIAL_CORE_H_
00023 
00024 #include <CGAL/Polynomial/basic.h>
00025 #include <vector>
00026 #include <iostream>
00027 #include <CGAL/Polynomial/internal/Rational/Evaluate_polynomial.h>
00028 #include <sstream>
00029 #include <algorithm>
00030 
00031 #define CGAL_EXCESSIVE(x)
00032 
00033 CGAL_POLYNOMIAL_BEGIN_INTERNAL_NAMESPACE
00034 
00035 template <class This, class NT_t>
00036 class Polynomial_impl;
00037 
00038 template < class T, class NT, class C, class Tr>
00039 inline std::ostream &operator<<(std::basic_ostream<C,Tr> &out,
00040                                 const Polynomial_impl<T, NT> &poly);
00041 
00043 
00059 
00060 
00061 template <class This, class NT_t>
00062 class Polynomial_impl
00063 {
00064   typedef std::vector<NT_t>                  Coefficients;
00065 public:
00066   typedef NT_t                             NT;
00067   typedef typename Coefficients::const_iterator  iterator;
00068   typedef NT                               result_type;
00069   typedef NT                               argument_type;
00070 
00071   //================
00072   // CONSTRUCTORS
00073   //================
00074 
00076   Polynomial_impl() {}
00077 
00079   Polynomial_impl(const NT& c) {
00080     coefs_.push_back(c);
00081   }
00082 
00084   template <class Iterator>
00085   Polynomial_impl(Iterator first, Iterator beyond): coefs_(first, beyond) {}
00086 
00087   //========================
00088   // ACCESS TO COEFFICIENTS
00089   //========================
00090 
00092 
00095   const NT& operator[](unsigned int i) const
00096   {
00097     CGAL_assertion( i < coefs_.size());
00098     //if (i < coefs_.size()) {
00099       return coefs_[i];
00100       /*}
00101     else {
00102       return zero_coef();
00103       }*/
00104   }
00105 
00106   //=====================================
00107   //     ITERATORS FOR COEFFICIENTS
00108   //=====================================
00109 
00110   iterator begin() const
00111   {
00112     return coefs_.begin();
00113   }
00114 
00115   iterator end() const
00116   {
00117     return coefs_.end();
00118   }
00119 
00120   //=========
00121   // DEGREE
00122   //=========
00123 
00125   int degree() const
00126   {
00127     return static_cast<int>(coefs_.size()) - 1;
00128   }
00129 
00130   //=============
00131   // PREDICATES
00132   //=============
00133 
00135   bool is_constant() const
00136   {
00137     return degree() < 1;
00138   }
00139 
00141 
00142   bool is_zero() const
00143   {
00144     CGAL_Polynomial_assertion( coefs_.empty() == (coefs_.size()==0) );
00145     return coefs_.empty();
00146   }
00147 
00148   //=======================
00149   //     OPERATORS
00150   //=======================
00151 
00153   This operator-() const
00154   {
00155     This ret;
00156     ret.coefs_.resize( coefs_.size() );
00157     for (unsigned int i=0; i < coefs_.size(); ++i) {
00158       ret.coefs_[i] = -coefs_[i];
00159     }
00160     return ret;
00161   }
00162 
00164   This operator+(const This &o) const
00165   {
00166     if (is_zero()) { return o; }
00167     else if (o.is_zero()) { return This(*this); }
00168     else {
00169       This ret;
00170       unsigned int new_deg = (std::max)(o.degree(), degree());
00171       ret.coefs_.resize(new_deg + 1);
00172       unsigned int md= (std::min)(degree(), o.degree());
00173       for (unsigned int i = 0; i <= md; ++i) {
00174         ret.coefs_[i] = operator[](i) + o[i];
00175       }
00176       for (int i=md+1; i <= degree(); ++i){
00177         ret.coefs_[i]= operator[](i);
00178       }
00179       for (int i=md+1; i <= o.degree(); ++i){
00180         ret.coefs_[i]= o[i];
00181       }
00182       CGAL_EXCESSIVE(std::cout << *this << " - " << o << " + " << ret << std::endl);
00183       ret.finalize();
00184       return ret;
00185     }
00186   }
00187 
00189   This operator-(const This &o) const
00190   {
00191     if (is_zero()) { return -o; }
00192     else if (o.is_zero()) { return This(*this); }
00193     else {
00194       This ret;
00195       unsigned int new_deg = (std::max)(o.degree(), degree());
00196       ret.coefs_.resize( new_deg + 1 );
00197       unsigned int md= (std::min)(degree(), o.degree());
00198       for (unsigned int i = 0; i <= md; ++i) {
00199         ret.coefs_[i] = operator[](i) - o[i];
00200       }
00201       for (int i=md+1; i <= degree(); ++i){
00202         ret.coefs_[i]= operator[](i);
00203       }
00204       for (int i=md+1; i <= o.degree(); ++i){
00205         ret.coefs_[i]= -o[i];
00206       }
00207       CGAL_EXCESSIVE(std::cout << *this << " - " << o << " = " << ret << std::endl);
00208       ret.finalize();
00209       return ret;
00210     }
00211   }
00212 
00214   This operator*(const This &o) const
00215   {
00216     if (is_zero()) return This(NT(0));
00217     else if (o.is_zero()) return o;
00218     This ret;
00219     ret.coefs_.resize( degree() + o.degree() + 1 );
00220     // the following for-loop makes sure that the values on ret.coefs_
00221     // are properly initialized with zero.
00222     for (int i = 0; i <= degree() + o.degree(); ++i) {
00223       ret.coefs_[i] = NT(0);
00224     }
00225     for (unsigned int i = 0; i < coefs_.size(); ++i) {
00226       for (unsigned int j = 0; j < o.coefs_.size(); ++j) {
00227         NT prev = ret.coefs_[i+j];
00228         NT result = prev + operator[](i) * o[j];
00229         ret.coefs_[i+j] = result;
00230       }
00231     }
00232     CGAL_EXCESSIVE(std::cout << *this << " * " << o << " = " << ret << std::endl);
00233     return ret;
00234   }
00235 
00237   This operator+(const NT& a) const
00238   {
00239     if ( is_zero() ) { return This(a); }
00240 
00241     This res(*this);
00242     res.coefs_[0] += a;
00243     CGAL_EXCESSIVE(std::cout << *this << " + " << a << " = " << res << std::endl);
00244     return res;
00245   }
00246 
00248   This operator-(const NT& a) const
00249   {
00250     return (*this) + (-a);
00251   }
00252 
00254   This operator*(const NT& a) const
00255   {
00256     if ( is_zero() || CGAL_NTS sign(a)==ZERO ) { return This(); }
00257 
00258     This res;
00259     unsigned int deg = degree();
00260     res.coefs_.resize(deg + 1, NT(0));
00261     for (unsigned int i = 0; i <= deg; i++) {
00262       res.coefs_[i] = coefs_[i] * a;
00263     }
00264     return res;
00265   }
00266 
00268   This operator/(const NT& a) const
00269   {
00270     NT inv_a = NT(1) / a;
00271     return (*this) * inv_a;
00272   }
00273 
00274   //=======================
00275   // VALUE OF POLYNOMIAL
00276   //=======================
00277 
00279 
00284   NT operator()(const NT &t) const
00285   {
00286     if (is_zero()) return NT(0);
00287     else if (degree()==0 /* || t==NT(0)*/ ) {
00288       return operator[](0);
00289     }
00290     else {
00291       return evaluate_polynomial(coefs_, t);
00292     }
00293   }
00294 
00295 
00297 
00299   NT value_at(const NT &t) const
00300   {
00301     return operator()(t);
00302   }
00303 
00304 
00306   bool operator!=(const This &o) const
00307   {
00308     return !operator==(o);
00309   }
00310 
00311 
00313   bool operator==(const This &o) const
00314   {
00315     if (degree() != o.degree()) return false;
00316     int max_size = (std::max)(o.coefs_.size(), coefs_.size());
00317     for (int i = 0; i < max_size; ++i) {
00318       if (o[i] != operator[](i)) return false;
00319     }
00320     return true;
00321   }
00322 
00323 
00324   void print()const
00325   {
00326     write(std::cout);
00327   }
00328 
00329 
00331   template <class charT, class Traits>
00332   void read(std::basic_istream<charT, Traits> &in) {
00333     bool pos=(in.peek()!='-');
00334     if (in.peek() == '+' || in.peek() == '-') {
00335       char c;
00336       in >> c;
00337     }
00338     char v='\0';
00339     while (true) {
00340       char vc, t;
00341       NT coef;
00342       // eat
00343       in >> coef;
00344       if (in.fail()) {
00345         //std::cout << "Read ";
00346         //write(std::cout);
00347         //std::cout << std::endl;
00348         return;
00349       }
00350       //std::cout << "Read " << coef << std::endl;
00351 
00352       //NT cp1= coef+NT(1);
00353       unsigned int pow;
00354       char p= in.peek();
00355       if (in.peek() =='*') {
00356         in >> t >> vc;
00357         if (t != '*') {
00358           in.setstate(std::ios_base::failbit);
00359           return;
00360           //return in;
00361         }
00362         if ( !(v=='\0' || v== vc)) {
00363           in.setstate(std::ios_base::failbit);
00364           return;
00365           //return in;
00366         }
00367         v=vc;
00368         p=in.peek();
00369         if (in.peek() =='^') {
00370           char c;
00371           in  >> c >> pow;
00372         }
00373         else {
00374           pow=1;
00375         }
00376       }
00377       else {
00378         pow=0;
00379       }
00380 
00381       if (coefs_.size() <=pow) {
00382         coefs_.resize(pow+1, NT(0));
00383       }
00384 
00385       if (!pos) coef=-coef;
00386       //std::cout << "Read 2 " << coef << "*t^" << pow << std::endl;
00387       coefs_[pow]=coef;
00388       //std::cout << "Read " << coefs_[pow] << std::endl;
00389 
00390       char n= in.peek();
00391       if (n=='+' || n=='-') {
00392         pos= (n!='-');
00393         char e;
00394         in >> e;
00395       } else {
00396         /*bool f= in.fail();
00397           bool g= in.good();
00398           bool e= in.eof();
00399           bool b= in.bad();*/
00400         // This is necessary since peek could have failed if we hit the end of the buffer
00401         // it would better to do without peek, but that is too messy
00402         in.clear();
00403         //std::cout << f << g << e << b<<std::endl;
00404         break;
00405       }
00406     };
00407   }
00408 
00409 
00411   template <class C, class T>
00412   void write(std::basic_ostream<C,T> &out) const
00413   {
00414     std::basic_ostringstream<C,T> s;
00415     s.flags(out.flags());
00416     s.imbue(out.getloc());
00417     s.precision(12);
00418     if (coefs_.size()==0) {
00419       s << "0";
00420     }
00421     else {
00422       for (unsigned int i=0; i< coefs_.size(); ++i) {
00423         if (i==0) {
00424           if (coefs_[i] != 0) s << coefs_[i];
00425         }
00426         else {
00427           if ( coefs_[i] != 0 ) {
00428             if (coefs_[i] >0) s << "+";
00429             s << coefs_[i] << "*t";
00430             if (i != 1) {
00431               s << "^" << i;
00432             }
00433           }
00434         }
00435       }
00436     }
00437 
00438     out << s.str();
00439   }
00440 
00441 
00442   /*
00443     typedef typename Coefficients::const_iterator Coefficients_iterator;
00444     Coefficients_iterator coefficients_begin() const {
00445     return coefs_.begin();
00446 
00447     }
00448 
00449     Coefficients_iterator coefficients_end() const {
00450     return coefs_.end();
00451     }*/
00452 
00453 protected:
00454 
00455   std::size_t size() const {return coefs_.size();}
00456 
00457   static const NT & zero_coef() {
00458     static NT z(0);
00459     return z;
00460   }
00461 
00462 
00464   Coefficients coefs_;
00465 };
00466 
00467 template < class T, class NT,  class C, class Tr>
00468 inline std::ostream &operator<<(std::basic_ostream<C, Tr> &out,
00469                                 const Polynomial_impl<T, NT> &poly)
00470 {
00471   poly.write(out);
00472   return out;
00473 }
00474 
00475 
00476 template < class T, class NT, class C, class Tr>
00477 inline std::istream &operator>>(std::basic_istream<C, Tr> &in,
00478                                 Polynomial_impl<T, NT> &poly)
00479 {
00480   poly.read(in);
00481   //std::cout << "Read " << poly << std::endl;
00482   return in;
00483 }
00484 
00485 
00487 template <class T, class NT>
00488 inline T operator*(const NT &a, const Polynomial_impl<T, NT> &poly)
00489 {
00490   return (poly * a);
00491 }
00492 
00493 
00495 template <class T, class NT>
00496 inline T operator+(const NT &a, const Polynomial_impl<T, NT> &poly)
00497 {
00498   return (poly + a);
00499 }
00500 
00501 
00503 template < class T, class NT>
00504 inline T  operator+(int a, const Polynomial_impl<T, NT> &poly)
00505 {
00506   return (poly + NT(a));
00507 }
00508 
00509 
00511 template <class T, class NT>
00512 inline T operator-(const NT &a, const Polynomial_impl<T, NT> &poly)
00513 {
00514   return -(poly - a);
00515 }
00516 
00517 
00519 template <class T, class NT>
00520 inline T operator-(int a, const Polynomial_impl<T, NT> &poly)
00521 {
00522   return -(poly - NT(a));
00523 }
00524 
00525 
00526 #undef CGAL_EXCESSIVE
00527 
00528 /*template <class NT>
00529 class Input_rep<Polynomial<NT> , CGAL::Maple_format_tag > {
00530   Input_rep(Polynomial<NT>& p): p_(p){}
00531   std::istream & operator()(std::istream &in) const {
00532     
00533   }
00534   };*/
00535 
00536 CGAL_POLYNOMIAL_END_INTERNAL_NAMESPACE
00537 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines