00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_SERIES_CARRY_LINEAR_ALGEBRA_HPP
00014 #define __MMX_SERIES_CARRY_LINEAR_ALGEBRA_HPP
00015 #include <algebramix/series_carry.hpp>
00016 #include <algebramix/series_matrix.hpp>
00017
00018 namespace mmx {
00019 #define TMPL template<typename M, typename V>
00020 #define C typename M::C
00021 #define Series series<M,V>
00022 #define Vector vector<M>
00023 #define Matrix matrix<M>
00024 #define Series_rep series_rep<M,V>
00025 #define Series_vector series<Vector,V>
00026 #define Series_vector_rep series_rep<Vector,V>
00027 #define Vector_series vector<Series>
00028 #define Series_matrix series<Matrix,V>
00029 #define Series_matrix_rep series_rep<Matrix,V>
00030 #define Matrix_series matrix<Series>
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 TMPL Matrix_series
00052 asmatrix (const Series_matrix& f) {
00053 nat nr= rows (f[0]), nc= cols (f[0]);
00054 Matrix_series m (Series (0), nr, nc);
00055 for (nat i=0; i<nr; i++)
00056 for (nat j=0; j<nc; j++)
00057 m (i, j)= access (f, i, j);
00058 return m;
00059 }
00060
00061 TMPL Series_matrix
00062 asseries (const Matrix_series& m) {
00063 return (series_rep<Matrix,V>*)
00064 new matrix_series_rep<M,V,typename Matrix_variant(M)> (m);
00065 }
00066
00067 TMPL Series_vector
00068 asseries (const Vector_series& v) {
00069 return (series_rep<Vector,V>*)
00070 new vector_series_rep<M,V,typename Vector_variant(M)> (v);
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 TMPL
00107 class lshiftz_series_matrix_rep: public series_rep<Matrix,V> {
00108 const Series_matrix f;
00109 const nat r,c;
00110 const int shift;
00111 public:
00112 lshiftz_series_matrix_rep (const Series_matrix& f2, nat r2, nat c2,
00113 int shift2):
00114 series_rep<Matrix,V> (CF(f2)),
00115 f (f2), r (r2), c (c2), shift (shift2) {}
00116 syntactic expression (const syntactic& z) const {
00117 return lshiftz (flatten (f, z), flatten (shift)); }
00118 void Increase_order (nat l) {
00119 series_rep<Matrix,V>::Increase_order (l);
00120 increase_order (f, max (0, ((int) l) - shift)); }
00121 Matrix next () { return shift > ((int) this->n)?
00122 Matrix (M (), r, c): f[this->n - shift]; }
00123 };
00124
00125 TMPL inline Series_matrix
00126 lshiftz_series_matrix (const Series_matrix& f, const nat& r, const nat& c,
00127 const int& shift=1) {
00128 if (is_exact_zero (f)) {
00129 Series zero (get_format1 (CF(f)));
00130 return as_series (Matrix_series (zero, r, c));
00131 }
00132 return Series_matrix ((series_rep<Matrix,V>*)
00133 new lshiftz_series_matrix_rep<M,V> (f, r, c, shift));
00134 }
00135
00136 TMPL inline Vector_series
00137 lshiftz (const Vector_series& v, const int& shift=1) {
00138 nat n= N (v);
00139 Vector_series lv (Series(), n);
00140 for (nat i=0; i<n; i++)
00141 lv[i] = lshiftz (v[i], shift);
00142 return lv;
00143 }
00144
00145 TMPL inline Vector_series
00146 rshiftz (const Vector_series& v, const int& shift=1) {
00147 return lshiftz (v, -shift);
00148 }
00149
00150 TMPL inline Matrix_series
00151 lshiftz (const Matrix_series& m, const int& shift=1) {
00152 nat c= cols (m), r= rows (m);
00153 Matrix_series lm (Series(), r, c);
00154 for (nat i=0; i<r; i++)
00155 for (nat j=0; j<c; j++)
00156 lm(i,j) = lshiftz (m(i,j), shift);
00157 return lm;
00158 }
00159
00160 TMPL inline Matrix_series
00161 rshiftz (const Matrix_series& m, const int& shift=1) {
00162 return lshiftz (m, -shift);
00163 }
00164
00165 TMPL inline Vector
00166 access (const Vector_series& v, nat n) {
00167 nat nv= N (v);
00168 Vector av (M(), nv);
00169 for (nat i=0; i<nv; i++)
00170 av[i] = v[i][n];
00171 return av;
00172 }
00173
00174 TMPL inline Matrix
00175 access (const Matrix_series& m, nat n) {
00176 nat c= cols (m), r= rows (m);
00177 Matrix am (M(), r, c);
00178 for (nat i=0; i<r; i++)
00179 for (nat j=0; j<c; j++)
00180 am(i,j) = m(i,j)[n];
00181 return am;
00182 }
00183
00184
00185
00186
00187
00188 struct series_vector_divide {};
00189
00190 template<typename U>
00191 struct implementation<series_vector_divide,U,series_naive> {
00192
00193 template<typename M, typename V, typename X>
00194 class vector_carry_mul_quo_series_rep: public series_rep<Vector,V> {
00195 typedef Lift_type(M) L;
00196 protected:
00197 Series_vector f;
00198 matrix<L> x;
00199 vector<L> fn, c;
00200 Vector q;
00201 L p;
00202 nat cx, rx, nf;
00203 public:
00204 inline vector_carry_mul_quo_series_rep (const matrix<X>& x2,
00205 const Series_vector& f2):
00206 series_rep<Vector,V> (get_format (vec<Vector>
00207 (get_sample (CF(f2))))),
00208 f(f2), cx(cols(x2)), rx (rows (x2)), nf (N (f2[0]))
00209 {
00210 ASSERT ((cx == rx) && (cx == nf), "Matrix and vector sizes do not match");
00211 p = L (* M::get_modulus());
00212 c = vector<L> (L (0), nf);
00213 fn= vector<L> (L (0), nf);
00214 x = matrix<L> (L (0), rx, cx);
00215 for (nat i=0; i < rx; i++)
00216 for (nat j=0; j < cx; j++)
00217 x(i,j)= L (* x2(i,j));
00218 }
00219 syntactic expression (const syntactic& z) const {
00220 return apply (syntactic ("vector_carry_mul_quo"), flatten (f, z),
00221 flatten (x)); }
00222 virtual void Increase_order (nat l) {
00223 series_rep<Vector,V>::Increase_order (l);
00224 increase_order (f, l); }
00225 virtual Vector next () {
00226 for (nat i=0; i < nf; i++)
00227 fn[i]= L (* f[this->n][i]);
00228 fn= quo (x * fn, p) + c;
00229
00230 q = as<Vector> (rem (fn, p));
00231 c = quo (fn, p);
00232 return q; }
00233 };
00234
00235 TMPL
00236 class vector_carry_mul_rem_series_rep: public series_rep<Vector, V> {
00237 protected:
00238 Matrix m;
00239 Series_vector sv;
00240 public:
00241 inline vector_carry_mul_rem_series_rep (const Matrix& m2,
00242 const Series_vector& sv2):
00243 series_rep<Vector, V> (CF(m2)), m (m2), sv(sv2) {}
00244 syntactic expression (const syntactic& z) const {
00245 return apply (apply (syntactic ("vector_carry_mul_rem"), flatten (m),
00246 flatten (sv,z))); }
00247 virtual void Increase_order (nat l) {
00248 series_rep<Vector, V>::Increase_order (l);
00249 increase_order (sv, l); }
00250 virtual Vector next () {
00251 return m*sv[this->n]; }
00252 };
00253
00254 TMPL
00255 class ldiv_sc_vec_series_rep: public recursive_series_rep<Vector,V> {
00256 protected:
00257 Vector_series f;
00258 Matrix c;
00259 nat nf, rc, cc;
00260 Matrix inv;
00261 bool init;
00262 Vector vinit;
00263 public:
00264 ldiv_sc_vec_series_rep (const Matrix& c2, const Vector_series& f2):
00265 recursive_series_rep<Vector,V> (get_vector_format (f2)),
00266 f(f2), c(c2), nf(N(f2)), rc(rows(c2)), cc(cols(c2)), inv(invert(c)),
00267 init(false) {}
00268 ldiv_sc_vec_series_rep (const Matrix& c2, const Vector_series& f2,
00269 const Matrix& inv2):
00270 recursive_series_rep<Vector,V> (get_vector_format (f2)),
00271 f(f2), c(c2), nf(N(f2)), rc(rows (c2)),cc(cols(c2)), inv(inv2),
00272 init(false) {}
00273 ldiv_sc_vec_series_rep (const Matrix& c2, const Vector_series& f2,
00274 const Matrix& inv2, const Vector& vinit2):
00275 recursive_series_rep<Vector,V> (get_vector_format (f2)),
00276 f(f2), c(c2), nf(N(f2)), rc(rows(c2)), cc(cols(c2)), inv(inv2), init(true),
00277 vinit(vinit2) {}
00278 syntactic expression (const syntactic& z) const {
00279 return invert (flatten (c)) * flatten (f,z); }
00280 virtual void Increase_order (nat l) {
00281 recursive_series_rep<Vector,V>::Increase_order (l);
00282 for (nat i = 0; i < nf; i++)
00283 increase_order (f[i],l);
00284 }
00285 Series_vector initialize () {
00286 ASSERT ((cc == rc) && (cc == nf), "Matrix and vector sizes do not match");
00287 if (init) this->initial (0)= vinit;
00288 else this->initial (0)= inv * access (f, 0);
00289 Series_vector ls_me = lshiftz_series_vector (this -> me (), nf);
00290 Vector_series tmp= f - as_vector (lmul_quo (c, ls_me));
00291 return lmul_rem (inv, asseries (tmp));
00292 }
00293 };
00294
00295 TMPL
00296 class ldiv_vec_series_rep: public recursive_series_rep<Vector,V> {
00297 protected:
00298 Vector_series f;
00299 Matrix_series m;
00300 nat nf, rm, cm;
00301 bool init;
00302 Vector vinit;
00303 public:
00304 ldiv_vec_series_rep (const Matrix_series& m2, const Vector_series& f2):
00305 recursive_series_rep<Vector,V> (get_vector_format (f2)), f(f2), m(m2),
00306 nf(N(f2)), rm(rows(m2)), cm(cols(m2)), init(false) {}
00307 ldiv_vec_series_rep (const Matrix_series& m2, const Vector_series& f2,
00308 const Vector& vinit2):
00309 recursive_series_rep<Vector,V> (get_vector_format (f2)), f(f2), m(m2),
00310 nf(N(f2)), rm(rows(m2)), cm(cols(m2)), init(true), vinit (vinit2) {}
00311 syntactic expression (const syntactic& z) const {
00312 return invert (flatten (m)) * flatten (f,z); }
00313 virtual void Increase_order (nat l) {
00314 recursive_series_rep<Vector,V>::Increase_order (l);
00315 for (nat i = 0; i < nf; i++) {
00316 increase_order (f[i],l);
00317 for (nat j = 0; j < cm; j++)
00318 increase_order (m(i,j),l);
00319 }
00320 }
00321 Series_vector initialize () {
00322 ASSERT ((cm == rm) && (cm == nf), "Matrix and vector sizes do not match");
00323 Matrix inv= invert (access (m, 0));
00324 if(init) this->initial (0)= vinit;
00325 else this->initial (0)= inv * access (f, 0);
00326 Vector_series va = f - lshiftz (rshiftz (m) * as_vector (this-> me ()));
00327 return ldiv (access (m, 0), va, inv);
00328 }
00329 };
00330
00331 TMPL static inline Series_vector
00332 ser_lmul_quo_sc (const Matrix& c, const Series_vector& f) {
00333 return Series_vector ((series_rep<Vector,V> *)
00334 new vector_carry_mul_quo_series_rep<M,V,M> (c, f));
00335 }
00336
00337 TMPL static inline Series_vector
00338 ser_lmul_rem_sc (const Matrix& m, const Series_vector& sv) {
00339 return Series_vector ((series_rep<Vector, V> *)
00340 new vector_carry_mul_rem_series_rep<M,V> (m, sv));
00341 }
00342
00343 TMPL static inline Series_vector
00344 ser_ldiv_sc (const Matrix& c, const Vector_series& f) {
00345 typedef ldiv_sc_vec_series_rep<M,V> Div_sc_rep;
00346 return recursive (Series_vector ((series_rep<Vector,V>*)
00347 new Div_sc_rep (c,f)));
00348 }
00349
00350 TMPL static inline Series_vector
00351 ser_ldiv_sc (const Matrix& c, const Vector_series& f, const Matrix& inv) {
00352 typedef ldiv_sc_vec_series_rep<M,V> Div_sc_rep;
00353 return recursive (Series_vector ((series_rep<Vector,V>*)
00354 new Div_sc_rep (c, f, inv)));
00355 }
00356
00357 TMPL static inline Series_vector
00358 ser_ldiv_sc (const Matrix& c, const Vector_series& f, const Matrix& inv,
00359 const Vector& init) {
00360 typedef ldiv_sc_vec_series_rep<M,V> Div_sc_rep;
00361 return recursive (Series_vector ((series_rep<Vector,V>*)
00362 new Div_sc_rep (c, f, inv, init)));
00363 }
00364
00365 TMPL static inline Series_vector
00366 ser_ldiv (const Matrix_series& m, const Vector_series& f) {
00367 typedef ldiv_vec_series_rep<M,V> Div_rep;
00368 return recursive (Series_vector ((series_rep<Vector,V>*)
00369 new Div_rep (m, f)));
00370 }
00371
00372 TMPL static inline Series_vector
00373 ser_ldiv (const Matrix_series& m, const Vector_series& f, const Vector& init) {
00374 typedef ldiv_vec_series_rep<M,V> Div_rep;
00375 return recursive (Series_vector ((series_rep<Vector,V>*)
00376 new Div_rep (m, f, init)));
00377 }
00378
00379
00380 };
00381
00382 TMPL static inline Series_vector
00383 lmul_quo (const Matrix& m, const Series_vector& sv) {
00384 typedef implementation<series_vector_divide,V> Ser;
00385 return Ser::template ser_lmul_quo_sc<M,V> (m, sv);
00386 }
00387
00388 TMPL inline Series_vector
00389 lmul_rem (const Matrix& m, const Series_vector& sv) {
00390 typedef implementation<series_vector_divide,V> Ser;
00391 return Ser::template ser_lmul_rem_sc<M,V> (m, sv);
00392 }
00393
00394 TMPL static inline Series_vector
00395 ldiv (const Matrix& m, const Vector_series& vs) {
00396 typedef implementation<series_vector_divide,V> Ser;
00397 return Ser::template ser_ldiv_sc<M,V> (m, vs);
00398 }
00399
00400 TMPL static inline Series_vector
00401 ldiv (const Matrix& m, const Vector_series& vs, const Matrix& inv) {
00402 typedef implementation<series_vector_divide,V> Ser;
00403 return Ser::template ser_ldiv_sc<M,V> (m, vs, inv);
00404 }
00405
00406 TMPL static inline Series_vector
00407 ldiv (const Matrix& m, const Vector_series& vs, const Matrix& inv,
00408 const Vector& init) {
00409 typedef implementation<series_vector_divide,V> Ser;
00410 return Ser::template ser_ldiv_sc<M,V> (m, vs, inv, init);
00411 }
00412
00413 TMPL static inline Series_vector
00414 ldiv (const Matrix_series& m, const Vector_series& vs) {
00415 typedef implementation<series_vector_divide,V> Ser;
00416 return Ser::template ser_ldiv<M,V> (m, vs);
00417 }
00418
00419 TMPL static inline Series_vector
00420 ldiv (const Matrix_series& m, const Vector_series& vs, const Vector& init) {
00421 typedef implementation<series_vector_divide,V> Ser;
00422 return Ser::template ser_ldiv<M,V> (m, vs, init);
00423 }
00424
00425
00426
00427
00428
00429 struct series_matrix_divide {};
00430
00431 template<typename U>
00432 struct implementation<series_matrix_divide,U,series_naive> {
00433
00434 template<typename M, typename V, typename X>
00435 class matrix_carry_mul_quo_series_rep:
00436 public series_rep<Matrix,V> {
00437 typedef Lift_type(M) L;
00438 protected:
00439 Series_matrix f;
00440 matrix<L> x, fn, c;
00441 Matrix q;
00442 L p;
00443 nat cx, rx, cf, rf;
00444 public:
00445 inline matrix_carry_mul_quo_series_rep (const matrix<X>& x2,
00446 const Series_matrix& f2):
00447 series_rep<Matrix,V> (get_format (vec<Matrix>
00448 (get_sample (CF(f2))))),
00449 f(f2), cx(cols(x2)), rx (rows (x2)), cf (cols (f2[0])), rf (rows (f2[0]))
00450 {
00451 ASSERT ((cx == rx) && (cx == rf), "Matrices sizes do not match");
00452 p = L (* M::get_modulus());
00453 c = matrix<L> (L (0), rf, cf);
00454 fn= matrix<L> (L (0), rf, cf);
00455 x = matrix<L> (L (0), rx, cx);
00456 for (nat i=0; i < rx; i++)
00457 for (nat j=0; j < cx; j++)
00458 x(i,j)= L (* x2(i,j));
00459 }
00460 syntactic expression (const syntactic& z) const {
00461 return apply (syntactic ("matrix_carry_mul_quo"), flatten (f, z),
00462 flatten (x)); }
00463 virtual void Increase_order (nat l) {
00464 series_rep<Matrix,V>::Increase_order (l);
00465 increase_order (f, l); }
00466 virtual Matrix next () {
00467 for (nat i=0; i < rf; i++)
00468 for (nat j=0; j < cf; j++)
00469 fn(i,j)= L (* f[this->n](i,j));
00470 fn= quo (x * fn, p) + c;
00471 q = as<Matrix> (rem (fn, p));
00472 c = quo (fn, p);
00473 return q; }
00474 };
00475
00476 TMPL
00477 class matrix_carry_mul_rem_series_rep: public series_rep<Matrix, V> {
00478 protected:
00479 Matrix m;
00480 Series_matrix sm;
00481 public:
00482 inline matrix_carry_mul_rem_series_rep (const Matrix& m2,
00483 const Series_matrix& sm2):
00484 series_rep<Matrix, V> (CF(m2)), m (m2), sm(sm2) {}
00485 syntactic expression (const syntactic& z) const {
00486 return apply (apply (syntactic ("matrix_carry_mul_rem"), flatten (m),
00487 flatten (sm,z))); }
00488 virtual void Increase_order (nat l) {
00489 series_rep<Matrix, V>::Increase_order (l);
00490 increase_order (sm, l); }
00491 virtual Matrix next () {
00492 return m*sm[this->n]; }
00493 };
00494 TMPL
00495 class ldiv_sc_vec_series_rep: public recursive_series_rep<Vector,V> {
00496 protected:
00497 Vector_series f;
00498 Matrix c;
00499 nat nf, rc, cc;
00500 Matrix inv;
00501 public:
00502 ldiv_sc_vec_series_rep (const Matrix& c2, const Vector_series& f2):
00503 recursive_series_rep<Vector,V> (get_vector_format (f2)),
00504 f(f2), c(c2), nf (N(f2)), rc (rows (c2)), cc (cols (c2)), inv (invert (c))
00505 {}
00506 ldiv_sc_vec_series_rep (const Matrix& c2, const Vector_series& f2,
00507 const Matrix& inv2):
00508 recursive_series_rep<Vector,V> (get_vector_format (f2)),
00509 f(f2), c(c2), nf (N(f2)), rc (rows (c2)), cc (cols (c2)), inv (inv2) {}
00510 syntactic expression (const syntactic& z) const {
00511 return invert (flatten (c)) * flatten (f,z); }
00512 virtual void Increase_order (nat l) {
00513 recursive_series_rep<Vector,V>::Increase_order (l);
00514 for (nat i = 0; i < nf; i++)
00515 increase_order (f[i],l);
00516 }
00517 Series_vector initialize () {
00518 ASSERT ((cc == rc) && (cc == nf), "Matrix and vector sizes do not match");
00519 this->initial (0)= inv * access (f, 0);
00520 Series_vector ls_me = lshiftz_series_vector (this -> me (), nf);
00521 Vector_series tmp= f - as_vector (lmul_quo (c, ls_me));
00522 return lmul_rem (inv, asseries (tmp));
00523 }
00524 };
00525
00526 TMPL static inline Series_vector
00527 ser_ldiv_sc_vec (const Matrix& c, const Vector_series& f) {
00528 typedef ldiv_sc_vec_series_rep<M,V> Div_sc_vec_rep;
00529
00530
00531 return recursive (Series_vector ((series_rep<Vector,V>*)
00532 new Div_sc_vec_rep (c,f)));
00533 }
00534
00535 TMPL static inline Series_vector
00536 ser_ldiv_sc_vec (const Matrix& c, const Vector_series& f, const Matrix& inv) {
00537 typedef ldiv_sc_vec_series_rep<M,V> Div_sc_vec_rep;
00538
00539
00540 return recursive (Series_vector ((series_rep<Vector,V>*)
00541 new Div_sc_vec_rep (c,f, inv)));
00542 }
00543
00544 TMPL
00545 class ldiv_vec_series_rep: public recursive_series_rep<Vector,V> {
00546 protected:
00547 Vector_series f;
00548 Matrix_series m;
00549 nat nf, rm, cm;
00550 public:
00551 ldiv_vec_series_rep (const Matrix_series& m2, const Vector_series& f2):
00552 recursive_series_rep<Vector,V> (get_vector_format (f2)), f(f2), m(m2),
00553 nf(N(f2)), rm(rows (m2)), cm(cols (m2)) {}
00554 syntactic expression (const syntactic& z) const {
00555 return invert (flatten (m)) * flatten (f,z); }
00556 virtual void Increase_order (nat l) {
00557 recursive_series_rep<Vector,V>::Increase_order (l);
00558 for (nat i = 0; i < nf; i++) {
00559 increase_order (f[i],l);
00560 for (nat j = 0; j < cm; j++)
00561 increase_order (m(i,j),l);
00562 }
00563 }
00564 Series_vector initialize () {
00565 ASSERT ((cm == rm) && (cm == nf), "Matrix and vector sizes do not match");
00566 Matrix inv= invert (access (m, 0));
00567 this->initial (0)= inv * access (f, 0);
00568 Vector_series va = f - lshiftz (rshiftz (m) * as_vector (this-> me ()));
00569
00570 return ser_ldiv_sc_vec (access (m, 0), va, inv);
00571 }
00572 };
00573
00574 TMPL static inline Series_vector
00575 ser_ldiv_vec (const Matrix_series& m, const Vector_series& f) {
00576 typedef ldiv_vec_series_rep<M,V> Div_vec_rep;
00577
00578
00579
00580
00581
00582
00583 return recursive (Series_vector ((series_rep<Vector,V>*)
00584 new Div_vec_rep (m,f)));
00585 }
00586
00587
00588
00589
00590
00591 TMPL
00592 class ldiv_sc_mat_series_rep: public recursive_series_rep<Matrix,V> {
00593 protected:
00594 Matrix_series f;
00595 Matrix c;
00596 nat rf, cf, rc, cc;
00597 Matrix inv;
00598 bool init;
00599 Matrix minit;
00600 public:
00601 ldiv_sc_mat_series_rep (const Matrix& c2, const Matrix_series& f2):
00602 recursive_series_rep<Matrix,V> (get_matrix_format (f2)), f(f2), c(c2),
00603 rf(rows(f2)), cf(cols(f2)), rc(rows(c2)), cc(cols(c2)), inv(invert(c)),
00604 init(false) {}
00605 ldiv_sc_mat_series_rep (const Matrix& c2, const Matrix_series& f2,
00606 const Matrix& inv2):
00607 recursive_series_rep<Matrix,V> (get_matrix_format (f2)), f (f2), c (c2),
00608 rf(rows(f2)), cf(cols(f2)), rc(rows(c2)), cc(cols(c2)), inv(inv2),
00609 init(false) {}
00610 ldiv_sc_mat_series_rep (const Matrix& c2, const Matrix_series& f2,
00611 const Matrix& inv2, const Matrix& minit2):
00612 recursive_series_rep<Matrix,V> (get_matrix_format (f2)), f(f2), c(c2),
00613 rf(rows(f2)), cf(cols(f2)), rc(rows(c2)), cc(cols(c2)), inv(inv2),
00614 init(true), minit(minit2) {}
00615 syntactic expression (const syntactic& z) const {
00616 return invert (flatten (c)) * flatten (f,z); }
00617 virtual void Increase_order (nat l) {
00618 recursive_series_rep<Matrix,V>::Increase_order (l);
00619 for (nat i = 0; i < rf; i++)
00620 for (nat j = 0; j < cf; j++)
00621 increase_order (f(i,j), l);
00622 }
00623 Series_matrix initialize () {
00624 ASSERT ((cc == rc) && (cc == rf), "Matrices sizes do not match");
00625 if (init) this->initial (0)= minit;
00626 else this->initial (0)= inv * access (f, 0);
00627 Series_matrix ls_me = lshiftz_series_matrix (this -> me (), rc, cf);
00628 Matrix_series tmp= f - asmatrix (lmul_quo (c, ls_me));
00629 return lmul_rem (inv, asseries (tmp));
00630 }
00631 };
00632 TMPL
00633 class ldiv_mat_series_rep: public recursive_series_rep<Matrix,V> {
00634 protected:
00635 Matrix_series f;
00636 Matrix_series m;
00637 nat rf, cf, rm, cm;
00638 bool init;
00639 Matrix minit;
00640 public:
00641 ldiv_mat_series_rep (const Matrix_series& m2, const Matrix_series& f2):
00642 recursive_series_rep<Matrix,V> (get_matrix_format (m2)), f(f2), m(m2),
00643 rf(rows(f2)), cf(cols(f2)), rm(rows(m2)), cm(cols(m2)), init(false) {}
00644 ldiv_mat_series_rep (const Matrix_series& m2, const Matrix_series& f2,
00645 const Matrix& minit2):
00646 recursive_series_rep<Matrix,V> (get_matrix_format (m2)), f(f2), m(m2),
00647 rf(rows(f2)), cf(cols(f2)), rm(rows(m2)), cm(cols(m2)), init(true),
00648 minit (minit2) {}
00649 syntactic expression (const syntactic& z) const {
00650 return invert (flatten (m)) * flatten (f,z); }
00651 virtual void Increase_order (nat l) {
00652 recursive_series_rep<Matrix,V>::Increase_order (l);
00653 for (nat i = 0; i < rf; i++) {
00654 for (nat j = 0; j < cf; j++)
00655 increase_order (f(i,j),l);
00656 for (nat j = 0; j < cm; j++)
00657 increase_order (m(i,j),l);
00658 }
00659 }
00660 Series_matrix initialize () {
00661 ASSERT ((cm == rm) && (cm == rf), "Matrices sizes do not match");
00662 Matrix inv= invert (access (m, 0));
00663 if (init) this->initial (0)= minit;
00664 else this->initial (0)= inv * access (f, 0);
00665 Matrix_series ma = f - lshiftz (rshiftz (m) * asmatrix (this-> me ()));
00666 return ldiv (access (m, 0), ma, inv);
00667 }
00668 };
00669
00670 TMPL static inline Series_matrix
00671 ser_lmul_quo_sc (const Matrix& c, const Series_matrix& f) {
00672 return Series_matrix ((series_rep<Matrix,V> *)
00673 new matrix_carry_mul_quo_series_rep<M,V,M> (c, f));
00674 }
00675
00676 TMPL static inline Series_matrix
00677 ser_lmul_rem_sc (const Matrix& m, const Series_matrix& sm) {
00678 return Series_matrix ((series_rep<Matrix, V> *)
00679 new matrix_carry_mul_rem_series_rep<M,V> (m, sm));
00680 }
00681
00682 TMPL static inline Series_matrix
00683 ser_ldiv_sc (const Matrix& c, const Matrix_series& f) {
00684 typedef ldiv_sc_mat_series_rep<M,V> Div_sc_rep;
00685 return recursive (Series_matrix ((series_rep<Matrix,V>*)
00686 new Div_sc_rep (c, f)));
00687 }
00688
00689 TMPL static inline Series_matrix
00690 ser_ldiv_sc (const Matrix& c, const Matrix_series& f, const Matrix& inv) {
00691 typedef ldiv_sc_mat_series_rep<M,V> Div_sc_rep;
00692 return recursive (Series_matrix ((series_rep<Matrix,V>*)
00693 new Div_sc_rep (c, f, inv)));
00694 }
00695
00696 TMPL static inline Series_matrix
00697 ser_ldiv_sc (const Matrix& c, const Matrix_series& f, const Matrix& inv,
00698 const Matrix& init) {
00699 typedef ldiv_sc_mat_series_rep<M,V> Div_sc_rep;
00700 return recursive (Series_matrix ((series_rep<Matrix,V>*)
00701 new Div_sc_rep (c, f, inv, init)));
00702 }
00703
00704 TMPL static inline Series_matrix
00705 ser_ldiv (const Matrix_series& m, const Matrix_series& f) {
00706 typedef ldiv_mat_series_rep<M,V> Div_rep;
00707 return recursive (Series_matrix ((series_rep<Matrix,V>*)
00708 new Div_rep (m, f)));
00709 }
00710
00711 TMPL static inline Series_matrix
00712 ser_ldiv (const Matrix_series& m, const Matrix_series& f, const Matrix& init) {
00713 typedef ldiv_mat_series_rep<M,V> Div_rep;
00714 return recursive (Series_matrix ((series_rep<Matrix,V>*)
00715 new Div_rep (m, f, init)));
00716 }
00717
00718 };
00719
00720 TMPL static inline Series_matrix
00721 lmul_quo (const Matrix& m, const Series_matrix& sm) {
00722 typedef implementation<series_matrix_divide,V> Ser;
00723 return Ser::template ser_lmul_quo_sc<M,V> (m, sm);
00724 }
00725
00726 TMPL inline Series_matrix
00727 lmul_rem (const Matrix& m, const Series_matrix& sm) {
00728 typedef implementation<series_matrix_divide,V> Ser;
00729 return Ser::template ser_lmul_rem_sc<M,V> (m, sm);
00730 }
00731
00732 TMPL static inline Series_matrix
00733 ldiv (const Matrix& m, const Matrix_series& ms) {
00734 typedef implementation<series_matrix_divide,V> Ser;
00735 return Ser::template ser_ldiv_sc<M,V> (m, ms);
00736 }
00737
00738 TMPL static inline Series_matrix
00739 ldiv (const Matrix& m, const Matrix_series& ms, const Matrix& inv) {
00740 typedef implementation<series_matrix_divide,V> Ser;
00741 return Ser::template ser_ldiv_sc<M,V> (m, ms, inv);
00742 }
00743
00744 TMPL static inline Series_matrix
00745 ldiv (const Matrix& m, const Matrix_series& ms, const Matrix& inv,
00746 const Matrix& init) {
00747 typedef implementation<series_matrix_divide,V> Ser;
00748 return Ser::template ser_ldiv_sc<M,V> (m, ms, inv, init);
00749 }
00750
00751 TMPL static inline Series_matrix
00752 ldiv (const Matrix_series& m, const Matrix_series& ms) {
00753 typedef implementation<series_matrix_divide,V> Ser;
00754 return Ser::template ser_ldiv<M,V> (m, ms);
00755 }
00756
00757 TMPL static inline Series_matrix
00758 ldiv (const Matrix_series& m, const Matrix_series& ms, const Matrix& init) {
00759 typedef implementation<series_matrix_divide,V> Ser;
00760 return Ser::template ser_ldiv<M,V> (m, ms, init);
00761 }
00762
00763
00764
00765
00766
00767 #define TMPLB template<typename M, typename V, nat s, typename BV, nat t>
00768 #define Monoblock_series series <Monoblock_modular,BV>
00769 #define Monoblock_transformer series_carry_monoblock_transformer<M,V,s,BV>
00770 #define Monoblock_modular modular<modulus<Lift_type(M)>, \
00771 modular_global_series_carry_monoblock \
00772 <M,s,BV> >
00773
00774 template<typename U,typename W,nat s,typename BV,nat t>
00775 struct implementation<series_vector_divide,U,
00776 series_carry_monoblock<W,s,BV,t> > {
00777
00778 template<typename M, typename V>
00779 class ldiv_vec_monoblock_series_rep: public Series_vector_rep {
00780 protected:
00781 Vector_series f;
00782 Matrix_series m;
00783 nat nf, rm, cm;
00784
00785 Monoblock_transformer blocker;
00786 bool h1_init;
00787 Series_vector h0, h1;
00788
00789 public:
00790 ldiv_vec_monoblock_series_rep (const Matrix_series& m2,
00791 const Vector_series& f2):
00792 Series_vector_rep (get_vector_format (f2)), f(f2), m(m2), nf(N(f2)),
00793 rm(rows(m2)), cm(cols(m2)), h1_init(false) {
00794 h0 = ldiv (m, f);
00795 }
00796 syntactic expression (const syntactic& z) const {
00797 return invert (flatten (m)) * flatten (f,z); }
00798 virtual void Increase_order (nat l) {
00799 Series_vector_rep::Increase_order (l);
00800 if (l <= t)
00801 increase_order (h0, l);
00802 else {
00803 if (! h1_init) {
00804 typedef Monoblock_modular MM;
00805 typedef Lift_type (M) L;
00806 MM::set_modulus (binpow (L(* M::get_modulus ()), s));
00807 matrix<Monoblock_series> newm (Monoblock_series (), rm, rm);
00808 vector<Monoblock_series> newf (Monoblock_series (), nf);
00809 vector<MM> init (MM (0), rm);
00810 for (nat i=0; i<rm; i++) {
00811 newf[i]= to_monoblock (f[i], blocker);
00812 init[i]= as<L> (truncate (access (h0, i), s));
00813 for (nat j=0; j<rm; j++)
00814 newm(i,j)= to_monoblock (m(i,j), blocker);
00815 }
00816 vector<Monoblock_series> newvh1= as_vector (ldiv (newm, newf, init));
00817 Vector_series vh1 (Series(), nf);
00818 for (nat i=0; i<rm; i++)
00819 vh1[i]= from_monoblock (newvh1[i], blocker);
00820 h1= asseries (vh1);
00821 h1_init= true;
00822 }
00823 increase_order (h1, l); } }
00824 Vector next () {
00825 return this->n < t ? h0[this->n] : h1[this->n]; }
00826 };
00827
00828
00829 TMPL static inline Series_vector
00830 ser_lmul_quo_sc (const Matrix& c, const Series_vector& f) {
00831 typedef implementation<series_vector_divide,W> Ser;
00832 return Ser::ser_lmul_quo_sc (c, f); }
00833
00834 TMPL static inline Series_vector
00835 ser_lmul_rem_sc (const Matrix& c, const Series_vector& f) {
00836 typedef implementation<series_vector_divide,W> Ser;
00837 return Ser::ser_lmul_rem_sc (c, f); }
00838
00839 TMPL static inline Series_vector
00840 ser_ldiv_sc (const Matrix& c, const Vector_series& f) {
00841 typedef implementation<series_vector_divide,W> Ser;
00842 return Ser::ser_ldiv_sc (c, f); }
00843
00844 TMPL static inline Series_vector
00845 ser_ldiv_sc (const Matrix& c, const Vector_series& f, const Matrix& inv) {
00846 typedef implementation<series_vector_divide,W> Ser;
00847 return Ser::ser_ldiv_sc (c, f, inv); }
00848
00849
00850 TMPL static inline Series_vector
00851 ser_ldiv (const Matrix_series& c, const Vector_series& f) {
00852 typedef ldiv_vec_monoblock_series_rep<M,W> Div_rep;
00853 series<vector<M>,W> s =
00854 series<vector<M>,W> ((series_rep<vector<M>,W>*) new Div_rep
00855 (as<matrix<series<M,W> > > (c),
00856 as<vector<series<M,W> > > (f)));
00857 return as<Series_vector> (s);
00858 }
00859
00860 };
00861
00862 template<typename U,typename W,nat s,typename BV,nat t>
00863 struct implementation<series_matrix_divide,U,
00864 series_carry_monoblock<W,s,BV,t> > {
00865
00866 template<typename M, typename V>
00867 class ldiv_mat_monoblock_series_rep: public Series_matrix_rep {
00868 protected:
00869 Matrix_series f;
00870 Matrix_series m;
00871 nat rf, cf, rm, cm;
00872
00873 Monoblock_transformer blocker;
00874 bool h1_init;
00875 Series_matrix h0, h1;
00876 public:
00877 ldiv_mat_monoblock_series_rep (const Matrix_series& m2,
00878 const Matrix_series& f2):
00879 Series_matrix_rep (get_matrix_format (f2)), f(f2), m(m2), rf(rows(f2)),
00880 cf(cols(f2)), rm(rows(m2)), cm(cols(m2)), h1_init(false) {
00881 h0 = ldiv (m, f);
00882 }
00883 syntactic expression (const syntactic& z) const {
00884 return invert (flatten (m)) * flatten (f,z); }
00885 virtual void Increase_order (nat l) {
00886 Series_matrix_rep::Increase_order (l);
00887 if (l <= t)
00888 increase_order (h0, l);
00889 else {
00890 if (! h1_init) {
00891 typedef Monoblock_modular MM;
00892 typedef Lift_type (M) L;
00893 MM::set_modulus (binpow (L(* M::get_modulus ()), s));
00894 matrix<Monoblock_series> newm (Monoblock_series (), rm, cm);
00895 matrix<Monoblock_series> newf (Monoblock_series (), rf, cf);
00896 matrix<MM> init (MM (0), rm, cf);
00897 for (nat i=0; i<rm; i++) {
00898 for (nat j=0; j<cm; j++)
00899 newm(i,j)= to_monoblock (m(i,j), blocker);
00900 for (nat j=0; j<cf; j++) {
00901 newf(i,j)= to_monoblock (f(i,j), blocker);
00902 init(i,j)= as<L> (truncate (access (h0, i, j), s));
00903 }
00904 }
00905 matrix<Monoblock_series> newmh1= asmatrix (ldiv (newm, newf, init));
00906 Matrix_series mh1 (Series(), rm, cf);
00907 for (nat i=0; i<rm; i++)
00908 for (nat j=0; j<cf; j++) {
00909 mh1(i,j)= from_monoblock (newmh1(i,j), blocker);
00910 }
00911 h1= asseries (mh1);
00912 h1_init= true;
00913 }
00914 increase_order (h1, l); } }
00915 Matrix next () {
00916 return this->n < t ? h0[this->n] : h1[this->n]; }
00917 };
00918
00919 TMPL static inline Series_matrix
00920 ser_lmul_quo_sc (const Matrix& c, const Series_matrix& f) {
00921 typedef implementation<series_matrix_divide,W> Ser;
00922 return Ser::ser_lmul_quo_sc (c, f); }
00923
00924 TMPL static inline Series_matrix
00925 ser_lmul_rem_sc (const Matrix& c, const Series_matrix& f) {
00926 typedef implementation<series_matrix_divide,W> Ser;
00927 return Ser::ser_lmul_rem_sc (c, f); }
00928
00929 TMPL static inline Series_matrix
00930 ser_ldiv_sc (const Matrix& c, const Matrix_series& f) {
00931 typedef implementation<series_matrix_divide,W> Ser;
00932 return Ser::ser_ldiv_sc (c, f);
00933 }
00934
00935 TMPL static inline Series_matrix
00936 ser_ldiv_sc (const Matrix& c, const Matrix_series& f, const Matrix& inv) {
00937 typedef implementation<series_matrix_divide,W> Ser;
00938 return Ser::ser_ldiv_sc (c, f, inv);
00939 }
00940
00941 TMPL static inline Series_matrix
00942 ser_ldiv (const Matrix_series& c, const Matrix_series& f) {
00943 typedef ldiv_mat_monoblock_series_rep<M,W> Div_rep;
00944 series<matrix<M>,W> s =
00945 series<matrix<M>,W> ((series_rep<matrix<M>,W>*) new Div_rep
00946 (as<matrix<series<M,W> > > (c),
00947 as<matrix<series<M,W> > > (f)));
00948 return as<Series_matrix> (s);
00949 }
00950
00951 };
00952
00953 #undef Monoblock_modular
00954 #undef Monoblock_transformer
00955 #undef Monoblock_series
00956 #undef TMPLB
00957
00958
00959
00960
00961
00962 #if 0
00963 TMPL
00964 class slp_polynomial_system_regular_root_series_rep:
00965 public recursive_series_rep<Vector, V> {
00966 public:
00967
00968 vector<generic> out, vars;
00969 Vector y0;
00970
00971 inline vector<Series>
00972 rec_add (const vector<Series>& p, const vector<Series>& q) {
00973 return p + q;
00974 }
00975 inline vector<Series>
00976 rec_add (const vector<Series>& ep, vector<vector<L> >& tp,
00977 const vector<Series>& eq, const vector<vector<L> >& tq) {
00978 tp= tp + tq;
00979 return ep + eq;
00980 }
00981
00982 inline vector<Series>
00983 rec_minus (const vector<Series>& p) {
00984 return -p;
00985 }
00986 inline vector<Series>
00987 rec_minus (const vector<Series>& ep, vector<vector<L> >& tp) {
00988 tp= -tp;
00989 return -ep;
00990 }
00991
00992 inline vector<Series>
00993 rec_minus (const vector<Series>& p, const vector<Series>& q) {
00994 return p - q;
00995 }
00996 inline vector<Series>
00997 rec_minus (const vector<Series>& ep, vector<vector<L> >& tp,
00998 const vector<Series>& eq, const vector<vector<L> >& tq) {
00999 tp= tp - tq;
01000 return ep - eq;
01001 }
01002
01003 inline vector<Series>
01004 rec_prod (const vector<Series>& p, const vector<Series>& q,
01005 const vector<Series>& y) {
01006 nat l= N(p);
01007 ASSERT (l == N(q) && (l-2) == N(y), "Wrong size of arguments");
01008 const Series& ep=p[0], ap=p[1], eq=q[0], aq=q[1];
01009 vector<Series> bp = range (p, 2, l);
01010 vector<Series> bq = range (q, 2, l);
01011
01012
01013 vector<Series> ry = as_vector (rshiftz (as_series (y)), N(y));
01014 vector<Series> lry = as_vector (lshiftz_series_vector
01015 (rshiftz (as_series (y)), l-2));
01016 Series tp = ap + dot (bp, lry);
01017 Series tq = aq + dot (bq, lry);
01018 Series er = (ep * eq + lshiftz (tp * rshiftz (eq, 2), 2) +
01019 lshiftz (rshiftz (ep, 2) * tq, 2) +
01020 lshiftz (dot (ry, bp) * dot (bq, ry), 2));
01021 return (vec<Series> (er, ap * aq) << (ap * bq + bp * aq));
01022 }
01023 inline vector<Series>
01024 rec_prod (const vector<Series>& ep, vector<vector<L> >& tp,
01025 const vector<Series>& eq, const vector<vector<L> >& tq,
01026 const vector<Series>& rme, const vector<Series>& pr_rme) {
01027 nat r= N(rme);
01028 ASSERT ((N(ep) == r+1) && (N(eq) == r+1), "Wrong size of tau");
01029 const vector<L>& ap= tp[0], aq= tq[0];
01030 vector<Series> aps (Series (), r);
01031 vector<Series> bps (Series (), r);
01032 for (nat i = 0; i < r; i++) {
01033 aps[i]= integer_to_series_carry<M,V> (ap[i]);
01034 bps[i]= integer_to_series_carry<M,V> (bp[i]);
01035 }
01036 vector<vector<L> > bp (vector<L> (), r);
01037 vector<vector<L> > bq (vector<L> (), r);
01038 vector<vector<Series> > bps (vector<Series> (), r);
01039 vector<vector<Series> > bqs (vector<Series> (), r);
01040 for (nat i = 0; i < r; i++) {
01041 bp[i]= range (tp, 1, r+1);
01042 bq[i]= range (tq, 1, r+1);
01043 for (nat j= 0; j < r; j++) {
01044 bps[i][j]= integer_to_series_carry<M,V> (bp[i][j]);
01045 bqs[i][j]= integer_to_series_carry<M,V> (bq[i][j]);
01046 }
01047 }
01048 vector<Series> c1 (Series (), r);
01049 vector<Series> c2 (Series (), r);
01050 for (nat i = 0; i < r; i++) {
01051 c1[i]= (dot (bp[i], lshiftz (rme)) * rshiftz (eq[i], 2)
01052 + dot (bq[i], lshiftz (rme)) * rshiftz (ep[i], 2));
01053 c2[i]= aps[i] * rshiftz (eq[i], 2) + bps[i] * rshiftz (ep[i], 2);
01054 }
01055 vector<Series> res (Series (), r);
01056 for (nat i = 0; i < r; i++) {
01057 tp[i]= vec<L> (ap[i] * aq[i]) << (ap[i] * bq[i] + bp[i] * aq[i]);
01058 res[i]= c1 + c2;
01059 for (nat j = 0; j < r; j++)
01060 for (nat k = j; k < r; k++)
01061 res[i] += ((bp[i][j] * bq[i][k] + bp[i][k] * bq[i][j])
01062 * pr_rme [i*r+j-i*(i+1)/2]);
01063 res[i] = ep[i] * eq[i] + lshiftz (res[i], 2);
01064 }
01065 return res;
01066 }
01067
01068 inline vector<Series>
01069 rec_square (const vector<Series>& p, const vector<Series>& y) {
01070 nat l= N(p);
01071 ASSERT ((l-2) == N(y), "Wrong size of arguments");
01072 Series ser_2 = integer_to_series_carry<M,V> (2);
01073 const Series& ep=p[0], ap=p[1];
01074 vector<Series> bp = range (p, 2, l);
01075 vector<Series> ry = as_vector (rshiftz (as_series (y)), N(y));
01076 vector<Series> lry = as_vector (lshiftz_series_vector
01077 (rshiftz (as_series (y)), l-2));
01078 Series tp = ap + dot (bp, lry);
01079 Series er = (square (ep) + ser_2 * lshiftz (tp * rshiftz (ep, 2), 2) +
01080 lshiftz (square (dot (bp, ry)), 2));
01081 return (vec<Series> (er, square (ap)) << (ser_2 * ap * bp));
01082 }
01083
01084 inline vector<Series>
01085 rec_lin (const Series& a, const vector<Series>& b) {
01086 return vec<Series> (Series (CF(a)), a) << b;
01087 }
01088
01089 inline vector<Series>
01090 rec_cst (const Series& p, nat n) {
01091 return rec_lin (p, vector<Series> (Series (CF(p)), n));
01092 }
01093
01094
01095 static Series
01096 _ev_der (const generic& f, const vector<Series>& a,
01097 const vector<generic>& x, vector<Series>& grad) {
01098 grad = vector<Series> (Series (get_format1 (CF(a))), N(a));
01099 if (is<literal> (f))
01100 for (nat i = 0; i < N(a); i++)
01101 if (f == x[i]) {
01102 grad[i]= Series (M(1));
01103 return a[i];
01104 }
01105 if (is<Series> (f))
01106 return as<Series> (f);
01107 if (is<compound> (f)) {
01108 Series o;
01109 if (N(f) == 2) {
01110 if (f[0] == GEN_MINUS) {
01111 o = -_ev_der (f[1], a, x, grad);
01112 grad = -grad;
01113 return o;
01114 }
01115 if (f[0] == GEN_SQUARE) {
01116 o = _ev_der (f[1], a, x, grad);
01117 Series ser_2= integer_to_series_carry<M,V> (2);
01118 grad = ser_2 * o * grad;
01119 return square (o);
01120 }
01121 }
01122 if (N(f) == 3) {
01123 vector<Series> grad2;
01124 if (f[0] == GEN_MINUS) {
01125 o = _ev_der (f[1], a, x, grad) - _ev_der (f[2], a, x, grad2);
01126 grad = grad - grad2;
01127 return o;
01128 }
01129 if (f[0] == GEN_PLUS) {
01130 o = _ev_der (f[1], a, x, grad) + _ev_der (f[2], a, x, grad2);
01131 grad = grad + grad2;
01132 return o;
01133 }
01134 if (f[0] == GEN_TIMES) {
01135 o = _ev_der (f[1], a, x, grad);
01136 Series o2 = _ev_der (f[2], a, x, grad2);
01137 grad = o*grad2 + grad*o2;
01138 return o*o2;
01139 } } }
01140 ERROR ("bug, unexpected type with generic"); }
01141
01142 static Series_vector
01143 _ev_der (const vector<generic>& f, const vector<Series>& a,
01144 const vector<generic>& x, matrix<Series, matrix_naive>& m) {
01145 m = matrix<Series, matrix_naive> (Series (get_format1 (CF(a))),
01146 N(f), N(a));
01147 vector<Series> v (Series (get_format1 (CF(a))), N(f));
01148 vector<Series> grad;
01149 for (nat i = 0; i < N(f); i++) {
01150 v[i] = _ev_der (f[i], a, x, grad);
01151 for (nat j = 0; j < N(a); j++)
01152 m (i,j) = grad [j];
01153 }
01154 return as_series (v); }
01155
01156 vector<Series>
01157 _eps (const generic& f, const vector<generic>& x, const Series_vector& y) {
01158 nat n = N(x);
01159 if (is<Series> (f))
01160 return rec_cst (as<Series> (f), n);
01161 if (is<literal> (f)) {
01162 for (nat i = 0; i < n; i++)
01163 if (f == x[i]) {
01164 vector<Series> tmp (Series (M(0) ), n);
01165 tmp [i] = Series (M(1));
01166 return rec_lin (Series (y0[i]), tmp);
01167 }
01168 }
01169 if (is<compound> (f)) {
01170 if (N(f) == 2) {
01171 if (f[0] == GEN_MINUS)
01172 return rec_minus (_eps (f[1], x, y));
01173 if (f[0] == GEN_SQUARE)
01174 return rec_square (_eps (f[1], x, y), as_vector (y));
01175 }
01176 if (N(f) == 3) {
01177 if (f[0] == GEN_MINUS)
01178 return rec_minus (_eps (f[1], x, y), _eps (f[2], x, y));
01179 if (f[0] == GEN_PLUS)
01180 return rec_add (_eps (f[1], x, y), _eps (f[2], x, y));
01181 if (f[0] == GEN_TIMES)
01182 return rec_prod (_eps (f[1], x, y), _eps (f[2], x, y),
01183 as_vector (y));
01184 }
01185 }
01186 ERROR ("bug, unexpected type with generic"); }
01187
01188 vector<Series>
01189 _eps (const vector<generic>& e, const vector<generic>& x,
01190 const Series_vector& y) {
01191 vector<Series> veps (Series (M(0) ), N(e));
01192 for (nat i = 0; i < N(e); i++) veps [i] = _eps (e[i], x, y)[0];
01193 return veps;
01194 }
01195
01196 static void
01197 increase_order_generic (generic f, nat l) {
01198 if (is<Series> (f))
01199 increase_order (as<Series> (f), l);
01200 if (is<compound> (f)) {
01201 if (N(f) == 2)
01202 increase_order_generic (f[1], l);
01203 if (N(f) == 3) {
01204 increase_order_generic (f[1], l);
01205 increase_order_generic (f[2], l);
01206 }
01207 }
01208 }
01209
01210 static inline void
01211 increase_order_generic (vector<generic> f, nat l) {
01212 for (nat i = 0; i < N(f); i++)
01213 increase_order_generic (f[i], l);
01214 }
01215
01216
01217 public:
01218 slp_polynomial_system_regular_root_series_rep (const vector<generic>& out2,
01219 const vector<generic>& vars2,
01220 const Vector& y02):
01221 recursive_series_rep<Vector,V> (get_format (y02)),
01222 out (out2), vars (vars2), y0 (y02) {}
01223 syntactic expression (const syntactic& z) const {
01224 return z; }
01225
01226 virtual void Increase_order (nat l) {
01227 recursive_series_rep<Vector,V>::Increase_order (l);
01228 increase_order_generic (out, l); }
01229 Series_vector initialize () {
01230
01231
01232
01233 nat n= N(out);
01234 ASSERT (N(vars) == n, "numbers of equations and variables don't match");
01235 this->initial (0) = y0;
01236 matrix<Series, matrix_naive> jac;
01237 vector<Series> num = as_vector (_ev_der (out, as<vector<Series> > (y0),
01238 vars, jac));
01239
01240
01241 vector<Series> eps = _eps (out, vars, this->me());
01242
01243
01244 Series_vector res = ldiv (jac, (jac * as<vector<Series> > (y0)
01245 - num - eps));
01246
01247
01248 return res;
01249 }
01250 };
01251
01252 TMPL static inline vector<Series>
01253 slp_polynomial_system_regular_root_series (const vector<generic>& f,
01254 const vector<generic>& x,
01255 const Vector& y0) {
01256 typedef slp_polynomial_system_regular_root_series_rep<M,V> Sys_root_rep;
01257 Series_vector s= (series_rep<Vector,V>*) new Sys_root_rep (f, x, y0);
01258 return as_vector (recursive(s));
01259 }
01260 #endif
01261
01262
01263 #undef Series_vector_rep
01264 #undef Series_matrix_rep
01265 #undef Vector
01266 #undef Series_vector
01267 #undef Vector_series
01268 #undef Series_matrix
01269 #undef Matrix_series
01270 #undef Matrix
01271 #undef Series
01272 #undef Series_rep
01273 #undef C
01274 #undef TMPL
01275 }
01276 #endif // __MMX_SERIES_CARRY_LINEAR_ALGEBRA_HHP