algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/series_matrix.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : series_matrix.hpp
00004 * DESCRIPTION: Vectors and matrices of univariate power series
00005 * COPYRIGHT  : (C) 2004  Joris van der Hoeven
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_MATRIX_HPP
00014 #define __MMX_SERIES_MATRIX_HPP
00015 #include <basix/vector.hpp>
00016 #include <algebramix/matrix.hpp>
00017 #include <algebramix/series.hpp>
00018 #include <algebramix/series_vector.hpp>
00019 
00020 namespace mmx {
00021 #define TMPL template<typename C, typename V, typename U>
00022 #define TMPLWU template<typename C, typename V, typename W, typename U>
00023 #define Series series<C,V>
00024 #define Matrix matrix<C,U>
00025 #define Series_rep series_rep<C,V>
00026 #define Series_matrix series<Matrix,V>
00027 #define Matrix_series matrix<Series,U>
00028 
00029 /******************************************************************************
00030 * Variant
00031 ******************************************************************************/
00032 
00033 template<typename C, typename V>
00034 struct series_variant_helper<matrix<C,V> > {
00035   typedef typename series_variant_helper<C>::SV SV;
00036 };
00037 
00038 /******************************************************************************
00039 * Matrices of series
00040 ******************************************************************************/
00041 
00042 STYPE_TO_TYPE(TMPL,as_matrix_type,Series_matrix,Matrix_series);
00043 
00044 TMPL
00045 class matrix_access_series_rep: public Series_rep {
00046   Series_matrix f;
00047   nat i, j;
00048 public:
00049   matrix_access_series_rep (const Series_matrix& f2, nat i2, nat j2):
00050     Series_rep (get_format1 (CF(f2))), f (f2), i (i2), j (j2) {}
00051   syntactic expression (const syntactic& z) const {
00052     return access (flatten (f, z), flatten (i), flatten (j)); }
00053   void Increase_order (nat l) {
00054     Series_rep::Increase_order (l);
00055     increase_order (f, l); }
00056   C next () { return f[this->n](i,j); }
00057 };
00058 
00059 TMPL Series
00060 access (const Series_matrix& f, nat i, nat j) {
00061   return (Series_rep*) new matrix_access_series_rep<C,V,U> (f, i, j);
00062 }
00063 
00064 TMPL Matrix_series
00065 as_matrix (const Series_matrix& f) {
00066   nat nr= rows (f[0]), nc= cols (f[0]);
00067   Matrix_series m (Series (0), nr, nc);
00068   for (nat i=0; i<nr; i++)
00069     for (nat j=0; j<nc; j++)
00070       m (i, j)= access (f, i, j);
00071   return m;
00072 }
00073 
00074 TMPL syntactic
00075 flatten (const Matrix_series& m, const syntactic& z) {
00076   syntactic g;
00077   nat i, j, nr= rows (m), nc= cols (m);
00078   matrix<syntactic,U> r (g, nr, nc);
00079   for (i=0; i<nr; i++)
00080     for (j=0; j<nc; j++)
00081       r (i, j)= flatten (m (i, j), z);
00082   return flatten (r);
00083 }
00084 
00085 TMPL format<Matrix >
00086 get_matrix_format (const Matrix_series& m) {
00087   format<Series > fm1= CF(m);
00088   format<C> fm2= get_format1 (fm1);
00089   C zero= promote (0, fm2);
00090   Matrix r (zero, rows (m), cols (m));
00091   return get_format (r);
00092 }
00093 
00094 TMPL
00095 class matrix_series_rep: public series_rep<Matrix,V> {
00096   const Matrix_series m;
00097 public:
00098   matrix_series_rep (const Matrix_series& m2):
00099     series_rep<Matrix,V> (get_matrix_format (m2)), m (m2) {}
00100   syntactic expression (const syntactic& z) const {
00101     return flatten (m, z); }
00102   void Increase_order (nat l) {
00103     series_rep<Matrix,V>::Increase_order (l);
00104     for (nat i=0; i<rows(m); i++)
00105       for (nat j=0; j<cols(m); j++)
00106         increase_order (m (i, j), l); }
00107   Matrix next () {
00108     nat i, j, nr= rows (m), nc= cols (m);
00109     Matrix coeff (C (0), nr, nc);
00110     for (i=0; i<nr; i++)
00111       for (j=0; j<nc; j++)
00112         coeff (i, j)= m (i, j) [this->n];
00113     return coeff; }
00114 };
00115 
00116 TMPL Series_matrix
00117 as_series (const Matrix_series& m) {
00118   return (series_rep<Matrix,V>*) new matrix_series_rep<C,V,U> (m);
00119 }
00120 
00121 TMPL Series_matrix
00122 from_matrix (const Matrix_series& m) {
00123   return (series_rep<Matrix,V>*) new matrix_series_rep<C,V,U> (m);
00124 }
00125 
00126 TMPL
00127 class lshiftz_series_matrix_rep: public series_rep<Matrix,V> {
00128   const Series_matrix f;
00129   const nat r,c;
00130   const int shift;
00131 public:
00132   lshiftz_series_matrix_rep (const Series_matrix& f2, nat r2, nat c2,
00133                              int shift2):
00134     series_rep<Matrix,V> (CF(f2)),
00135     f (f2),  r (r2), c (c2), shift (shift2) {}
00136   syntactic expression (const syntactic& z) const {
00137     return lshiftz (flatten (f, z), flatten (shift)); }
00138   void Increase_order (nat l) {
00139     series_rep<Matrix,V>::Increase_order (l);
00140     increase_order (f, max (0, ((int) l) - shift)); }
00141   Matrix next () { return shift > ((int) this->n)? 
00142       Matrix (C (), r, c): f[this->n - shift]; }
00143 };
00144 
00145 TMPL inline Series_matrix
00146 lshiftz_series_matrix (const Series_matrix& f, const nat& r, const nat& c,
00147                        const int& shift=1) {
00148   if (is_exact_zero (f)) {
00149     Series zero (get_format1 (CF(f)));
00150     return as_series (Matrix_series (zero, r, c));
00151   }
00152   return (series_rep<Matrix,V>*) 
00153     new lshiftz_series_matrix_rep<C,V,U> (f, r, c, shift);
00154 }
00155 
00156 /******************************************************************************
00157 * Linear differential matrix equations
00158 ******************************************************************************/
00159 
00160 TMPL Series_matrix
00161 solve_matrix_lde_init (const Series_matrix& f, const Matrix& c) {
00162   return unary_recursive_series<solve_matrix_lde_op> (f, c);
00163 }
00164 
00165 TMPL Matrix_series
00166 solve_lde (const Matrix_series& f) {
00167   ASSERT (is_square_matrix (f), "square matrix expected");
00168   Matrix c (C(1), rows (f), cols (f));
00169   return as_matrix (solve_matrix_lde_init (as_series (f), c));
00170 }
00171 
00172 TMPL Matrix_series
00173 solve_lde_init (const Matrix_series& f, const Matrix& c) {
00174   ASSERT (is_square_matrix (f), "square matrix expected");
00175   ASSERT (rows (f) == rows (c), "unequal matrix dimensions");
00176   return as_matrix (solve_matrix_lde_init (as_series (f), c));
00177 }
00178 
00179 
00180 
00181 /******************************************************************************
00182 * Matrix equations resolution
00183 ******************************************************************************/
00184 
00185 #define D       typename C::C
00186 
00187 template<typename C,typename V,typename U,typename UU>
00188 static inline Matrix_series
00189 matrix_mul_nocarry (const matrix<C,UU>& mat, const Matrix_series& m) {
00190   typedef typename Series_variant(D) SV;
00191   return as<Matrix_series> (as<matrix<series<C,SV>, U> > (mat) * 
00192                             as<matrix<series<C,SV>, U> > (m));
00193 }
00194 
00195 template<typename C,typename V,typename U,typename UU>
00196 static Matrix_series
00197 matrix_mul_quo (const matrix<C,UU>& Mat, const Matrix_series& ma) {
00198   Matrix mat= as<Matrix> (Mat);
00199   nat m= rows(mat), n= cols(mat);
00200   ASSERT (rows(ma) == n, "sizes don't match");
00201   if (is_a_scalar (mat)) return as<Series> (mat.scalar()) * ma;
00202   ASSERT (is_non_scalar (ma), "non-scalar matrix expected");
00203   Series zero (CF(Mat));
00204   Matrix_series w (zero, m, cols(ma));
00205   Series mr, mq, c, ar, aq;
00206   for (nat k=0; k < m; k++) 
00207     for (nat j=0; j < cols(ma); j++) {
00208       mr = carry_mul_rem_series (mat(k,0), ma(0,j), mq);
00209       c  = mq;
00210       ar = mr;
00211       for (nat l=1; l < n; l++) {
00212         if (is_exact_zero (mat (k,l))) {
00213           mr = zero;
00214           mq = zero;
00215           aq = zero;
00216           continue;
00217         }
00218         mr = carry_mul_rem_series (mat(k,l), ma(l,j), mq);
00219         ar = carry_add_rem (ar, mr, aq);
00220         c  = carry_special_add (c, mq, aq);  
00221       }
00222       w(k,j) = c;
00223     }
00224   return w;
00225 }
00226 
00227 
00228 template<typename C,typename V,typename U,typename UU>
00229 class ldiv_sc_mat_mat_series_rep: public recursive_series_rep<Matrix,V> {
00230 protected:
00231   Matrix_series f;
00232   Matrix c;
00233 public:
00234   ldiv_sc_mat_mat_series_rep (const matrix<C,UU>& c2, const Matrix_series& f2):
00235     recursive_series_rep<Matrix,V> (get_matrix_format (f2)),
00236     f (f2), c (as<Matrix> (c2)) {}
00237   syntactic expression (const syntactic& z) const {
00238     return invert (flatten (c)) * flatten (f,z); }
00239   virtual void Increase_order (nat l) {
00240     recursive_series_rep<Matrix,V>::Increase_order (l);
00241     for (nat i = 0; i < rows(f); i++)
00242       for (nat j = 0; j < cols(f); j++)
00243         increase_order (f(i,j),l);
00244   }
00245   Series_matrix initialize () {
00246     Matrix u= invert (c);
00247     this->initial (0)= u * as_series (f)[0];
00248     Series_matrix ls_me = lshiftz_series_matrix (this -> me (),
00249                                                  cols(c), cols(f));
00250     Matrix_series tmp= f - matrix_mul_quo (c, as_matrix (ls_me));
00251     return as_series (matrix_mul_nocarry (u, tmp));
00252   }
00253 };
00254 
00255 template<typename C,typename V,typename U,typename UU> 
00256 static inline Matrix_series
00257 ser_ldiv_sc_mat_mat (const matrix<C,UU>& c, const Matrix_series& f) {
00258   typedef ldiv_sc_mat_mat_series_rep<C,V,U,UU> Div_sc_mat_mat_rep;
00259   if (is_exact_zero (as_series (f))) {
00260     Series zero (get_format1 (CF(f)));
00261     return Matrix_series (zero, cols(c), cols(f));
00262   }
00263   Series_matrix s = (series_rep<Matrix,V>*) new Div_sc_mat_mat_rep (c,f);
00264   return as_matrix (recursive (s));
00265 }
00266 
00267 TMPL
00268 class ldiv_mat_mat_series_rep: public recursive_series_rep<Matrix,V> {
00269 protected:
00270   Matrix_series f;
00271   Matrix_series mat;
00272 public:
00273   ldiv_mat_mat_series_rep (const Matrix_series& mat2, const Matrix_series& f2):
00274     recursive_series_rep<Matrix,V> (get_matrix_format (mat2)),
00275     f(f2), mat(mat2) {}
00276   syntactic expression (const syntactic& z) const {
00277     return invert (flatten (mat)) * flatten (f,z); }
00278   virtual void Increase_order (nat l) {
00279     recursive_series_rep<Matrix,V>::Increase_order (l);
00280     for (nat i = 0; i < rows(f); i++) {
00281       for (nat j = 0; j < cols(f); j++)
00282         increase_order (f(i,j),l);
00283       for (nat j = 0; j < cols(mat); j++)
00284         increase_order (mat(i,j),l);
00285     }
00286   }
00287   Series_matrix initialize () {
00288     Series_matrix smat = as_series (mat);
00289     //matrix<C> smat0 = smat[0]; 
00290     //this->initial (0)= invert (smat0) * ((matrix<C>) as_series (f)[0]);
00291     this->initial (0)= invert (smat[0]) * as_series (f)[0];
00292     Matrix_series ma = f - 
00293       as_matrix (lshiftz_series_matrix (as_series (as_matrix (rshiftz (smat))*
00294                                                    as_matrix (this-> me ())),
00295                                         cols(mat), cols(f)));
00296     return as_series (ser_ldiv_sc_mat_mat (smat[0], ma));
00297   }
00298 };
00299 
00300 TMPL static inline Matrix_series
00301 ser_ldiv_mat_mat (const Matrix_series& mat, const Matrix_series& f) {
00302   typedef ldiv_mat_mat_series_rep<C,V,U> Div_mat_rep;
00303   if (is_exact_zero (as_series (f))) {
00304     Series zero (get_format1 (CF(f)));
00305     return Matrix_series (zero, cols(mat), cols(f));
00306   }
00307   Series_matrix s = (series_rep<Matrix,V>*) new Div_mat_rep (mat,f);
00308   return as_matrix (recursive (s)); 
00309 }
00310 
00311 
00312 #undef D
00313 
00314 #undef Series_matrix
00315 #undef Matrix_series
00316 #undef Matrix
00317 #undef Series
00318 #undef Series_rep
00319 #undef TMPLWU
00320 #undef TMPL
00321 } // namespace mmx
00322 #endif // __MMX_SERIES_MATRIX_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines