00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __MMX__POLYNOMIAL_SCHONHAGE__HPP
00016 #define __MMX__POLYNOMIAL_SCHONHAGE__HPP
00017 #include <numerix/modulus.hpp>
00018 #include <algebramix/polynomial_dicho.hpp>
00019 #include <algebramix/polynomial_schonhage_strassen.hpp>
00020 #include <algebramix/polynomial_schonhage_triadic.hpp>
00021
00022 namespace mmx {
00023 #define TMPL template<typename C>
00024
00025
00026
00027
00028
00029 struct schonhage_threshold {};
00030 struct schonhage_internal_threshold {};
00031
00032 template<typename V,
00033 typename Th1= schonhage_threshold,
00034 typename Th2= schonhage_internal_threshold>
00035 struct polynomial_schonhage_inc: public V {
00036 typedef typename V::Vec Vec;
00037 typedef typename V::Naive Naive;
00038 typedef typename V::Positive Positive;
00039 typedef polynomial_schonhage_inc<typename V::No_simd,Th1,Th2> No_simd;
00040 typedef polynomial_schonhage_inc<typename V::No_thread,Th1,Th2> No_thread;
00041 typedef polynomial_schonhage_inc<typename V::No_scaled,Th1,Th2> No_scaled;
00042 };
00043
00044 template<typename F, typename V, typename W, typename Th1, typename Th2>
00045 struct implementation<F,V,polynomial_schonhage_inc<W,Th1,Th2> >:
00046 public implementation<F,V,W> {};
00047
00048 DEFINE_VARIANT_1 (typename V, V,
00049 polynomial_schonhage,
00050 polynomial_balanced_tft<
00051 polynomial_schonhage_inc<
00052 polynomial_karatsuba<V> > >)
00053
00054
00055
00056
00057
00058 template<typename V, typename W, typename Th, typename Th_rec>
00059 struct implementation<polynomial_multiply,V,
00060 polynomial_schonhage_inc<W,Th,Th_rec> >:
00061 public implementation<polynomial_linear,V>
00062 {
00063 typedef implementation<vector_linear,V> Vec;
00064 typedef implementation<polynomial_multiply,W> Fallback;
00065
00066 TMPL static inline void
00067 mul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00068 typedef polynomial_schonhage_strassen_inc<V,Th_rec> V2;
00069 typedef polynomial_schonhage_triadic_inc<V,Th_rec> V3;
00070 typedef implementation<polynomial_multiply,V2> Pol2;
00071 typedef implementation<polynomial_multiply,V3> Pol3;
00072 typedef modulus_int_naive<8*sizeof(nat)> MV;
00073 typedef modulus<nat, MV> Modulus;
00074 if (n1 < Threshold(C,Th) || n2 < Threshold(C,Th)) {
00075 Fallback::mul (dest, s1, s2, n1, n2);
00076 return;
00077 }
00078 nat n = n1 + n2 - 1;
00079 nat l = aligned_size<C,V> (n);
00080 C* temp = mmx_new<C> (l);
00081 nat k2= Pol2::mul (dest, s1, s2, n1, n2, false);
00082 if (k2 == 0) return;
00083 nat k3= Pol3::mul (temp, s1, s2, n1, n2, false);
00084 if (k3 == 0) {
00085 Vec::copy (dest, temp, n);
00086 return;
00087 }
00088 nat u2, u3;
00089 nat c2= ((nat) 1) << k2, c3= binpow ((nat) 3, k3);
00090 MV::inv_mod (u2, binpow ((nat) 2, k2), Modulus (c3));
00091 MV::inv_mod (u3, binpow ((nat) 3, k3), Modulus (c2));
00092 u3= c2 - u3;
00093 VERIFY (u2*c2 - u3*c3 == 1, "bug");
00094 Vec::mul (dest, C(u2), n);
00095 Vec::mul (temp, C(u3), n);
00096 Vec::sub (dest, temp , n);
00097 mmx_delete<C> (temp, l); }
00098
00099 TMPL static inline void
00100 square (C* dest, const C* s1, nat n1) {
00101 mul (dest, s1, s1, n1, n1); }
00102
00103 };
00104
00105
00106
00107
00108
00109 DEFINE_VARIANT (polynomial_generic_schonhage,
00110 polynomial_ring_dicho<
00111 polynomial_schonhage<
00112 polynomial_ring_naive<
00113 polynomial_naive> > >)
00114
00115 STMPL
00116 struct threshold_helper<generic,
00117 polynomial_multiply_threshold<
00118 polynomial_generic_schonhage> > {
00119 typedef fixed_value<nat,16> impl;
00120 };
00121
00122 STMPL
00123 struct threshold_helper<generic, schonhage_threshold> {
00124 typedef fixed_value<nat,16384> impl;
00125 };
00126
00127 STMPL
00128 struct threshold_helper<generic, schonhage_internal_threshold> {
00129 typedef fixed_value<nat,128> impl;
00130 };
00131
00132 #define POLYNOMIAL_GENERIC_USES_SCHONHAGE \
00133 STMPL \
00134 struct polynomial_variant_helper<generic> { \
00135 typedef polynomial_generic_schonhage PV; \
00136 };
00137
00138 #undef TMPL
00139 }
00140 #endif //__MMX__POLYNOMIAL_SCHONHAGE__HPP