algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/polynomial_schonhage.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : polynomial_schonhage.hpp
00004 * DESCRIPTION: Fast product for any ring with unity
00005 * COPYRIGHT  : (C) 2008  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 // Ref. "Modern Computer Algebra", Chapter 8, Exercise 8.30.
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 * Variant for Schonhage multiplication
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 * Multiplication
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 }; // implementation<polynomial_multiply,V,polynomial_schonhage_inc<W,Th,Th_rec> >
00104 
00105 /******************************************************************************
00106 * Schonhage Strassen multiplication for generic coefficients
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 } // namespace mmx
00140 #endif //__MMX__POLYNOMIAL_SCHONHAGE__HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines