BWAPI
|
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