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