algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/polynomial_series.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines