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