algebramix_doc 0.3
|
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