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