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