algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/series.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : series.hpp
00004 * DESCRIPTION: Univariate power series
00005 * COPYRIGHT  : (C) 2004  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #ifndef __MMX_SERIES_HPP
00014 #define __MMX_SERIES_HPP
00015 #include <algebramix/series_naive.hpp>
00016 
00017 namespace mmx {
00018 #define Series_variant(C) series_variant_helper<C>::SV
00019 #define TMPL template<typename C, typename V>
00020 #define TMPLK template<typename C, typename V, typename K>
00021 #define Format format<C>
00022 #define Series series<C,V>
00023 #define Series_rep series_rep<C,V>
00024 #define Recursive_series_rep recursive_series_rep<C,V>
00025 #define Polynomial polynomial<C, typename series_polynomial_helper<C,V>::PV>
00026 TMPL syntactic flatten (const Series& f, const syntactic& z);
00027 TMPL Series lshiftz (const Series& f, const int& shift= 1);
00028 TMPL Series rshiftz (const Series& f, const int& shift= 1);
00029   
00030 /******************************************************************************
00031 * Dense series
00032 ******************************************************************************/
00033 
00034 TMPL
00035 class series_rep REP_STRUCT_1(C) {
00036 public:   // should be protected
00037   C*  a;  // coefficients
00038   nat n;  // number of computed coefficients
00039   nat l;  // number of allocated coefficients
00040           // a[n],...,a[l-1] may be used by relaxed computations
00041 
00042   inline series_rep (const Format& fm):
00043     Format (fm), a (mmx_new<C> (0)), n (0), l (0) {}
00044   inline virtual ~series_rep () { mmx_delete<C> (a, l); }
00045   inline C zero () { return promote (0, this->tfm ()); }
00046   inline C one () { return promote (1, this->tfm ()); }
00047   inline Series me () const;
00048   virtual C next () = 0;
00049   virtual syntactic expression (const syntactic& z) const = 0;
00050 
00051 public:
00052   virtual void Set_order (nat l2);
00053   virtual void Increase_order (nat l2=0);
00054   virtual inline bool test_exact_zero () const { return false; }
00055   friend class Series;
00056 };
00057 
00058 TMPL
00059 class series {
00060 INDIRECT_PROTO_2 (series, series_rep, C, V)
00061   typedef implementation<series_defaults,V> Ser;
00062   typedef typename Ser::template global_variables<Series> S;
00063 
00064 public:
00065   static inline generic get_variable_name () {
00066     return S::get_variable_name (); }
00067   static inline void set_variable_name (const generic& x) {
00068     S::set_variable_name (x); }
00069 
00070   static inline nat get_output_order () {
00071     return S::get_output_order (); }
00072   static inline void set_output_order (const nat& x) {
00073     S::set_output_order (x); }
00074 
00075   static inline nat get_cancel_order () {
00076     return S::get_cancel_order (); }
00077   static inline void set_cancel_order (const nat& x) {
00078     S::set_cancel_order (x); }
00079 
00080   static inline bool get_formula_output () {
00081     return S::get_formula_output (); }
00082   static inline void set_formula_output (const bool& x) {
00083     S::set_formula_output (x); }
00084 
00085 public:
00086   series ();
00087   series (const Format& fm);
00088   series (const C& c);
00089   template<typename T> series (const T& c);
00090   template<typename T> series (const T& c, const Format& fm);
00091   template<typename T> series (const T& c, nat deg);
00092   template<typename T> series (const polynomial<T>& P);
00093   template<typename T, typename W>
00094   series (const series<T,W>& f);
00095   template<typename T, typename W>
00096   series (const series<T,W>& f, const Format& fm);
00097   series (const vector<C>& coeffs);
00098   series (const iterator<C>& it, const string& name= "explicit");
00099   series (C (*coeffs) (nat), const string& name= "explicit");
00100   const C& operator [] (nat n) const;
00101   const C* operator () (nat start, nat end) const;
00102 };
00103 INDIRECT_IMPL_2 (series, series_rep, typename C, C, typename V, V)
00104 DEFINE_UNARY_FORMAT_2 (series)
00105 
00106 STYPE_TO_TYPE(TMPL,scalar_type,Series,C);
00107 
00108 TMPL inline Format CF (const Series& f) { return f->tfm (); }
00109 
00110 TMPL inline void set_variable_name (const Series&, const generic& x) {
00111   return Series::set_variable_name (x); }
00112 TMPL inline void set_output_order (const Series&, const nat& n) {
00113   return Series::set_output_order (n); }
00114 TMPL inline void set_cancel_order (const Series&, const nat& n) {
00115   return Series::set_cancel_order (n); }
00116 TMPL inline void set_formula_output (const Series&, const bool& b) {
00117   return Series::set_formula_output (b); }
00118 
00119 /******************************************************************************
00120 * Recursive series
00121 ******************************************************************************/
00122 
00123 TMPL
00124 class recursive_series_rep: public Series_rep {
00125 public:
00126   Series eq;
00127 public:
00128   inline recursive_series_rep (const Format& fm):
00129     Series_rep (fm) {}
00130   virtual Series initialize () = 0;
00131   C& initial (nat n2) {
00132     if (n2>=this->n) { this->n = n2+1; Set_order (this->n); }
00133     return this->a[n2]; }
00134   virtual void Increase_order (nat l) {
00135     Series_rep::Increase_order (l);
00136     increase_order (eq, l); }
00137   inline C next () { return eq[this->n]; }
00138 };
00139 
00140 TMPL
00141 class recursive_container_series_rep: public Series_rep {
00142   Series f;
00143 public:
00144   recursive_container_series_rep (const Series& f2):
00145     Series_rep (CF(f2)), f (f2) {
00146     Recursive_series_rep* rep= (Recursive_series_rep*) f.operator -> ();
00147     rep->eq= rep->initialize (); }
00148   ~recursive_container_series_rep () {
00149     Recursive_series_rep* rep= (Recursive_series_rep*) f.operator -> ();
00150     rep->eq= Series (); }
00151   syntactic expression (const syntactic& z) const { return flatten (f, z); }
00152   virtual void Increase_order (nat l) {
00153     Series_rep::Increase_order (l);
00154     increase_order (f, l); }
00155   C next () { return f[this->n]; }
00156 };
00157 
00158 TMPL Series
00159 recursive (const Series& f) {
00160   return (Series_rep*) new recursive_container_series_rep<C,V> (f);
00161 }
00162 
00163 /******************************************************************************
00164 * Routines on dense series
00165 ******************************************************************************/
00166 
00167 TMPL inline generic var (const Series& f) {
00168   (void) f; return Series::get_variable_name ();
00169 }
00170 
00171 TMPL inline Series
00172 Series_rep::me () const {
00173   return Series (this, true);
00174 }
00175 
00176 TMPL void
00177 Series_rep::Set_order (nat l2) {
00178   typedef typename series_polynomial_helper<C,V>::PV PV;
00179   typedef implementation<polynomial_linear,PV> Pol;
00180   if (l2 <= l) return;
00181   C* b= mmx_new<C> (l2);
00182   Pol::copy (b, a, l);
00183   Pol::clear (b+l, l2-l);
00184   mmx_delete<C> (a, l);
00185   a= b;
00186   l= l2;
00187 }
00188 
00189 TMPL void
00190 Series_rep::Increase_order (nat l2) {
00191   l2= max (l2, l << 1);
00192   Set_order (max ((nat) 1, l2));
00193 }
00194 
00195 TMPL void
00196 increase_order (const Series& f, nat l) {
00197   if (f->l < l) inside (f) -> Increase_order (l);
00198 }
00199 
00200 TMPL const C&
00201 Series::operator [] (nat n) const {
00202   if (n <  rep->n) return rep->a[n];
00203   if (n >= rep->l) rep->Increase_order (n+1);
00204   while (rep->n <= n) {
00205     rep->a[rep->n]= rep->next ();
00206     //mmout << "{" << rep->n << ";" << this << "}";
00207     rep->n++;
00208   }
00209   // mmout << (*this) << " [" << n << "] -> " << rep->a[n] << "\n";
00210   return rep->a[n];
00211 }
00212 
00213 TMPL const C*
00214 Series::operator () (nat start, nat end) const {
00215   if (end <= rep->n) return rep->a + start;
00216   if (end >= rep->l) rep->Increase_order (end);
00217   while (rep->n < end) {
00218     rep->a[rep->n]= rep->next ();
00219     //mmout << "{" << rep->n << ";" << this << "}";
00220     rep->n++;
00221   }
00222   return rep->a + start;
00223 }
00224 
00225 TMPL Polynomial
00226 truncate (const Series& f, nat n) {
00227   typedef typename series_polynomial_helper<C,V>::PV PV;
00228   nat l= aligned_size<C,PV> (n);
00229   C* coeffs= mmx_formatted_new<C> (l, CF(f));
00230   if (n>0) (void) f[n-1];
00231   for (nat i=0; i<n; i++) coeffs[i]= f[i];
00232   return Polynomial (coeffs, n, l, CF(f));
00233 }
00234 
00235 TMPL Polynomial
00236 range (const Series& f, nat start, nat end) {
00237   typedef typename series_polynomial_helper<C,V>::PV PV;
00238   nat n= (end >= start? end - start: 0);
00239   nat l= aligned_size<C,PV> (n);
00240   C* coeffs= mmx_formatted_new<C> (l, CF(f));
00241   if (end>start) (void) f[end-1];
00242   for (nat i=0; i<n; i++) coeffs[i]= f[i + start];
00243   return Polynomial (coeffs, n, l, CF(f));
00244 }
00245 
00246 /******************************************************************************
00247 * Series iterator
00248 ******************************************************************************/
00249 
00250 TMPL
00251 class series_iterator_rep: public iterator_rep<C> {
00252   Series f;  // the series to traverse
00253   nat i;     // current position
00254 protected:
00255   bool is_busy () { return true; }
00256   void advance () { i++; }
00257   C current () { return f[i]; }
00258 public:
00259   series_iterator_rep (const Series& f2):
00260     iterator_rep<C> (CF(f2)), f(f2), i(0) {}
00261 };
00262 
00263 TMPL iterator<C>
00264 iterate (const Series& f) {
00265   return iterator<C> (new series_iterator_rep<C,V> (f));
00266 }
00267 
00268 /******************************************************************************
00269 * Hashing and equality testing
00270 ******************************************************************************/
00271 
00272 HARD_TO_EXACT_IDENTITY_SUGAR(TMPL,Series)
00273 
00274 template<typename Op, typename C, typename V> nat
00275 unary_hash (const Series& s) {
00276   register nat i, h= 7531;
00277   for (i=0; i< Series::get_cancel_order (); i++)
00278     h= (h<<1) ^ (h<<5) ^ (h>>27) ^ Op::op (s[i]);
00279   return h;
00280 }
00281 
00282 TMPL inline nat
00283 hash (const Series& s) {
00284   return unary_hash<hash_op> (s);
00285 }
00286 
00287 template<typename Op,typename C,typename V> inline bool
00288 binary_test (const Series& f1, const Series& f2) {
00289   for (nat n=0; n< Series::get_cancel_order (); n++)
00290     if (Op::not_op (f1[n], f2[n])) return false;
00291   return true;
00292 }
00293 
00294 TMPL bool operator == (const Series& f1, const Series& f2) {
00295   return binary_test<equal_op> (f1, f2); }
00296 TMPL bool operator != (const Series& f1, const Series& f2) {
00297   return !binary_test<equal_op> (f1, f2); }
00298 
00299 TMPL bool is_exact_zero (const Series& f) {
00300   return f->test_exact_zero (); }
00301 
00302 /******************************************************************************
00303 * Printing series
00304 ******************************************************************************/
00305 
00306 TMPL syntactic
00307 flatten (const Series& f, const syntactic& z) {
00308   if (Series::get_formula_output ()) return f->expression (z);
00309   syntactic s= 0;
00310   nat order= Series::get_output_order ();
00311   for (nat i=0; i<order; i++) {
00312     (void) f[order-1];
00313     C coeff= f[i];
00314     s= s + flatten (coeff) * pow (z, i);
00315   }
00316   s= s + apply ("O", pow (z, syntactic (order)));
00317   return s;
00318 }
00319 
00320 TMPL syntactic
00321 flatten (const Series& f) {
00322   return flatten (f, as_syntactic (var (f)));
00323 }
00324 
00325 /******************************************************************************
00326 * Comparisons
00327 ******************************************************************************/
00328 
00329 TMPL int
00330 val (const Series& f) {
00331   for (nat n=0; n< Series::get_cancel_order (); n++)
00332     if (f[n] != 0) return n;
00333   return (int) (((nat) (-1)) >> 1);
00334 }
00335 
00336 TMPL int
00337 sign (const Series& f) {
00338   for (nat n=0; n< Series::get_cancel_order (); n++) {
00339     int sgn= sign (f[n]);
00340     if (sgn != 0) return sgn;
00341   }
00342   return 0;
00343 }
00344 
00345 TMPL int
00346 compare (const Series& f1, const Series& f2) {
00347   for (nat n=0; n< Series::get_cancel_order (); n++) {
00348     int sgn= compare (f1[n], f2[n]);
00349     if (sgn != 0) return sgn;
00350   }
00351   return 0;
00352 }
00353 
00354 EQUAL_INT_SUGAR(TMPL,Series)
00355 COMPARE_SUGAR(TMPL,Series)
00356 COMPARE_INT_SUGAR(TMPL,Series)
00357 
00358 /******************************************************************************
00359 * Explicit series
00360 ******************************************************************************/
00361 
00362 TMPL
00363 class zero_series_rep: public Series_rep {
00364 public:
00365   zero_series_rep (const Format& fm):
00366     Series_rep (fm) {}
00367   syntactic expression (const syntactic&) const {
00368     return flatten (0); }
00369   bool test_exact_zero () const {
00370     return true; }
00371   C next () { return this->zero (); }
00372 };
00373 
00374 TMPL Series::series () {
00375   rep= new zero_series_rep<C,V> (format<C> (no_format ())); }
00376 TMPL Series::series (const Format& fm) {
00377   rep= new zero_series_rep<C,V> (fm); }
00378 
00379 TMPL
00380 class scalar_series_rep: public Series_rep {
00381   C c;
00382 public:
00383   scalar_series_rep (const C& c2):
00384     Series_rep (get_format (c2)), c(c2) {}
00385   syntactic expression (const syntactic& z) const {
00386     (void) z; return flatten (c); }
00387   bool test_exact_zero () const {
00388     return is_exact_zero (c); }
00389   C next () { return this->n == 0 ? c : this->zero (); }
00390 };
00391 
00392 TMPL Series::series (const C& c) {
00393   rep= new scalar_series_rep<C,V> (c); }
00394 TMPL template<typename T> Series::series (const T& c) {
00395   rep= new scalar_series_rep<C,V> (as<C> (c)); }
00396 TMPL template<typename T> Series::series (const T& c, const Format& fm) {
00397   rep= new scalar_series_rep<C,V> (promote (c, fm)); }
00398 
00399 TMPL
00400 class polynomial_series_rep: public Series_rep {
00401   Polynomial P;
00402 public:
00403   polynomial_series_rep (const polynomial<C>& P2):
00404     Series_rep (CF(P2)), P (as<Polynomial> (P2)) {}
00405   syntactic expression (const syntactic& z) const {
00406     return flatten (P, z); }
00407   bool test_exact_zero () const {
00408     return is_exact_zero (P); }
00409   C next () {
00410     return this->n < N(P)? P[this->n]: this->zero (); }
00411 };
00412 
00413 TMPL template<typename T>
00414 Series::series (const T& c, nat deg) {
00415   rep= new polynomial_series_rep<C,V> (polynomial<C> (as<C> (c), deg));
00416 }
00417 
00418 TMPL template<typename T>
00419 Series::series (const polynomial<T>& P) {
00420   rep= new polynomial_series_rep<C,V> (polynomial<C> (P));
00421 }
00422 
00423 TMPL
00424 Series::series (const vector<C>& coeffs) {
00425   rep= new polynomial_series_rep<C,V> (polynomial<C> (coeffs));
00426 }
00427 
00428 TMPL
00429 class iterator_series_rep: public Series_rep {
00430   iterator<C> it;
00431   string name;
00432 public:
00433   iterator_series_rep (const iterator<C>& it2, const string& name2):
00434     Series_rep (CF(it)), it (it2), name (name2) {}
00435   syntactic expression (const syntactic& z) const {
00436     return apply (syntactic (name), z); }
00437   C next () {
00438     if (busy (it)) {
00439       C c= *it; ++it; return c; }
00440     else return this->zero (); }
00441 };
00442 
00443 TMPL
00444 Series::series (const iterator<C>& it, const string& name) {
00445   rep= new iterator_series_rep<C,V> (it, name);
00446 }
00447 
00448 /******************************************************************************
00449 * Casting
00450 ******************************************************************************/
00451 
00452 template<typename C, typename V>
00453 class fast_series_rep: public series_rep<Fast_type(C) > {
00454   Series f;
00455 public:
00456   fast_series_rep (const Series& f2):
00457     series_rep<Fast_type(C) > (fast (CF(f2))), f (f2) {}
00458   syntactic expression (const syntactic& z) const {
00459     return apply (GEN_FAST, flatten (f, z)); }
00460   void Increase_order (nat l) {
00461     Series_rep::Increase_order (l);
00462     increase_order (f, l); }
00463   Fast_type(C) next () { return fast (f[this->n]); }
00464 };
00465 
00466 template<typename C, typename V>
00467 class slow_series_rep: public Series_rep {
00468   series<Fast_type(C) > f;
00469 public:
00470   slow_series_rep (const series<Fast_type(C) >& f2):
00471     Series_rep (slow<C> (CF(f2))), f (f2) {}
00472   syntactic expression (const syntactic& z) const {
00473     return apply (GEN_SLOW, flatten (f, z)); }
00474   void Increase_order (nat l) {
00475     Series_rep::Increase_order (l);
00476     increase_order (f, l); }
00477   C next () { return slow<C> (f[this->n]); }
00478 };
00479 
00480 TMPL
00481 struct fast_helper<Series > {
00482   typedef series<Fast_type(C) > fast_type;
00483   static inline fast_type dd (const Series& f) {
00484     return (series_rep<Fast_type(C) >*) new fast_series_rep<C,V> (f); }
00485   static inline Series uu (const fast_type& f) {
00486     return (Series_rep*) new slow_series_rep<C,V> (f); }
00487 };
00488 
00489 template<typename C, typename V, typename K, typename W>
00490 class cast_series_rep: public Series_rep {
00491   series<K,W> f;
00492 public:
00493   cast_series_rep (const series<K,W>& f2):
00494     Series_rep (as<Format> (CF(f2))), f (f2) {}
00495   cast_series_rep (const series<K,W>& f2, const Format& fm):
00496     Series_rep (fm), f (f2) {}
00497   syntactic expression (const syntactic& z) const { return flatten (f, z); }
00498   void Increase_order (nat l) {
00499     Series_rep::Increase_order (l);
00500     increase_order (f, l); }
00501   C next () { return as<C> (f[this->n]); }
00502 };
00503 
00504 TMPL template<typename T, typename W>
00505 Series::series (const series<T,W>& f) {
00506   rep= new cast_series_rep<C,V,T,W> (f);
00507 }
00508 
00509 TMPL template<typename T, typename W>
00510 Series::series (const series<T,W>& f, const Format& fm) {
00511   rep= new cast_series_rep<C,V,T,W> (f, fm);
00512 }
00513 
00514 template<typename T, typename F, typename TV, typename FV>
00515 struct as_helper<series<T,TV>,series<F,FV> > {
00516   static inline series<T,TV>
00517   cv (const series<F,FV>& f) {
00518     return (series_rep<T,TV>*) new cast_series_rep<T,TV,F,FV> (f); }
00519 };
00520 
00521 template<typename T, typename F, typename TV, typename FV> inline void
00522 set_as (series<T,TV>& r, const series<F,FV>& f) {
00523   r= series<T,TV> (f, CF(r));
00524 }
00525 
00526 template<typename C, typename V, typename T> inline void
00527 set_as (Series& r, const T& x) {
00528   r= Series (x, CF(r));
00529 }
00530 
00531 /******************************************************************************
00532 * Scalar abstractions
00533 ******************************************************************************/
00534 
00535 template<typename Op,typename C,typename V,typename X> inline Series
00536 binary_scalar_series (const Series& f, const X& x) {
00537   typedef implementation<series_scalar_abstractions,V> Ser;
00538   typedef typename Ser::template binary_scalar_series_rep<Op,C,V,X>
00539     Binary_rep;
00540   return (Series_rep*) new Binary_rep (f, x);
00541 }
00542 
00543 template<typename Op,typename C,typename V,typename X, typename Y>
00544 inline Series
00545 ternary_scalar_series (const Series& f, const X& x, const Y& y) {
00546   typedef implementation<series_scalar_abstractions,V> Ser;
00547   typedef typename Ser::template ternary_scalar_series_rep<Op,C,V,X,Y>
00548     Ternary_rep;
00549   return (Series_rep*) new Ternary_rep (f, x, y);
00550 }
00551 
00552 /******************************************************************************
00553 * Map abstractions
00554 ******************************************************************************/
00555 
00556 template<typename Op, typename C, typename V, typename S, typename SV> Series
00557 unary_map_as (const series<S,SV>& f) {
00558   typedef implementation<series_map_as_abstractions,V> Ser;
00559   typedef typename Ser::
00560     template unary_map_as_series_rep<Op,C,V,S,SV> Map_as_rep;
00561   return (Series_rep*) new Map_as_rep (f);
00562 }
00563 
00564 /******************************************************************************
00565 * Dynamic mappers
00566 ******************************************************************************/
00567 
00568 template<typename C, typename V, typename S, typename SV>
00569 class map_series_rep: public Series_rep {
00570 protected:
00571   function_1<C,Argument(S) > fun;
00572   series<S,SV> f;
00573 public:
00574   inline map_series_rep (const function_1<C,Argument(S) >& fun2,
00575                          const series<S,SV>& f2, const Format& fm):
00576     Series_rep (fm), fun (fun2), f (f2) {}
00577   syntactic expression (const syntactic& z) const {
00578     return syn (flatten (fun), flatten (f, z)); }
00579   virtual void Increase_order (nat l) {
00580     Series_rep::Increase_order (l);
00581     increase_order (f, l); }
00582   virtual C next () {
00583     return fun (f[this->n]); }
00584 };
00585 
00586 template<typename S1, typename D> series<D>
00587 map (const function_1<D,Argument(S1) >& fun,
00588      const series<S1>& f, const format<D>& fm)
00589 {
00590   typedef map_series_rep<D,typename Series_variant(D),
00591                          S1,typename Series_variant(S1) > Mapper;
00592   return (series_rep<D>*) new Mapper (fun, f, fm);
00593 }
00594 
00595 template<typename S1, typename D> inline series<D>
00596 map (D (*fun) (const S1&),
00597      const series<S1>& x1, const format<D>& fm) {
00598   return map (function_1<D,Argument(S1) > (fun), x1, fm);
00599 }
00600 
00601 /******************************************************************************
00602 * Recursive abstractions
00603 ******************************************************************************/
00604 
00605 template<typename Op,typename C> inline series<C>
00606 nullary_recursive_series (const C& c= Op::template op<C> ()) {
00607   typedef typename Series_variant (C) V;
00608   typedef implementation<series_recursive_abstractions,V> Ser;
00609   typedef typename Ser::template nullary_recursive_series_rep<Op,C,V> Nullary;
00610   series_rep<C>* rep= new Nullary (c);
00611   return recursive (series<C> (rep));
00612 }
00613 
00614 template<typename Op,typename C,typename V> inline Series
00615 unary_recursive_series (const Series& f) {
00616   typedef implementation<series_recursive_abstractions,V> Ser;
00617   typedef typename Ser::template unary_recursive_series_rep<Op,C,V> Unary;
00618   Series_rep* rep= new Unary (f);
00619   return recursive (Series (rep));
00620 }
00621 
00622 template<typename Op,typename C,typename V> inline Series
00623 unary_recursive_series (const Series& f, const C& c) {
00624   typedef implementation<series_recursive_abstractions,V> Ser;
00625   typedef typename Ser::template unary_recursive_series_rep<Op,C,V> Unary;
00626   Series_rep* rep= new Unary (f, c);
00627   return recursive (Series (rep));
00628 }
00629 
00630 template<typename Op,typename C,typename V> inline Series
00631 binary_recursive_series (const Series& f, const Series& g) {
00632   typedef implementation<series_recursive_abstractions,V> Ser;
00633   typedef typename Ser::template binary_recursive_series_rep<Op,C,V> Binary;
00634   Series_rep* rep= new Binary (f, g);
00635   return recursive (Series (rep));
00636 }
00637 
00638 template<typename Op,typename C,typename V,typename X> inline Series
00639 binary_scalar_recursive_series (const Series& f, const X& x) {
00640   typedef implementation<series_recursive_abstractions,V> Ser;
00641   typedef typename Ser::
00642     template binary_scalar_recursive_series_rep<Op,C,V,X> Binary;
00643   Series_rep* rep= new Binary (f, x);
00644   return recursive (Series (rep));
00645 }
00646 
00647 template<typename Op,typename C,typename V,typename X> inline Series
00648 binary_scalar_recursive_series (const Series& f, const X& x, const C& init) {
00649   typedef implementation<series_recursive_abstractions,V> Ser;
00650   typedef typename Ser::
00651     template binary_scalar_recursive_series_rep<Op,C,V,X> Binary;
00652   Series_rep* rep= new Binary (f, x, init);
00653   return recursive (Series (rep));
00654 }
00655 
00656 /******************************************************************************
00657 * Function abstractions
00658 ******************************************************************************/
00659 
00660 template<typename Op,typename C,typename V> inline Series
00661 unary_series (const Series& f) {
00662   typedef implementation<series_abstractions,V> Ser;
00663   typedef typename Ser::template unary_series_rep<Op,C,V> Unary;
00664   return (Series_rep*) new Unary (f);
00665 }
00666 
00667 template<typename Op,typename C,typename V> inline Series
00668 binary_series (const Series& f, const Series& g) {
00669   typedef implementation<series_abstractions,V> Ser;
00670   typedef typename Ser::template binary_series_rep<Op,C,V> Binary;
00671   return (Series_rep*) new Binary (f, g);
00672 }
00673 
00674 /******************************************************************************
00675 * Coefficient-wise operations
00676 ******************************************************************************/
00677 
00678 TMPL inline Series
00679 operator + (const Series& f, const Series& g) {
00680   if (is_exact_zero (f)) return g;
00681   if (is_exact_zero (g)) return f;
00682   return binary_series<add_op> (f, g);
00683 }
00684 
00685 TMPL inline Series
00686 operator + (const C& c, const Series& f) {
00687   if (is_exact_zero (c)) return f;
00688   if (is_exact_zero (f)) return Series (c);
00689   return binary_series<add_op> (Series (c), f);
00690 }
00691 
00692 TMPL inline Series
00693 operator + (const Series& f, const C& c) {
00694   if (is_exact_zero (c)) return f;
00695   if (is_exact_zero (f)) return Series (c);
00696   return binary_series<add_op> (f, Series (c));
00697 }
00698 
00699 TMPL inline Series
00700 operator - (const Series& f) {
00701   if (is_exact_zero (f)) return f;
00702   return unary_series<neg_op> (f);
00703 }
00704 
00705 TMPL inline Series
00706 operator - (const Series& f, const Series& g) {
00707   if (is_exact_zero (f)) return -g;
00708   if (is_exact_zero (g)) return f;
00709   return binary_series<sub_op> (f, g);
00710 }
00711 
00712 TMPL inline Series
00713 operator - (const C& c, const Series& f) {
00714   if (is_exact_zero (c)) return -f;
00715   if (is_exact_zero (f)) return Series (c);
00716   return binary_series<sub_op> (Series (c), f);
00717 }
00718 
00719 TMPL inline Series
00720 operator - (const Series& f, const C& c) {
00721   if (is_exact_zero (f)) return Series (-c);
00722   if (is_exact_zero (c)) return f;
00723   return binary_series<sub_op> (f, Series (c));
00724 }
00725 
00726 TMPL inline Series
00727 operator * (const Series& f, const C& c) {
00728   if (is_exact_zero (f) || is_exact_zero (c))
00729     return Series (get_format (c));
00730   return binary_scalar_series<rmul_op> (f, c);
00731 }
00732 
00733 TMPL inline Series
00734 operator * (const C& c, const Series& f) {
00735   if (is_exact_zero (f) || is_exact_zero (c))
00736     return Series (get_format (c));
00737   return binary_scalar_series<lmul_op> (f, c);
00738 }
00739 
00740 /******************************************************************************
00741 * Gcd -- over fields only
00742 ******************************************************************************/
00743 
00744 TMPL
00745 class gcd_series_rep: public Series_rep {
00746 protected:
00747   Series f, g;
00748   int v; // gcd is z^v
00749 public:
00750   inline gcd_series_rep (const Series& f2, const Series& g2):
00751     Series_rep (CF(f2)), f (f2), g (g2), v (-1) {}
00752   syntactic expression (const syntactic& z) const {
00753     return gcd (flatten (f, z), flatten (g, z)); }
00754   virtual void Increase_order (nat l) {
00755     Series_rep::Increase_order (l);
00756     increase_order (f, l);
00757     increase_order (g, l); }
00758   virtual C next () {
00759     if (v >= 0) return this->zero ();
00760     if (f[this->n] != 0 || g[this->n] != 0) {
00761       v= this->n;
00762       return this->one ();
00763     }
00764     return this->zero (); }
00765 };
00766 
00767 TMPL inline Series
00768 gcd (const Series& f, const Series& g) {
00769   return (Series_rep*) new gcd_series_rep<C,V> (f, g);
00770 }
00771 
00772 TMPL
00773 class lcm_series_rep: public Series_rep {
00774 protected:
00775   Series f, g;
00776   int v_f, v_g; // respective valuations
00777 public:
00778   inline lcm_series_rep (const Series& f2, const Series& g2):
00779     Series_rep (CF(f2)), f(f2), g (g2), v_f (-1), v_g (-1) {}
00780   syntactic expression (const syntactic& z) const {
00781     return lcm (flatten (f, z), flatten (g, z)); }
00782   virtual void Increase_order (nat l) {
00783     Series_rep::Increase_order (l);
00784     increase_order (f, l);
00785     increase_order (g, l); }
00786   virtual C next () {
00787     if (v_f >= 0 && v_g >= 0) return this->zero ();
00788     if (v_f < 0 && f[this->n] != 0) v_f= this->n;
00789     if (v_g < 0 && g[this->n] != 0) v_g= this->n;
00790     if (v_f >= 0 && v_g >= 0) return this->one ();
00791     return this->zero ();
00792   }
00793 };
00794 
00795 TMPL inline Series
00796 lcm (const Series& f, const Series& g) {
00797   return (Series_rep*) new lcm_series_rep<C,V> (f, g);
00798 }
00799 
00800 /******************************************************************************
00801 * Other linear time operations
00802 ******************************************************************************/
00803 
00804 TMPL
00805 class lshiftz_series_rep: public Series_rep {
00806   Series f;
00807   int shift;
00808 public:
00809   lshiftz_series_rep (const Series& f2, int shift2):
00810     Series_rep (CF(f2)), f (f2), shift (shift2) {}
00811   syntactic expression (const syntactic& z) const {
00812     return lshiftz (flatten (f, z), flatten (shift)); }
00813   void Increase_order (nat l) {
00814     Series_rep::Increase_order (l);
00815     increase_order (f, max (0, ((int) l) - shift)); }
00816   C next () {
00817     return shift > ((int) this->n)? this->zero (): f[this->n - shift]; }
00818 };
00819 
00820 TMPL inline Series
00821 lshiftz (const Series& f, const int& shift) {
00822   if (is_exact_zero (f)) return Series (CF(f));
00823   return (Series_rep*) new lshiftz_series_rep<C,V> (f, shift);
00824 }
00825 
00826 TMPL inline Series
00827 rshiftz (const Series& f, const int& shift) {
00828   if (is_exact_zero (f)) return Series (CF(f));
00829   return (Series_rep*) new lshiftz_series_rep<C,V> (f, -shift);
00830 }
00831 
00832 TMPL
00833 class restrict_series_rep: public Series_rep {
00834   Series f;
00835   nat start, end;
00836 public:
00837   restrict_series_rep (const Series& f2, nat start2, nat end2):
00838     Series_rep (CF(f2)), f (f2), start (start2), end (end2) {}
00839   syntactic expression (const syntactic& z) const {
00840     return apply ("restrict", flatten (f, z),
00841                   flatten (start), flatten (end)); }
00842   void Increase_order (nat l) {
00843     Series_rep::Increase_order (l);
00844     increase_order (f, min (l, end)); }
00845   C next () {
00846     return ((this->n>=start && this->n<end)? f[this->n]: this->zero ()); }
00847 };
00848 
00849 TMPL inline Series
00850 restrict (const Series& f, nat start, nat end) {
00851   if (is_exact_zero (f)) return Series (CF(f));
00852   return (Series_rep*) new restrict_series_rep<C,V> (f, start, end);
00853 }
00854 
00855 TMPL
00856 class piecewise_series_rep: public Series_rep {
00857   Series f, g;
00858   nat pos;
00859 public:
00860   piecewise_series_rep (const Series& f2, const Series &g2, nat pos2):
00861     Series_rep (CF(f2)), f (f2), g (g2), pos (pos2) {}
00862   syntactic expression (const syntactic& z) const {
00863     return apply ("piecewise", flatten (f, z), flatten (g, z),
00864                   flatten (pos)); }
00865   void Increase_order (nat l) {
00866     Series_rep::Increase_order (l);
00867     increase_order (f, min (l, pos));
00868     increase_order (g, l <= pos ? 0 : l); }
00869   C next () { return this->n < pos ? f[this->n] : g[this->n]; }
00870 };
00871 
00872 TMPL inline Series
00873 piecewise (const Series& f, const Series& g, nat pos) {
00874   return (Series_rep*) new piecewise_series_rep<C,V> (f, g, pos);
00875 }
00876 
00877 TMPL
00878 class derive_series_rep: public Series_rep {
00879   Series f;
00880 public:
00881   derive_series_rep (const Series& f2):
00882     Series_rep (CF(f2)), f (f2) {}
00883   syntactic expression (const syntactic& z) const {
00884     return derive (flatten (f, z)); }
00885   void Increase_order (nat l) {
00886     Series_rep::Increase_order (l);
00887     increase_order (f, l+1); }
00888   C next () {
00889     return promote ((int) (this->n + 1), CF(f)) * f[this->n + 1]; }
00890 };
00891 
00892 TMPL inline Series
00893 derive (const Series& f) {
00894   if (is_exact_zero (f)) return Series (CF(f));
00895   return (Series_rep*) new derive_series_rep<C,V> (f);
00896 }
00897 
00898 template<typename C, typename V, typename T> inline Series
00899 derive_coeffs (const Series& f, const T& v) {
00900   return binary_scalar_series<derive_op> (f, v);
00901 }
00902 
00903 TMPL
00904 class xderive_series_rep: public Series_rep {
00905   Series f;
00906 public:
00907   xderive_series_rep (const Series& f2):
00908     Series_rep (CF(f2)), f (f2) {}
00909   syntactic expression (const syntactic& z) const {
00910     return xderive (flatten (f, z)); }
00911   void Increase_order (nat l) {
00912     Series_rep::Increase_order (l);
00913     increase_order (f, l); }
00914   C next () { return promote ((int) this->n, CF(f)) * f[this->n]; }
00915 };
00916 
00917 TMPL inline Series
00918 xderive (const Series& f) {
00919   if (is_exact_zero (f)) return Series (CF(f));
00920   return (Series_rep*) new xderive_series_rep<C,V> (f);
00921 }
00922 
00923 TMPL
00924 class integrate_series_rep: public Series_rep {
00925   Series f;
00926   C c;
00927 public:
00928   integrate_series_rep (const Series& f2):
00929     Series_rep (CF(f2)), f (f2), c (promote (0, CF(f2))) {}
00930   integrate_series_rep (const Series& f2, const C& c2):
00931     Series_rep (CF(f2)), f (f2), c (c2) {}
00932   syntactic expression (const syntactic& z) const {
00933     if (c == promote (0, c)) return integrate (flatten (f, z));
00934     else return integrate_init (flatten (f, z), flatten (c)); }
00935   void Increase_order (nat l) {
00936     Series_rep::Increase_order (l);
00937     increase_order (f, max (0, ((int) l) - 1)); }
00938   C next () {
00939     if (this->n == 0) return c;
00940     return invert (promote ((int) this->n, c)) * f[this->n - 1]; }
00941 };
00942 
00943 TMPL inline Series
00944 integrate (const Series& f) {
00945   if (is_exact_zero (f)) return Series (CF(f));
00946   return (Series_rep*) new integrate_series_rep<C,V> (f);
00947 }
00948 
00949 TMPL inline Series
00950 integrate_init (const Series& f, const C& c) {
00951   return (Series_rep*) new integrate_series_rep<C,V> (f, c);
00952 }
00953 
00954 template<typename C, typename V, typename T> inline Series
00955 integrate_coeffs (const Series& f, const T& v) {
00956   return binary_scalar_series<integrate_op> (f, v);
00957 }
00958 
00959 TMPL
00960 class shift_series_rep: public Series_rep {
00961   // heuristic shifting
00962   Series f;
00963   C c;
00964   nat order;
00965 public:
00966   shift_series_rep (const Series& f2, const C& c2, nat order2):
00967     Series_rep (CF(f2)), f (f2), c (c2), order (order2) {}
00968   syntactic expression (const syntactic& z) const {
00969     return apply ("shift", flatten (f, z), flatten (c)); }
00970   void Increase_order (nat l) {
00971     Series_rep::Increase_order (l);
00972     increase_order (f, l + order); }
00973   C next () {
00974     C s= this->zero (), p= this->one ();
00975     for (nat i=0; i<order; i++) {
00976       s += p * f[this->n + i];
00977       p *= c * (promote ((int) (this->n + i + 1), c) /
00978                 promote ((int) (i + 1), c));
00979     }
00980     return s; }
00981 };
00982 
00983 TMPL inline Series
00984 shift (const Series& f, const C& q, nat order) {
00985   if (is_exact_zero (f)) return Series (CF(f));
00986   return (Series_rep*) new shift_series_rep<C,V> (f, q, order);
00987 }
00988 
00989 TMPL
00990 class q_difference_series_rep: public Series_rep {
00991   Series f;
00992   C q;
00993   C p;
00994 public:
00995   q_difference_series_rep (const Series& f2, const C& q2):
00996     Series_rep (CF(f2)), f (f2), q (q2), p (promote (1, q2)) {}
00997   syntactic expression (const syntactic& z) const {
00998     return apply ("q_difference", flatten (f, z), flatten (q)); }
00999   void Increase_order (nat l) {
01000     Series_rep::Increase_order (l);
01001     increase_order (f, l); }
01002   C next () {
01003     C c= p * f[this->n];
01004     p *= q;
01005     return c; }
01006 };
01007 
01008 TMPL inline Series
01009 q_difference (const Series& f, const C& q) {
01010   if (is_exact_zero (f)) return Series (CF(f));
01011   return (Series_rep*) new q_difference_series_rep<C,V> (f, q);
01012 }
01013 
01014 TMPL
01015 class dilate_series_rep: public Series_rep {
01016   Series f;
01017   nat p;
01018 public:
01019   dilate_series_rep (const Series& f2, int p2):
01020     Series_rep (CF(f)), f (f2), p (p2) {}
01021   syntactic expression (const syntactic& z) const {
01022     return apply ("dilate", flatten (f, z), flatten (p)); }
01023   void Increase_order (nat l) {
01024     Series_rep::Increase_order (l);
01025     increase_order (f, l/p); }
01026   C next () {
01027     return this->n % p == 0? f[this->n / p]: this->zero (); }
01028 };
01029 
01030 TMPL inline Series
01031 dilate (const Series& f, nat p) {
01032   if (is_exact_zero (f)) return Series (CF(f));
01033   return (Series_rep*) new dilate_series_rep<C,V> (f, p);
01034 }
01035 
01036 TMPL
01037 class deflate_series_rep: public Series_rep {
01038   Series f;
01039   nat p;
01040 public:
01041   deflate_series_rep (const Series& f2, int p2):
01042     Series_rep (CF(f)), f (f2), p (p2) {}
01043   syntactic expression (const syntactic& z) const {
01044     return apply ("deflate", flatten (f, z), flatten (p)); }
01045   void Increase_order (nat l) {
01046     Series_rep::Increase_order (l);
01047     increase_order (f, l*p); }
01048   C next () { return f[(this->n)*p]; }
01049 };
01050 
01051 TMPL inline Series
01052 deflate (const Series& f, nat p) {
01053   if (is_exact_zero (f)) return Series (CF(f));
01054   return (Series_rep*) new deflate_series_rep<C,V> (f, p);
01055 }
01056 
01057 /******************************************************************************
01058 * Multiplication and division
01059 ******************************************************************************/
01060 
01061 TMPL inline Series
01062 operator * (const Series& f, const Series& g) {
01063   typedef implementation<series_multiply,V> Ser;
01064   return Ser::ser_mul (f, g);
01065 }
01066 
01067 TMPL inline Series
01068 truncate_mul (const Series& f, const Series& g, nat nf, nat ng) {
01069   // Product of the only nf first terms of f by the ng first ones of g
01070   typedef implementation<series_multiply,V> Ser;
01071   return Ser::ser_truncate_mul (f, g, nf, ng);
01072 }
01073 
01074 TMPL inline Series
01075 operator / (const Series& f, const C& c) {
01076   typedef implementation<series_divide,V> Ser;
01077   return Ser::ser_rdiv_sc (f, c);
01078 }
01079 
01080 TMPL inline Series
01081 operator / (const Series& f, const Series& g) {
01082   typedef implementation<series_divide,V> Ser;
01083   return Ser::ser_div (f, g);
01084 }
01085 
01086 TMPL inline Series
01087 operator / (const C& c, const Series& f) {
01088   typedef implementation<series_divide,V> Ser;
01089   if (is_exact_zero (c)) return Series (get_format (c));
01090   return Ser::ser_div (Series (c), f);
01091 }
01092 
01093 TMPL inline Series
01094 invert (const Series& f) {
01095   return promote (1, CF(f)) / f;
01096 }
01097 
01098 TMPL inline Series
01099 quo (const Series& f, const C& c) {
01100   typedef implementation<series_divide,V> Ser;
01101   return Ser::ser_rquo_sc (f, c);
01102 }
01103 
01104 TMPL inline Series
01105 quo (const Series& f, const Series& g) {
01106   typedef implementation<series_divide,V> Ser;
01107   return Ser::ser_quo (f, g);
01108 }
01109 
01110 TMPL inline Series
01111 rem (const Series& f, const C& c) {
01112   typedef implementation<series_divide,V> Ser;
01113   return Ser::ser_rrem_sc (f, c);
01114 }
01115 
01116 TMPL inline Series
01117 rem (const Series& f, const Series& g) {
01118   if (is_exact_zero (f)) return Series (CF(f));
01119   return f - g * quo (f, g);
01120 }
01121 
01122 TMPL inline bool
01123 divides (const Series& f, const Series& g) {
01124   return val (f) <= val (g);
01125 }
01126 
01127 ARITH_SCALAR_INT_SUGAR(TMPL,Series);
01128 
01129 /******************************************************************************
01130 * Separable nth root
01131 ******************************************************************************/
01132 
01133 TMPL inline Series
01134 separable_root (const Series& f, nat n) {
01135   typedef implementation<series_separable_root,V> Ser;
01136   return Ser::sep_root (f, n);
01137 }
01138 
01139 TMPL inline Series
01140 separable_root_init (const Series& f, nat n, const C& init) {
01141   typedef implementation<series_separable_root,V> Ser;
01142   return Ser::sep_root (f, n, init);
01143 }
01144 
01145 /******************************************************************************
01146 * pth root where p is the characteristic of the residual ring
01147 ******************************************************************************/
01148 
01149 TMPL inline Series
01150 pth_root (const Series& f) {
01151   typedef implementation<series_pth_root,V> Ser;
01152   return Ser::unsep_root (f);
01153 }
01154 
01155 /******************************************************************************
01156 * Composition and reversion
01157 ******************************************************************************/
01158 
01159 TMPL inline Series
01160 compose (const Series& f, const Series& g) {
01161   typedef implementation<series_compose,V> Ser;
01162   return Ser::ser_compose (f, g);
01163 }
01164 
01165 TMPL inline Series
01166 reverse (const Series& f) {
01167   typedef implementation<series_compose,V> Ser;
01168   return Ser::ser_reverse (f);
01169 }
01170 
01171 /******************************************************************************
01172 * Reliable and precision related routines
01173 ******************************************************************************/
01174 
01175 TMPL
01176 class change_precision_series_rep: public Series_rep {
01177   Series f;
01178   nat p;
01179 public:
01180   inline change_precision_series_rep (const Series& f2, nat p2):
01181     Series_rep (CF(f2)), f (f2), p (p2) {}
01182   syntactic expression (const syntactic& z) const {
01183     return syn ("change_precision", flatten (f, z), flatten (p)); }
01184   void Increase_order (nat l) {
01185     Series_rep::Increase_order (l);
01186     increase_order (f, l); }
01187   C next () {
01188     return change_precision (f[this->n], p); }
01189 };
01190 
01191 TMPL inline Series
01192 change_precision (const Series& f, nat p) {
01193   return (Series_rep*) new change_precision_series_rep<C,V> (f, p);
01194 }
01195 
01196 TMPL inline nat
01197 precision (const Series& f) {
01198   return precision (f[0]);
01199 }
01200 
01201 TMPL inline Series sharpen (const Series& f) {
01202   return unary_map<sharpen_op> (f); }
01203 TMPLK inline Series blur (const Series& f, const K& x) {
01204   return binary_map_scalar<blur_op> (f, x); }
01205 
01206 #undef TMPL
01207 #undef TMPLK
01208 #undef Format
01209 #undef Series
01210 #undef Series_rep
01211 #undef Recursive_series_rep
01212 #undef Polynomial
01213 } // namespace mmx
01214 #endif // __MMX_SERIES_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines