algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : polynomial_series.hpp 00004 * DESCRIPTION: Polynomials over power series numbers 00005 * COPYRIGHT : (C) 2009 Gregoire Lecerf 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_POLYNOMIAL_SERIES_HPP 00014 #define __MMX_POLYNOMIAL_SERIES_HPP 00015 #include <algebramix/series.hpp> 00016 #include <algebramix/series_vector.hpp> 00017 #include <algebramix/polynomial.hpp> 00018 #include <algebramix/polynomial_ring_dicho.hpp> 00019 00020 namespace mmx { 00021 #define TMPL template<typename C, typename U, typename V, typename W> 00022 #define Series series<C,V> 00023 #define Series_vector series <vector<C,W> > 00024 #define Series_vector_rep series_rep <vector<C,W> > 00025 #define Recursive_series_vector_rep recursive_series_rep<vector<C,W> > 00026 #define Polynomial polynomial<Series,U> 00027 00028 /****************************************************************************** 00029 * Variants 00030 ******************************************************************************/ 00031 00032 template<typename V> 00033 struct polynomial_series: public V { 00034 typedef typename V::Vec Vec; 00035 typedef typename V::Naive Naive; 00036 typedef polynomial_series<typename V::Positive> Positive; 00037 typedef polynomial_series<typename V::No_simd> No_simd; 00038 typedef polynomial_series<typename V::No_thread> No_thread; 00039 typedef polynomial_series<typename V::No_scaled> No_scaled; 00040 }; 00041 00042 template<typename F, typename V, typename W> 00043 struct implementation<F,V,polynomial_series<W> >: 00044 public implementation<F,V,W> {}; 00045 00046 DEFINE_VARIANT (polynomial_series_dicho, 00047 polynomial_series< 00048 polynomial_dicho< 00049 polynomial_naive> >) 00050 00051 template<typename C, typename V> 00052 struct polynomial_variant_helper<Series> { 00053 typedef polynomial_series_dicho PV; 00054 }; 00055 00056 /****************************************************************************** 00057 * Modular inversion 00058 ******************************************************************************/ 00059 00060 template<typename X, typename BV> 00061 struct implementation<polynomial_gcd,X,polynomial_series<BV> >: 00062 public implementation<polynomial_gcd,X,BV> { 00063 00064 typedef implementation<polynomial_gcd,X,BV> Pol; 00065 00066 TMPL 00067 class inv_mod_polynomial_series_rep: public Recursive_series_vector_rep { 00068 00069 public: 00070 const Polynomial a, b; // inverse of a mod b 00071 00072 inv_mod_polynomial_series_rep (const Polynomial& a2, 00073 const Polynomial& b2): a (a2), b (b2) {} 00074 virtual void Increase_order (nat l) { 00075 Recursive_series_vector_rep::Increase_order (l); } 00076 syntactic expression (const syntactic& z) const { 00077 return flatten (1) / flatten (a); } 00078 Series_vector initialize () { 00079 VERIFY (N(b) > 0, "unexpected zero polynomial"); 00080 polynomial<C> a0 (as<polynomial<C> > (a)), b0 (as<polynomial<C> > (b)); 00081 polynomial<C> u= invert_modulo (a0, b0); 00082 if (u == 0) return Series_vector (); 00083 nat n= N(b) - 1; 00084 Polynomial c (rem (a * as<Polynomial> (u) - 1, b)); 00085 vector<Series> w= coefficients (c, 0, n); 00086 w= as_vector<C,V,W> (rshiftz (Series_vector (w),1),n); 00087 c= rem (Polynomial (w) 00088 * Polynomial (as_vector<C,V,W> (this->me (), n)), b); 00089 w= coefficients (c, 0, n); 00090 w= as_vector<C,V,W> (lshiftz (Series_vector (w),1), n); 00091 c= as<Polynomial> (u) - Polynomial (w); 00092 return coefficients (c, 0, n); } 00093 }; 00094 00095 TMPL static inline Series_vector 00096 inv_mod_polynomial_series (const Polynomial& a, const Polynomial &b) { 00097 Series_vector_rep* rep= new inv_mod_polynomial_series_rep<C,U,V,W> (a, b); 00098 return recursive_vector (Series_vector (rep)); } 00099 00100 template<typename C, typename U, typename V> static Polynomial 00101 invert_mod (const Polynomial& a, const Polynomial& b) { 00102 typedef typename Vector_variant(C) W; 00103 Series_vector v= inv_mod_polynomial_series<C,U,V,W> (a, b); 00104 if (b == 0) { 00105 if (deg (a) != 0) return 0; 00106 return 1 / a[0]; 00107 } 00108 vector<Series> tmp= as_vector (v, N(b) - 1); 00109 return Polynomial (tmp); } 00110 00111 }; // implementation<polynomial_gcd,X,polynomial_series<BV> > 00112 00113 #undef TMPL 00114 #undef Series 00115 #undef Series_vector 00116 #undef Series_vector_rep 00117 #undef Recursive_series_vector_rep 00118 #undef Polynomial 00119 } // namespace mmx 00120 #endif // __MMX_POLYNOMIAL_SERIES_HPP