algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/series_vector.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : series_vector.hpp
00004 * DESCRIPTION: Vectors and matrices of univariate power series
00005 * COPYRIGHT  : (C) 2011  J. Berthomieu, J. van der Hoeven and R. 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_VECTOR_HPP
00014 #define __MMX_SERIES_VECTOR_HPP
00015 #include <basix/vector.hpp>
00016 #include <algebramix/series.hpp>
00017 #include <algebramix/matrix.hpp>
00018 #include <algebramix/series_matrix.hpp>
00019 
00020 namespace mmx {
00021 #define TMPL template<typename C, typename V, typename W>
00022 #define TMPLU template<typename C, typename V, typename U>
00023 #define TMPLWU template<typename C, typename V, typename W, typename U>
00024 #define Series series<C,V>
00025 #define Vector vector<C,W>
00026 #define Matrix matrix<C,U>
00027 #define Series_rep series_rep<C,V>
00028 #define Series_vector series<Vector,V>
00029 #define Vector_series vector<Series,W>
00030 #define Series_matrix series<Matrix,V>
00031 #define Matrix_series matrix<Series,U>
00032 
00033 /******************************************************************************
00034 * Variants
00035 ******************************************************************************/
00036 
00037 template<typename C, typename V>
00038 struct series_variant_helper<vector<C,V> > {
00039   typedef typename series_variant_helper<C>::SV SV;
00040 };
00041 
00042 /******************************************************************************
00043 * Vectors of series
00044 ******************************************************************************/
00045 
00046 STYPE_TO_TYPE(TMPL,as_vector_type,Series_vector,Vector_series);
00047 
00048 TMPL
00049 class vector_access_series_rep: public Series_rep {
00050   const Series_vector f;
00051   const nat i;
00052 public:
00053   vector_access_series_rep (const Series_vector& f2, nat i2):
00054     Series_rep (get_format1 (CF(f2))), f (f2), i (i2) {}
00055   syntactic expression (const syntactic& z) const {
00056     return access (flatten (f, z), flatten (i)); }
00057   void Increase_order (nat l) {
00058     Series_rep::Increase_order (l);
00059     increase_order (f, l); }
00060   C next () {
00061     if (is_a_scalar (f[this->n])) return C();
00062     return i < N(f[this->n]) ? f[this->n][i] : C(); }
00063 };
00064 
00065 TMPL Series
00066 access (const Series_vector& f, nat i) {
00067   return (Series_rep*) new vector_access_series_rep<C,V,W> (f, i);
00068 }
00069 
00070 TMPL Vector_series
00071 as_vector (const Series_vector& f, nat n) {
00072   Vector_series v (Series (get_format1 (CF(f))), n);
00073   for (nat i=0; i<n; i++)
00074     v[i]= access (f, i);
00075   return v;
00076 }
00077 
00078 TMPL inline Vector_series
00079 as_vector (const Series_vector& f) {
00080   return as_vector (f, N(f[0]));
00081 }
00082 
00083 TMPL syntactic
00084 flatten (const Vector_series& v, const syntactic& z) {
00085   syntactic g;
00086   nat i, n= N(v);
00087   vector<syntactic,W> r (g, n);
00088   for (i=0; i<n; i++)
00089     r[i]= flatten (v[i], z);
00090   return flatten (r);
00091 }
00092 
00093 TMPL format<Vector >
00094 get_vector_format (const Vector_series& v) {
00095   format<Series > fm1= CF(v);
00096   format<C> fm2= get_format1 (fm1);
00097   C zero= promote (0, fm2);
00098   Vector r (zero, N(v));
00099   return get_format (r);
00100 }
00101 
00102 TMPL
00103 class vector_series_rep: public series_rep<Vector,V> {
00104   const Vector_series v;
00105 public:
00106   vector_series_rep (const Vector_series& v2):
00107     series_rep<Vector,V> (get_vector_format (v2)), v (v2) {}
00108   syntactic expression (const syntactic& z) const {
00109     return flatten (v, z); }
00110   void Increase_order (nat l) {
00111     series_rep<Vector,V>::Increase_order (l);
00112     for (nat i=0; i<N(v); i++)
00113       increase_order (v[i], l); }
00114   Vector next () {
00115     nat i, n= N(v);
00116     Vector coeff (promote (0, get_format1 (CF(v))), n);
00117     for (i=0; i<n; i++)
00118       coeff[i]= v[i][this->n];
00119     return coeff; }
00120 };
00121 
00122 TMPL Series_vector
00123 as_series (const Vector_series& v) {
00124   return (series_rep<Vector,V>*) new vector_series_rep<C,V,W> (v);
00125 }
00126 
00127 TMPL Series_vector
00128 from_vector (const Vector_series& v) {
00129   return (series_rep<Vector,V>*) new vector_series_rep<C,V,W> (v);
00130 }
00131 
00132 TMPL
00133 class lshiftz_series_vector_rep: public series_rep<Vector,V> {
00134   Series_vector f;
00135   nat s;
00136   int shift;
00137 public:
00138   lshiftz_series_vector_rep (const Series_vector& f2, nat s2, int shift2):
00139     series_rep<Vector,V> (CF(f2)),
00140     f (f2), s (s2), shift (shift2) {}
00141   syntactic expression (const syntactic& z) const {
00142     return lshiftz (flatten (f, z), flatten (shift)); }
00143   void Increase_order (nat l) {
00144     series_rep<Vector,V>::Increase_order (l);
00145     increase_order (f, max (0, ((int) l) - shift)); }
00146   Vector next () { return shift > ((int) this->n)? 
00147       Vector (promote (0, get_format1 (CF(f))), s):
00148       f[this->n - shift]; }
00149 };
00150 
00151 TMPL inline Series_vector
00152 lshiftz_series_vector (const Series_vector& f, const nat& n,
00153                        const int& shift=1) {
00154   if (is_exact_zero (f)) {
00155     Series zero (get_format1 (CF(f)));
00156     return as_series (Vector_series (zero, n));
00157   }
00158   return (series_rep<Vector,V>*) 
00159     new lshiftz_series_vector_rep<C,V,W> (f, n, shift);
00160 }
00161 
00162 /******************************************************************************
00163 * Linear differential equations
00164 ******************************************************************************/
00165 
00166 TMPL Series_vector
00167 solve_vector_lde_init (const Series_vector& f, const Vector& c) {
00168   return unary_recursive_series<solve_vector_lde_op> (f, c);
00169 }
00170 
00171 TMPL Vector_series
00172 solve_lde_init (const Vector_series& f, const Vector& c) {
00173   return as_vector (solve_vector_lde_init (as_series (f), c));
00174 }
00175 
00176 TMPL Series // FIXME: obsolete
00177 solve_lde (const Vector_series& f, const Vector& c) {
00178   return read (solve_lde_init (f, c), 0);
00179 }
00180 
00181 /******************************************************************************
00182 * Linear equations resolution
00183 ******************************************************************************/
00184 #define D       typename C::C
00185 
00186 template<typename C, typename V, typename X>
00187 class carry_mul_quorem_series_rep: public series_rep<vector<C>,V> {
00188 protected:
00189   Series f;
00190   C x;
00191   D q;
00192 public:
00193   inline carry_mul_quorem_series_rep (const X& x2, const Series& f2):
00194     series_rep<vector<C>,V> (get_format (vec<C> (get_sample (CF(f2))))),
00195     f(f2), x (as<C> (x2)), q (0) {}
00196   syntactic expression (const syntactic& z) const {
00197     return apply (syntactic ("carry_mul_quorem"), flatten (f, z),
00198                   flatten (x)); }
00199   virtual void Increase_order (nat l) {
00200     series_rep<vector<C>,V>::Increase_order (l);
00201     increase_order (f, l); }
00202   virtual vector<C> next () {
00203     C r= C (rem (x.rep * f[this->n].rep, * C::get_modulus (), q));
00204     return vec<C> (C (q), r); }
00205 };
00206 
00207 template<typename C, typename V> static inline Series
00208 carry_mul_rem_series (const C& c, const Series& f, Series& q) {
00209   series<vector<C>,V> s= (series_rep<vector<C>,V> *)
00210     new carry_mul_quorem_series_rep<C,V,C> (c, f);
00211   vector<Series> v= as_vector (s);
00212   q= v[0];
00213   return v[1];
00214 }
00215 
00216 TMPLWU
00217 static inline Vector_series
00218 matrix_mul_nocarry (const Matrix& mat, const Vector_series& v) {
00219   typedef typename Series_variant(D) SV;
00220   return as<vector<Series, W> > (as<matrix<series<C,SV>, U> > (mat) * 
00221                                  as<vector<series<C,SV>, W> > (v));
00222 }
00223 
00224 template<typename C, typename V>
00225 class carry_add_quorem_series_rep: public series_rep<vector<C>,V> {
00226 protected:
00227   Series a, b;
00228   D r;
00229 public:
00230   inline carry_add_quorem_series_rep (const Series& a2, const Series& b2):
00231     series_rep<vector<C>,V> (get_format (vec<C> (get_sample (CF(a2))))),
00232     a(a2), b (b2), r (0) {}
00233   syntactic expression (const syntactic& z) const {
00234     return apply (syntactic ("carry_add_quorem"), flatten (a, z),
00235                   flatten (b,z)); }
00236   virtual void Increase_order (nat l) {
00237     series_rep<vector<C>,V>::Increase_order (l);
00238     increase_order (a, l);
00239     increase_order (b, l); }
00240   virtual vector<C> next () {
00241     D r = a[this->n].rep + b[this->n].rep;
00242     if (r < * C::get_modulus ())
00243       return vec<C> (C(0), C(r));
00244     return vec<C> (C(1), C(r- (* C::get_modulus ())) ); }
00245 };
00246 
00247 
00248 template<typename C, typename V> static inline Series
00249 carry_add_rem (const Series& a, const Series& b, Series& q) {
00250   series<vector<C>,V> s= (series_rep<vector<C>,V> *)
00251     new carry_add_quorem_series_rep<C,V> (a, b);
00252   vector<Series> v= as_vector (s);
00253   q= v[0];
00254   return v[1];
00255 }
00256 
00257 template<typename C, typename V>
00258 class carry_special_add_series_rep: public Series_rep {
00259 protected:
00260   Series a, b, c;
00261   D r;
00262 public:
00263   inline carry_special_add_series_rep (const Series& a2, const Series& b2,
00264                                        const Series& c2):
00265     Series_rep (CF(a2)), a(a2), b (b2), c (c2), r (0) {}
00266   syntactic expression (const syntactic& z) const {
00267     return apply (apply (syntactic ("carry_special_add"), flatten (a, z),
00268                          flatten (b,z)), flatten (c,z)); }
00269   virtual void Increase_order (nat l) {
00270     Series_rep::Increase_order (l);
00271     increase_order (a, l);
00272     increase_order (b, l);
00273     increase_order (c, l); }
00274   virtual C next () {
00275     D s = a[this->n].rep + b[this->n].rep + c[this->n].rep + r;
00276     if (s < * C::get_modulus ()) {
00277       r = 0;
00278       return C (s);
00279     }
00280     r = 1;
00281     return C(s - (* C::get_modulus ())); }
00282 };
00283 
00284 template<typename C, typename V> static inline Series
00285 carry_special_add (const Series& a, const Series& b, const Series& c) {
00286   return (Series_rep *) new carry_special_add_series_rep<C,V> (a, b, c);
00287 }
00288 
00289 
00290 TMPLWU
00291 static Vector_series
00292 matrix_mul_quo (const Matrix& mat, const Vector_series& v) {
00293   nat m= rows(mat), n= cols(mat);
00294   ASSERT (N(v) == n, "sizes don't match");
00295   if (is_a_scalar (mat)) return as<Series> (mat.scalar()) * v;
00296   ASSERT (is_non_scalar (v), "non-scalar vector expected");
00297   Series zero (get_format1 (CF(v)));
00298   Vector_series w (zero, m);
00299   Series mr, mq, c, ar, aq;
00300   for (nat k=0; k < m; k++) {
00301     mr = carry_mul_rem_series (mat(k,0), v[0], mq);
00302     c  = mq;
00303     ar = mr;
00304     for (nat l=1; l < n; l++) {
00305       if (mat (k,l) == C(0)) {
00306         mr = zero;
00307         mq = zero;
00308         aq = zero;
00309         continue;
00310       }
00311       mr = carry_mul_rem_series (mat(k,l), v[l], mq);
00312       ar = carry_add_rem (ar, mr, aq);
00313       c  = carry_special_add (c, mq, aq);  
00314     }
00315     w[k] = c;
00316   }
00317   return w;
00318 }
00319 
00320 
00321 TMPLWU
00322 class ldiv_sc_mat_series_rep: public recursive_series_rep<Vector,V> {
00323 protected:
00324   Vector_series f;
00325   Matrix c;
00326 public:
00327   ldiv_sc_mat_series_rep (const Matrix& c2, const Vector_series& f2):
00328     recursive_series_rep<Vector,V> (get_vector_format (f2)),
00329     f(f2), c(c2) {}
00330   syntactic expression (const syntactic& z) const {
00331     return invert (flatten (c)) * flatten (f,z); }
00332   virtual void Increase_order (nat l) {
00333     recursive_series_rep<Vector,V>::Increase_order (l);
00334     for (nat i = 0; i < N(f); i++)
00335       increase_order (f[i],l);
00336   }
00337   Series_vector initialize () {
00338     Matrix u= invert (c);
00339     this->initial (0)= u * as_series (f)[0];
00340     Series_vector ls_me = lshiftz_series_vector (this -> me (), N(f));
00341     Vector_series tmp= f - matrix_mul_quo (c, as_vector (ls_me));
00342     return as_series (matrix_mul_nocarry (u, tmp));
00343   }
00344 };
00345 
00346 
00347 TMPLWU static inline Vector_series
00348 ser_ldiv_sc_mat (const Matrix& c, const Vector_series& f) {
00349   typedef ldiv_sc_mat_series_rep<C,V,W,U> Div_sc_mat_rep;
00350   if (is_exact_zero (as_series (f)))
00351     return Vector_series (Series (CF(c)), cols(c));
00352   Series_vector s = (series_rep<Vector,V>*) new Div_sc_mat_rep (c,f);
00353   return as_vector (recursive (s)); 
00354 }
00355 
00356 
00357 
00358 TMPLWU
00359 class ldiv_mat_series_rep: public recursive_series_rep<Vector,V> {
00360 protected:
00361   Vector_series f;
00362   Matrix_series mat;
00363 public:
00364   ldiv_mat_series_rep (const Matrix_series& mat2, const Vector_series& f2):
00365     recursive_series_rep<Vector,V> (get_vector_format (f2)),
00366     f(f2), mat(mat2) {}
00367   syntactic expression (const syntactic& z) const {
00368     return invert (flatten (mat)) * flatten (f,z); }
00369   virtual void Increase_order (nat l) {
00370     recursive_series_rep<Vector,V>::Increase_order (l);
00371     for (nat i = 0; i < N(f); i++) {
00372       increase_order (f[i],l);
00373       for (nat j = 0; j < cols(mat); j++)
00374         increase_order (mat(i,j),l);
00375     }
00376   }
00377   Series_vector initialize () {
00378     Series_matrix smat = as_series (mat);
00379     //TODO create a matrix variant helper for Matrix_series
00380     //matrix<C> smat0 = smat[0]; 
00381     this->initial (0)= invert (smat[0]) * as_series (f)[0];
00382     
00383     Vector_series v = f - 
00384       as_vector (lshiftz_series_vector (as_series (as_matrix (rshiftz (smat))*
00385                                                    as_vector (this-> me ())),
00386                                         N(f)));
00387     //Conversions series <-> vector, matrix dues à
00388     //-produit matrice vecteur prend en entrée matrix, vector
00389     //-rshiftz sur une matrice prend en entrée series
00390     //-appel à ser_ldiv_sc_smat prend en entrée matrix, vector
00391     return as_series (ser_ldiv_sc_mat (smat[0], v));
00392     /* Pour essayer de simplifier l'appel à ser_ldiv_sc_mat
00393     typedef ldiv_sc_mat_series_rep<C,V,W,matrix_naive> Div_sc_mat_rep;
00394     Series_vector s = (series_rep<Vector,V>*) Div_sc_mat_rep (smat0, v);
00395     return s; */
00396   }
00397 };
00398 
00399 TMPLWU static inline Vector_series
00400 ser_ldiv_mat (const Matrix_series& mat, const Vector_series& f) {
00401   typedef ldiv_mat_series_rep<C,V,W,U> Div_mat_rep;
00402   if (is_exact_zero (as_series (f))) {
00403     Series zero (get_format1 (CF(mat)));
00404     return Vector_series (zero, cols(mat));
00405   }
00406   Series_vector s = (series_rep<Vector,V>*) new Div_mat_rep (mat,f);
00407   return as_vector (recursive (s)); 
00408 }
00409 
00410 #undef D
00411 
00412 #undef Series_matrix
00413 #undef Matrix_series
00414 #undef Vector_series
00415 #undef Series_vector
00416 #undef Vector
00417 #undef Matrix
00418 #undef Series
00419 #undef Series_rep
00420 #undef TMPLWU
00421 #undef TMPLU
00422 #undef TMPL
00423 } // namespace mmx
00424 #endif // __MMX_SERIES_VECTOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines