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