00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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;
00071
00072 inv_mod_polynomial_series_rep (const Polynomial& a2,
00073 const Polynomial& b2) :
00074 Recursive_series_vector_rep (CF (b2)), a (a2), b (b2) {}
00075 virtual void Increase_order (nat l) {
00076 Recursive_series_vector_rep::Increase_order (l); }
00077 syntactic expression (const syntactic& z) const {
00078 return flatten (1) / flatten (a); }
00079 Series_vector initialize () {
00080 VERIFY (N(b) > 0, "unexpected zero polynomial");
00081 polynomial<C> a0, b0;
00082 vector<C> coeff (C (), N (a));
00083 for (nat i = 0; i < N (a); i++)
00084 coeff[i] = a[i][0];
00085 a0 = polynomial<C> (coeff);
00086 coeff = vector<C> (C (), N (b));
00087 for (nat i = 0; i < N (b); i++)
00088 coeff[i] = b[i][0];
00089 b0 = polynomial<C> (coeff);
00090 polynomial<C> u= invert_modulo (a0, b0);
00091 if (u == 0) return Series_vector ();
00092 nat n= N(b) - 1;
00093 Polynomial c (rem (a * as<Polynomial> (u) - 1, b));
00094 vector<Series> w= coefficients (c, 0, n);
00095 w= as_vector<C,V,W> (rshiftz (as_series (w),1),n);
00096 c= rem (Polynomial (w)
00097 * Polynomial (as_vector<C,V,W> (this->me (), n)), b);
00098 w= coefficients (c, 0, n);
00099 w= as_vector<C,V,W> (lshiftz (as_series (w),1), n);
00100 c= as<Polynomial> (u) - Polynomial (w);
00101 return as_series (coefficients (c, 0, n)); }
00102 };
00103
00104 TMPL static inline Series_vector
00105 inv_mod_polynomial_series (const Polynomial& a, const Polynomial &b) {
00106 Series_vector_rep* rep= new inv_mod_polynomial_series_rep<C,U,V,W> (a, b);
00107 return recursive (Series_vector (rep)); }
00108
00109 template<typename C, typename U, typename V> static Polynomial
00110 invert_mod (const Polynomial& a, const Polynomial& b) {
00111 typedef typename Vector_variant(C) W;
00112 Series_vector v= inv_mod_polynomial_series<C,U,V,W> (a, b);
00113 if (b == 0) {
00114 if (deg (a) != 0) return 0;
00115 return 1 / a[0];
00116 }
00117 vector<Series> tmp= as_vector (v, N(b) - 1);
00118 return Polynomial (tmp); }
00119
00120 };
00121
00122 #undef TMPL
00123 #undef Series
00124 #undef Series_vector
00125 #undef Series_vector_rep
00126 #undef Recursive_series_vector_rep
00127 #undef Polynomial
00128 }
00129 #endif // __MMX_POLYNOMIAL_SERIES_HPP