algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/series_carry_naive.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : series_carry_naive.hpp
00004 * DESCRIPTION: lazy p-adic numbers
00005 * COPYRIGHT  : (C) 2011  Jeremy Berthomieu, Gregoire Lecerf and Romain Lebreton
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_CARRY_NAIVE_HPP
00014 #define __MMX_SERIES_CARRY_NAIVE_HPP
00015 #include <algebramix/p_expansion.hpp>
00016 #include <algebramix/series_naive.hpp>
00017 #include <algebramix/root_modular.hpp>
00018 #include <algebramix/series_vector.hpp>
00019 #include <basix/literal.hpp>
00020 #include <basix/compound.hpp>
00021 #include <basix/timer.hpp>
00022 
00023 namespace mmx {
00024 #define Series     series<M,V>
00025 #define Series_rep series_rep<M,V>
00026 #define Recursive_series_rep recursive_series_rep<M,V>
00027 #define C       typename M::C
00028 #define Modulus typename M::modulus
00029 #define TMPL    template<typename M, typename V>
00030 #define TMPLW   template<typename M, typename V, typename W>
00031 #define Vector        vector<M,W>
00032 #define Series_vector series<Vector, V>  
00033 
00034 /******************************************************************************
00035 * Variant helpers
00036 ******************************************************************************/
00037 
00038 struct series_carry_naive {};
00039 
00040 template<typename V,typename W>
00041 struct implementation<V,W,series_carry_naive>:
00042   public implementation<V,W,series_naive> {};
00043 
00044 template<typename M>
00045 struct series_polynomial_helper<M,series_carry_naive> {
00046   typedef typename P_expansion_variant(M) PV;
00047 };
00048 
00049 template<typename M>
00050 struct series_carry_variant_helper {
00051   typedef series_carry_naive SV;
00052 };
00053 
00054 #define Series_carry_variant(C) series_carry_variant_helper<C>::SV
00055 
00056 /******************************************************************************
00057 * Output
00058 ******************************************************************************/
00059 
00060 template<typename U>
00061 struct implementation<series_defaults,U,series_carry_naive> {
00062   typedef implementation<series_defaults,U,series_naive> Ser;
00063 
00064   template<typename S>
00065   class global_variables :
00066     public Ser::template global_variables<S> {
00067 
00068     static inline generic& dyn_name () {
00069       static generic name = "p";
00070       return name; }
00071     
00072   public:
00073     static inline void set_variable_name (const generic& x) {
00074       dyn_name () = x; }
00075     static inline generic get_variable_name () {
00076       return dyn_name (); }
00077   };
00078 };
00079 
00080 /******************************************************************************
00081 * Abstract scalar operations on series
00082 ******************************************************************************/
00083 
00084 template<typename U>
00085 struct implementation<series_scalar_abstractions,U,series_carry_naive>:
00086   public implementation<series_defaults,U>
00087 {
00088 
00089 template<typename Op,typename M,typename V,typename X>
00090 class binary_scalar_series_rep: public Series_rep {
00091 protected:
00092   Series f;
00093   M x;
00094   C c;
00095 public:
00096   inline binary_scalar_series_rep (const Series& f2, const X& x2):
00097     Series_rep (CF(f2)), f(f2), x (as<M> (x2)), c (0) {}
00098   syntactic expression (const syntactic& z) const {
00099     return Op::op (flatten (f, z), flatten (x)); }
00100   virtual void Increase_order (nat l) {
00101     Series_rep::Increase_order (l);
00102     increase_order (f, l); }
00103   virtual M next () {
00104     return Op::op_mod (f[this->n].rep, x.rep, M::get_modulus (), c); }
00105 };
00106 
00107 }; // implementation<series_scalar_abstractions,V,series_carry_naive>
00108 
00109 /******************************************************************************
00110 * Abstract operations on p_adic
00111 ******************************************************************************/
00112 
00113 template<typename U>
00114 struct implementation<series_abstractions,U,series_carry_naive>:
00115   public implementation<series_recursive_abstractions,U>
00116 {
00117 
00118 template<typename Op,typename M,typename V>
00119 class unary_series_rep: public Series_rep {
00120 protected:
00121   const Series f;
00122   C carry;
00123 public:
00124   inline unary_series_rep (const Series& f2):
00125     Series_rep (CF(f2)), f(f2), carry (C(0)) {}
00126   syntactic expression (const syntactic& z) const {
00127     return Op::op (flatten (f, z)); }
00128   virtual void Increase_order (nat l) {
00129     Series_rep::Increase_order (l);
00130     increase_order (f, l); }
00131   virtual M next () {
00132     return Op::op_mod (f[this->n].rep, M::get_modulus (), carry); }
00133 };
00134 
00135 template<typename Op,typename M,typename V>
00136 class binary_series_rep: public Series_rep {
00137 protected:
00138   Series f, g;
00139   C carry;
00140 public:
00141   inline binary_series_rep (const Series& f2, const Series& g2):
00142     Series_rep (CF(f2)), f(f2), g (g2), carry (0) {}
00143   syntactic expression (const syntactic& z) const {
00144     return Op::op (flatten (f, z), flatten (g, z)); }
00145   virtual void Increase_order (nat l) {
00146     Series_rep::Increase_order (l);
00147     increase_order (f, l);
00148     increase_order (g, l); }
00149   virtual M next () {
00150     return Op::op_mod (f[this->n].rep, g[this->n].rep,
00151                        M::get_modulus (), carry); }
00152 };
00153 
00154 }; // implementation<series_abstractions,U,series_carry_naive>:
00155 
00156 /******************************************************************************
00157 * Multiplication
00158 ******************************************************************************/
00159 
00160 template<typename U>
00161 struct implementation<series_multiply,U,series_carry_naive>:
00162   public implementation<series_abstractions,U>
00163 {
00164   typedef implementation<series_abstractions,U> Ser;
00165 
00166 TMPL
00167 class mul_series_rep: public Ser::template binary_series_rep<mul_op,M,V> {
00168   typedef Lift_type (M) L;
00169   L carry;
00170 public:
00171   inline mul_series_rep (const Series& f, const Series& g):
00172     Ser::template binary_series_rep<mul_op,M,V> (f, g), carry (0) {}
00173   M next () {
00174     Modulus p= M::get_modulus ();
00175     L acc= carry;
00176     for (nat i= 0; i <= this->n; i++)
00177       acc += L ((this->f[i]).rep) * L((this->g[this->n-i]).rep);
00178     return rem (acc, * p, carry); }
00179 };
00180 
00181 TMPL
00182 class truncate_mul_series_rep:
00183     public Ser::template binary_series_rep<mul_op,M,V> {
00184   nat nf, ng;
00185   typedef Lift_type (M) L;
00186   L carry;
00187 public:
00188   inline truncate_mul_series_rep (const Series& f, const Series& g,
00189                                   nat nf2, nat ng2):
00190     Ser::template binary_series_rep<mul_op,M,V> (f, g), nf (nf2), ng (ng2),
00191     carry (0) {}
00192   M next () {
00193     nat i, n= this->n;
00194     Modulus p= M::get_modulus ();
00195     L acc= carry;
00196     for (i= n >= ng ? n - ng + 1 : 0; i < min (1 + n, nf); i++)
00197       acc += L ((this->f[i]).rep) * L((this->g[n-i]).rep);
00198     return rem (acc, * p, carry); }
00199 };
00200 
00201 TMPL static inline Series
00202 ser_mul (const Series& f, const Series& g) {
00203   typedef mul_series_rep<M,V> Mul_rep;
00204   if (is_exact_zero (f) || is_exact_zero (g))
00205     return Series (CF(f));
00206   return (Series_rep*) new Mul_rep (f, g); }
00207 
00208 TMPL static inline Series
00209 ser_truncate_mul (const Series& f, const Series& g, nat nf, nat ng) {
00210   typedef truncate_mul_series_rep<M,V> Mul_rep;
00211   if (is_exact_zero (f) || is_exact_zero (g) || nf == 0 || ng == 0)
00212     return Series (CF(f));
00213   return (Series_rep*) new Mul_rep (f, g, nf, ng); }
00214 
00215 }; // implementation<series_multiply,U,series_carry_naive>:
00216 
00217 /******************************************************************************
00218 * Multiplication with lift & reduction to series
00219 ******************************************************************************/
00220 
00221 template<typename V>
00222 struct series_carry_lift {};
00223 
00224 template<typename U,typename V,typename W>
00225 struct implementation<V,U,series_carry_lift<W> >:
00226   public implementation<V,U,W> {};
00227 
00228 template<typename U,typename W>
00229 struct implementation<series_multiply,U,series_carry_lift<W> >:
00230   public implementation<series_abstractions,U>
00231 {
00232   typedef implementation<series_abstractions,U> Ser;
00233 
00234 template<typename M,typename V>
00235 class mul_series_rep: public Ser::template binary_series_rep<mul_op,M,V> {
00236   typedef C L;
00237   series<L> H;
00238   L c;
00239 public:
00240   inline mul_series_rep (const Series& f, const Series& g):
00241     Ser::template binary_series_rep<mul_op,M,V> (f, g), c(0) {
00242     H= as<series<L> > (f) * as<series<L> > (g); }
00243   M next () {
00244     c += H[this->n];
00245     return M (as<C> (rem (c, * M::get_modulus (), c)), true); }
00246 };
00247 
00248 template<typename M,typename V>
00249 class truncate_mul_series_rep:
00250     public Ser::template binary_series_rep<mul_op,M,V> {
00251   typedef C L;
00252   series<L> H;
00253   L c;
00254 public:
00255   inline truncate_mul_series_rep (const Series& f, const Series& g,
00256                                    nat nf, nat ng):
00257     Ser::template binary_series_rep<mul_op,M,V> (f, g), c(0) {
00258     H= truncate_mul (as<series<L> > (f), as<series<L> > (g), nf, ng); }
00259   M next () {
00260     c += H[this->n];
00261     return M (as<C> (rem (c, * M::get_modulus (), c)), true); }
00262 };
00263 
00264 template<typename M,typename V> static inline Series
00265 ser_mul (const Series& f, const Series& g) {
00266   typedef mul_series_rep<M,V> Mul_rep;
00267   if (is_exact_zero (f) || is_exact_zero (g))
00268     return Series (CF(f));
00269   return (Series_rep*) new Mul_rep (f, g); }
00270 
00271 TMPL static inline Series
00272 ser_truncate_mul (const Series& f, const Series& g, nat nf, nat ng) {
00273   typedef truncate_mul_series_rep<M,V> Mul_rep;
00274   if (is_exact_zero (f) || is_exact_zero (g) || nf == 0 || ng == 0)
00275     return Series (CF(f));
00276   return (Series_rep*) new Mul_rep (f, g, nf, ng); }
00277 
00278 }; // implementation<series_multiply,V,series_carry_lift<U> >
00279 
00280 /******************************************************************************
00281 * Division
00282 ******************************************************************************/
00283 
00284 template<typename U>
00285 struct implementation<series_divide,U,series_carry_naive>:
00286   public implementation<series_recursive_abstractions,U>
00287 {
00288 
00289 template<typename M,typename V,typename X>
00290 class carry_mul_sc_series_rep: public Series_rep {
00291 protected:
00292   Series f;
00293   M x;
00294   C c;
00295 public:
00296   inline carry_mul_sc_series_rep (const Series& f2, const X& x2):
00297     Series_rep (CF(f2)), f(f2), x (as<M> (x2)), c (0) {}
00298   syntactic expression (const syntactic& z) const {
00299     return apply (syntactic ("carry_mul"), flatten (f, z), flatten (x)); }
00300   virtual void Increase_order (nat l) {
00301     Series_rep::Increase_order (l);
00302     increase_order (f, l); }
00303   virtual M next () {
00304     if (this->n == 0) return M (0);
00305     return (quo (f[this->n-1].rep * x.rep, * M::get_modulus ())); }
00306 };
00307 
00308 template<typename M,typename V> static inline Series
00309 carry_mul_series (const Series& f, const M& c) {
00310   return (Series_rep*) new carry_mul_sc_series_rep<M,V,M> (f, c);
00311 }
00312 
00313 template<typename M,typename V,typename X>
00314 class rdiv_sc_series_rep: public Recursive_series_rep {
00315 protected:
00316   Series f;
00317   M c;
00318 public:
00319   rdiv_sc_series_rep (const Series& f2, const X& c2):
00320     Recursive_series_rep (CF(f2)), f(f2), c(as<M> (c2)) {}
00321   syntactic expression (const syntactic& z) const {
00322     return flatten (f, z) / flatten (c); }
00323   virtual void Increase_order (nat l) {
00324     Recursive_series_rep::Increase_order (l);
00325     increase_order (f, l); }
00326   Series initialize () {
00327     typedef typename Series_variant(C) SV;
00328     ASSERT (c != 0, "division by zero");
00329     M u= invert (c);
00330     this->initial (0)= u * f[0];
00331     Series tmp= f - carry_mul_series (this -> me (), c);
00332     return as<Series> (u * as<series<M,SV> > (tmp));
00333   }
00334 };
00335 
00336 TMPL static inline Series
00337 ser_rdiv_sc (const Series& f, const M& c) {
00338   typedef rdiv_sc_series_rep<M,V,M> Div_sc_rep;
00339   if (is_exact_zero (f)) return Series (CF(f));
00340   return recursive (Series ((Series_rep*) new Div_sc_rep (f, c))); }
00341 
00342 template<typename M,typename V>
00343 class div_series_rep: public Recursive_series_rep {
00344 protected:
00345   Series f, g;
00346 
00347 public:
00348   div_series_rep (const Series& f2, const Series& g2):
00349     Recursive_series_rep (CF(f2)), f(f2), g(g2) {}
00350   syntactic expression (const syntactic& z) const {
00351     return flatten (f, z) / flatten (g, z); }
00352   virtual void Increase_order (nat l) {
00353     Recursive_series_rep::Increase_order (l);
00354     increase_order (f, l);
00355     increase_order (g, l); }
00356   Series initialize () {
00357     typedef typename Series_variant(C) SV;
00358     ASSERT (g[0] != 0, "division by zero");
00359     M u= invert (g[0]);
00360     this->initial (0)= u * f[0];
00361     Series tmp= f - lshiftz (this -> me () * rshiftz (g))
00362       - carry_mul_series (this -> me (), g[0]);
00363     return as<Series> (u * as<series<M,SV> > (tmp)); }
00364 };
00365 
00366 TMPL static inline Series
00367 ser_div (const Series& f, const Series& g) {
00368   typedef div_series_rep<M,V> Div_rep;
00369   if (is_exact_zero (f)) return Series (CF(f));
00370   return recursive (Series ((Series_rep*) new Div_rep (f, g))); }
00371 
00372 TMPL static inline Series
00373 ser_quo (const Series& f, const M& c) {
00374   return ser_div_sc (f, c); }
00375   
00376 TMPL static inline Series
00377 ser_quo (const Series& f, const Series& g) {
00378   return ser_div (f, g); }
00379 
00380 TMPL static inline Series
00381 ser_rrem_sc (const Series& f, const M& c) {
00382   return Series (CF(f)); }
00383 
00384 }; // implementation<series_divide,U,series_carry_naive>:
00385 
00386 /******************************************************************************
00387 * separable_root
00388 ******************************************************************************/
00389 
00390 struct ser_carry_separable_root_op {
00391   // regular case when r is invertible in the residual field
00392 
00393   template<typename S, typename I> static inline S
00394   binpow_no_tangent (const S& me, const I& r) {
00395     typedef Scalar_type(S) M;
00396     // me^r - r * (me - me[0]) * me[0]^(r-1) - me[0]^r
00397     //M me0= me[0]; S me1= lshiftz (me,1);
00398     if (r <= 1) return S (0);
00399     if (r == 2) return lshiftz (square (rshiftz (me, 1)), 2);
00400 
00401     I h= r >> 1;
00402     S s_h (coefficients (as<default_p_expansion(M)> (integer (h))));
00403     M x= me[0];
00404     S x_h_1= binpow (S(x), h-1);
00405     S y= me - me[0];
00406     S z= rshiftz (binpow_no_tangent (me, h), 1);
00407     S t0= s_h * y;
00408     S t1= square (rshiftz (t0 * x_h_1, 1));
00409     S t2= x_h_1 * z * (t0 + x);
00410     S w= lshiftz (square (z) + t1, 2) + lshiftz (t2 + t2, 1);
00411     if ((r & 1) == 1) {
00412       I h2= h << 1;
00413       S s_h2 (coefficients (as<default_p_expansion(M)> (integer (h2))));
00414       w= lshiftz (me * rshiftz (w, 1), 1)
00415         + lshiftz (s_h2 * square (rshiftz (y * x_h_1, 1)) * x, 2);
00416     }
00417     return w; }
00418 
00419   static generic name () { return "separable_root"; }
00420 
00421   template<typename S> static inline S
00422   op (const S& x, nat r) { return separable_root (x, r); }
00423 
00424   static inline syntactic
00425   op (const syntactic& x, const syntactic& r) {
00426     return apply ("separable_root", x, r); }
00427 
00428   template<typename R, typename S> static inline void
00429   set_op (R& x, const S& y, nat r) { x= separable_root (y, r); }
00430 
00431   template<typename S, typename I> static inline S
00432   op_init (const S& x, nat r, const I& i) {
00433     return separable_root_init (x, r, i); }
00434 
00435   static inline nat nr_init () { return 1; }
00436 
00437   template<typename S> static inline S
00438   def (const S& me, const S& a, nat r) {
00439     typedef Scalar_type(S) M;
00440     if (r == 2) {
00441       return ((a - S (me[0]) * me[0] - binpow_no_tangent (me, r))
00442               / M (r)) / me[0];
00443     }
00444     S ser_r (coefficients (as<default_p_expansion(M)> (integer (r))));
00445     S me_0_r_1= binpow (S (me[0]), r - 1);
00446     S me_0_r= me[0] * me_0_r_1;
00447     return (a - me_0_r - binpow_no_tangent (me, r))
00448       / (ser_r * me_0_r_1); }
00449 
00450 }; // struct ser_carry_separable_root_op
00451 
00452 template<typename U>
00453 struct implementation<series_separable_root,U,series_carry_naive> {
00454 
00455 TMPL static inline Series
00456 sep_root (const Series& a, nat r) {
00457   ASSERT (M(r) != 0, "wrong argument");
00458   if (is_exact_zero (a)) return Series (CF(a));
00459   return binary_scalar_recursive_series
00460     <ser_carry_separable_root_op> (a, r); }
00461 
00462 TMPL static inline Series
00463 sep_root (const Series& a, nat r, const M& init) {
00464   ASSERT (M(r) != 0, "wrong argument");
00465   if (is_exact_zero (a)) return Series (CF(a));
00466   return binary_scalar_recursive_series
00467     <ser_carry_separable_root_op> (a, r, init); }
00468 
00469 }; // implementation<series_separable_root,V,series_carry_naive>
00470 
00471 
00472 /******************************************************************************
00473 * simple_root
00474 ******************************************************************************/
00475 TMPL inline vector<Series>
00476 rec_add (const vector<Series>& p, const vector<Series>& q) {
00477   return p + q;
00478 }
00479 
00480 TMPL inline vector<Series>
00481 rec_minus (const vector<Series>& p) {
00482   return -p;
00483 }
00484 
00485 TMPL inline vector<Series>
00486 rec_minus (const vector<Series>& p, const vector<Series>& q) {
00487   return p - q;
00488 }
00489 
00490 TMPL inline vector<Series>
00491 rec_prod (const vector<Series>& p, const vector<Series>& q,
00492           const Series& y) {
00493   ASSERT (N(p) == N(q) && N(p) == 3, "Wrong size of arguments");
00494   const Series& ep=p[0], ap=p[1], eq=q[0], aq=q[1];
00495   const Series& bp=p[2], bq=q[2];
00496   Series ry = rshiftz (y); 
00497   Series tp = ap + bp * lshiftz (ry);
00498   Series tq = aq + bq * lshiftz (ry);
00499   //TODO stocker récursivement rshiftz (er, 2) plutôt 
00500   Series er = (ep * eq + lshiftz (tp * rshiftz (eq, 2), 2) + 
00501                lshiftz (rshiftz (ep, 2) * tq, 2) + 
00502                bp * bq * lshiftz (square (ry), 2));
00503   return vec<Series> (er, ap * aq, ap * bq + bp * aq);   
00504 }
00505 
00506 TMPL inline vector<Series>
00507 rec_prod (const vector<Series>& p, const vector<Series>& q,
00508           const vector<Series>& y) {
00509   nat l= N(p);
00510   ASSERT (l == N(q) && (l-2) == N(y), "Wrong size of arguments");
00511   const Series& ep=p[0], ap=p[1], eq=q[0], aq=q[1];
00512   vector<Series> bp = range (p, 2, l);
00513   vector<Series> bq = range (q, 2, l);
00514   //Beware of as_vector (rshiftz (y)) which call
00515   // as_vector (y, N(f[1]))
00516   vector<Series> ry = as_vector (rshiftz (as_series (y)), N(y));
00517   vector<Series> lry = as_vector (lshiftz_series_vector
00518                                   (rshiftz (as_series (y)), l-2));
00519   Series tp = ap + dot (bp, lry);
00520   Series tq = aq + dot (bq, lry);
00521   Series er = (ep * eq + lshiftz (tp * rshiftz (eq, 2), 2) + 
00522                lshiftz (rshiftz (ep, 2) * tq, 2) +
00523                lshiftz (dot (ry, bp) * dot (bq, ry), 2));
00524   return (vec<Series> (er, ap * aq) << (ap * bq + bp * aq));
00525 }
00526 
00527 TMPL inline vector<Series>
00528 rec_square (const vector<Series>& p, const Series& y) {
00529   ASSERT (N(p) == 3, "Wrong size of arguments");
00530   Series ser_2 (coefficients (as<default_p_expansion(M)> (2)));
00531   const Series& ep=p[0], ap=p[1], bp=p[2];
00532   Series ry = rshiftz (y); 
00533   Series tp = ap + bp * lshiftz (ry);
00534   Series er = (square (ep) + ser_2 * lshiftz (tp * rshiftz (ep, 2), 2) +
00535                lshiftz (square (bp * ry), 2));
00536   return vec<Series> (er, square (ap), ser_2 * ap * bp);   
00537 }
00538 
00539 
00540 TMPL inline vector<Series>
00541 rec_square (const vector<Series>& p, const vector<Series>& y) {
00542   nat l= N(p);
00543   ASSERT ((l-2) == N(y), "Wrong size of arguments");
00544   Series ser_2 (coefficients (as<default_p_expansion(M)> (2)));
00545   const Series& ep=p[0], ap=p[1];
00546   vector<Series> bp = range (p, 2, l);
00547   vector<Series> ry = as_vector (rshiftz (as_series (y)), N(y));
00548   vector<Series> lry = as_vector (lshiftz_series_vector
00549                                   (rshiftz (as_series (y)), l-2));
00550   Series tp = ap + dot (bp, lry);
00551   Series er = (square (ep) + ser_2 * lshiftz (tp * rshiftz (ep, 2), 2) +
00552                lshiftz (square (dot (bp, ry)), 2));
00553   return (vec<Series> (er, square (ap)) << (ser_2 * ap * bp));
00554 }
00555 
00556 TMPL inline vector<Series>
00557 rec_lin (const Series& a, const Series& b) {
00558   return vec<Series> (Series (CF(a)), a, b);
00559 }
00560 
00561 TMPL inline vector<Series>
00562 rec_lin (const Series& a, const vector<Series>& b) {
00563   return vec<Series> (Series (CF(a)), a) << b;
00564 }
00565 
00566 TMPL inline vector<Series>
00567 rec_cst (const Series& p) {
00568   return rec_lin (p, Series (CF(p)));
00569 }
00570 
00571 TMPL inline vector<Series>
00572 rec_cst (const Series& p, nat n) {
00573   return rec_lin (p, vector<Series> (Series (CF(p)), n));
00574 }
00575 
00576 
00577 TMPL
00578 class root_series_rep: public Recursive_series_rep {
00579 public:
00580   //protected:
00581   generic f, x;
00582   M y0;
00583   static Series _eval (const generic& e, const Series& a) {
00584     if (is<literal> (e))
00585       return a;
00586     if (is<Series> (e))
00587       return as<Series> (e);
00588     if (is<compound> (e)) {
00589       if (N(e) == 2) {
00590         if (e[0] == GEN_MINUS)
00591           return - _eval (e[1], a);
00592         if (e[0] == GEN_SQUARE)
00593           return square (_eval (e[1], a));
00594       }
00595       if (N(e) == 3) {
00596         if (e[0] == GEN_MINUS)
00597           return _eval (e[1], a) - _eval (e[2], a);
00598         if (e[0] == GEN_PLUS)
00599           return _eval (e[1], a) + _eval (e[2], a);
00600         if (e[0] == GEN_TIMES)
00601           return _eval (e[1], a) * _eval (e[2], a);
00602       }
00603     }
00604     ERROR ("bug, unexpected type with generic"); }
00605 
00606   static generic _derive (const generic& e, const generic& x) {
00607     if (e == x) return as<generic> (Series (1));
00608     if (is<Series> (e))
00609       return as<generic> (as<Series> (0));
00610     if (is<compound> (e)) {
00611       if (N(e) == 2) {
00612         if (e[0] == GEN_MINUS)
00613           return gen (GEN_MINUS, _derive (e[1], x));
00614         if (e[0] == GEN_SQUARE) {
00615           Series ser_2 (coefficients (as<default_p_expansion(M)> (2)));
00616           return gen (GEN_TIMES, as<generic> (ser_2),
00617                       gen (GEN_TIMES, _derive (e[1], x), e[1]));
00618         }
00619       }
00620       if (N(e) == 3) {
00621         if (e[0] == GEN_MINUS)
00622           return gen (GEN_MINUS, _derive (e[1], x), _derive (e[2], x));
00623         if (e[0] == GEN_PLUS)
00624           return gen (GEN_PLUS, _derive (e[1], x), _derive (e[2], x));
00625         if (e[0] == GEN_TIMES)
00626           return gen (GEN_PLUS, gen (GEN_TIMES, _derive (e[1], x), e[2]),
00627                       gen (GEN_TIMES, e[1], _derive (e[2], x)));
00628       }
00629     }
00630     ERROR ("bug, unexpected type with generic"); }
00631 
00632   vector<Series> _eps (const generic& e, const generic& x) {
00633     if (is<Series> (e))
00634       return rec_cst (as<Series> (e));
00635     if (e == x)
00636       return rec_lin (Series (y0), Series (M(1)));
00637     if (is<compound> (e)) {
00638       if (N(e) == 2) {
00639         if (e[0] == GEN_MINUS)
00640           return rec_minus (_eps (e[1], x));
00641         if (e[0] == GEN_SQUARE)
00642           return rec_square (_eps (e[1], x), this->me ());
00643       }
00644       if (N(e) == 3) {
00645         if (e[0] == GEN_MINUS)
00646           return rec_minus (_eps (e[1], x), _eps (e[2], x));
00647         if (e[0] == GEN_PLUS)
00648           return rec_add (_eps (e[1], x), _eps (e[2], x));
00649         if (e[0] == GEN_TIMES)
00650           return rec_prod (_eps (e[1], x), _eps (e[2], x), this->me ());
00651       }
00652     }
00653     ERROR ("bug, unexpected type with generic"); }
00654 
00655   static void
00656   increase_order_generic (generic ff, nat l) {
00657     if (is<Series> (ff))
00658       increase_order (as<Series> (ff), l);
00659     if (is<compound> (ff)) {
00660       if (N(ff) == 2)
00661         increase_order_generic (ff[1], l);
00662       if (N(ff) == 3) {
00663         increase_order_generic (ff[1], l);
00664         increase_order_generic (ff[2], l);
00665       }
00666     }
00667   }
00668   
00669   public:
00670   root_series_rep (const generic& f2, const generic& x2, const M& y02):
00671     Recursive_series_rep (get_format (y02)), f (f2), x (x2), y0 (y02) {}
00672   syntactic expression (const syntactic& z) const {
00673     return z; }
00674     //return flatten (f, z) / flatten (c); }
00675   virtual void Increase_order (nat l) {
00676     Recursive_series_rep::Increase_order (l);
00677     increase_order_generic (f, l); }
00678   Series initialize () {
00679     this->initial (0) = y0;
00680     generic der = _derive (f, x);
00681     Series evder = _eval (der, y0);
00682     Series num = (Series (y0) * evder - _eval(f, Series (y0)) 
00683                   - _eps (f, x)[0]) / evder;
00684     return num;
00685   }
00686 };
00687 
00688 TMPL static inline Series
00689 root_series (const generic& f, const generic& x, const M& y0) {
00690   return recursive(Series ((Series_rep*) new root_series_rep<M,V> (f, x, y0)));
00691 }
00692 
00693 
00694 
00695 TMPLW
00696 class system_root_series_rep: public recursive_series_rep<Vector, V> {
00697 public:
00698   //protected:
00699   vector<generic> out, vars;
00700   Vector y0;
00701 
00702   static Series
00703   _ev_der (const generic& f, const vector<Series>& a,
00704            const vector<generic>& x, vector<Series>& grad) {
00705     grad = vector<Series> (Series (get_format1 (CF(a))), N(a));
00706     if (is<literal> (f))
00707       for (nat i = 0; i < N(a); i++)
00708         if (f == x[i]) {
00709           grad[i]= Series (M(1));
00710           return a[i];
00711         }
00712     if (is<Series> (f))
00713       return as<Series> (f);
00714     if (is<compound> (f)) {
00715       Series o;
00716       if (N(f) == 2) {
00717         if (f[0] == GEN_MINUS) {
00718           o = -_ev_der (f[1], a, x, grad);
00719           grad = -grad;
00720           return o;
00721         }
00722         if (f[0] == GEN_SQUARE) {
00723           o = _ev_der (f[1], a, x, grad);
00724           Series ser_2 (coefficients (as<default_p_expansion(M)> (2)));
00725           grad = ser_2 * o * grad;
00726           return square (o);
00727         }
00728       }
00729       if (N(f) == 3) {
00730         vector<Series> grad2;
00731         if (f[0] == GEN_MINUS) {
00732           o = _ev_der (f[1], a, x, grad) - _ev_der (f[2], a, x, grad2);
00733           grad = grad - grad2;
00734           return o;
00735         }
00736         if (f[0] == GEN_PLUS) {
00737           o = _ev_der (f[1], a, x, grad) + _ev_der (f[2], a, x, grad2);
00738           grad = grad + grad2;
00739           return o;
00740         }
00741         if (f[0] == GEN_TIMES) {
00742           o =  _ev_der (f[1], a, x, grad);
00743           Series o2 = _ev_der (f[2], a, x, grad2);
00744           grad = o*grad2 + grad*o2;
00745           return o*o2;
00746         } } }
00747     ERROR ("bug, unexpected type with generic"); }
00748 
00749   static Series_vector
00750   _ev_der (const vector<generic>& f, const vector<Series>& a,
00751            const vector<generic>& x, matrix<Series, matrix_naive>& m) {
00752     m = matrix<Series, matrix_naive> (Series (get_format1 (CF(a))),
00753                                       N(f), N(a));
00754     vector<Series> v (Series (get_format1 (CF(a))), N(f));
00755     vector<Series> grad;
00756     for (nat i = 0; i < N(f); i++) {
00757       v[i] = _ev_der (f[i], a, x, grad);
00758       for (nat j = 0; j < N(a); j++)
00759         m (i,j) = grad [j];
00760     }
00761     return as_series (v); }
00762   
00763   vector<Series> 
00764   _eps (const generic& f, const vector<generic>& x, const Series_vector& y) {
00765     nat n = N(x);
00766     if (is<Series> (f))
00767       return rec_cst (as<Series> (f), n);
00768     if (is<literal> (f)) {
00769       for (nat i = 0; i < n; i++)
00770         if (f == x[i]) {
00771           vector<Series> tmp (Series (M(0) /*FIXME*/), n);
00772           tmp [i] = Series (M(1));
00773           return rec_lin (Series (y0[i]), tmp);
00774         }
00775     }
00776     if (is<compound> (f)) {
00777       if (N(f) == 2) {
00778         if (f[0] == GEN_MINUS)
00779           return rec_minus (_eps (f[1], x, y));
00780         if (f[0] == GEN_SQUARE)
00781           return rec_square (_eps (f[1], x, y), as_vector (y));
00782       }
00783       if (N(f) == 3) {
00784         if (f[0] == GEN_MINUS)
00785           return rec_minus (_eps (f[1], x, y), _eps (f[2], x, y));
00786         if (f[0] == GEN_PLUS)
00787           return rec_add (_eps (f[1], x, y), _eps (f[2], x, y));
00788         if (f[0] == GEN_TIMES)
00789           return rec_prod (_eps (f[1], x, y), _eps (f[2], x, y),
00790                            as_vector (y));
00791       }
00792     }
00793     ERROR ("bug, unexpected type with generic"); }
00794 
00795   vector<Series>
00796   _eps (const vector<generic>& e, const vector<generic>& x, 
00797         const Series_vector& y) {
00798     vector<Series> veps (Series (M(0) /*FIXME*/), N(e));
00799     for (nat i = 0; i < N(e); i++) veps [i] = _eps (e[i], x, y)[0];
00800     return veps;
00801   }
00802 
00803   static void
00804   increase_order_generic (generic f, nat l) {
00805     if (is<Series> (f))
00806       increase_order (as<Series> (f), l);
00807     if (is<compound> (f)) {
00808       if (N(f) == 2)
00809         increase_order_generic (f[1], l);
00810       if (N(f) == 3) {
00811         increase_order_generic (f[1], l);
00812         increase_order_generic (f[2], l);
00813       }
00814     }
00815   }
00816 
00817   static inline void
00818   increase_order_generic (vector<generic> f, nat l) {
00819     for (nat i = 0; i < N(f); i++)
00820       increase_order_generic (f[i], l);
00821   }
00822   
00823   
00824   public:
00825   system_root_series_rep (const vector<generic>& out2,
00826                           const vector<generic>& vars2, const Vector& y02):
00827     recursive_series_rep<Vector,V> (get_format (y02)),
00828     out (out2),  vars (vars2), y0 (y02) {}
00829   syntactic expression (const syntactic& z) const {
00830     return z; }
00831     //return flatten (f, z) / flatten (c); }
00832   virtual void Increase_order (nat l) {
00833     recursive_series_rep<Vector,V>::Increase_order (l); 
00834     increase_order_generic (out, l); }
00835   Series_vector initialize () {
00836     //double start = mmx_time ();
00837     //double inter;
00838     
00839     nat n= N(out);
00840     ASSERT (N(vars) == n, "numbers of equations and variables don't match");
00841     this->initial (0) = y0;
00842     matrix<Series, matrix_naive> jac;
00843     vector<Series> num = as_vector (_ev_der (out, as<vector<Series> > (y0),
00844                                              vars, jac));
00845     //mmout << "init: " << (int) (mmx_time() - start) << " + ";
00846     //inter = mmx_time ();
00847     vector<Series> eps = _eps (out, vars, this->me());
00848     //mmout << (int) (mmx_time () - inter) << " + ";
00849     //inter = mmx_time ();
00850     Series_vector res = as_series (ser_ldiv_mat (jac, (jac * \
00851                                    as<vector<Series> > (y0) - num - eps)));
00852     //mmout << (int) (mmx_time () - inter)  << " = ";
00853     //mmout << (int) (mmx_time () - start)  << " ms" << lf;
00854     return res;
00855   }
00856 };
00857 
00858 TMPLW static inline vector<Series,W>
00859 system_root_series (const vector<generic>& f, const vector<generic>& x,
00860                     const Vector& y0) {
00861   typedef system_root_series_rep<M,V,W> Sys_root_rep;
00862   Series_vector s= (series_rep<Vector,V>*) new Sys_root_rep (f, x, y0);
00863   return as_vector (recursive(s));
00864 }
00865 
00866 #undef Series
00867 #undef Series_rep
00868 #undef Recursive_series_rep
00869 #undef C
00870 #undef Modulus
00871 #undef TMPL
00872 #undef TMPLW
00873 #undef Vector
00874 #undef Series_vector
00875 
00876 } // namespace mmx
00877 #endif // __MMX_SERIES_CARRY_NAIVE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines