00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_POLYNOMIAL_MODULAR_HPP
00014 #define __MMX_POLYNOMIAL_MODULAR_HPP
00015 #include <algebramix/polynomial_dicho.hpp>
00016
00017 namespace mmx {
00018 #define TMPL template<typename I, typename MoV, typename MaV>
00019 #define M modular<modulus<I, MoV>, MaV>
00020 #define C Lift_type(M)
00021
00022
00023
00024
00025
00026 template<typename V>
00027 struct polynomial_modular: public V {
00028 typedef typename V::Vec Vec;
00029 typedef typename V::Naive Naive;
00030 typedef typename V::Positive Positive;
00031 typedef polynomial_modular<typename V::No_simd> No_simd;
00032 typedef polynomial_modular<typename V::No_thread> No_thread;
00033 typedef polynomial_modular<typename V::No_scaled> No_scaled;
00034 };
00035
00036 template<typename F, typename V, typename W>
00037 struct implementation<F,V,polynomial_modular<W> >:
00038 public implementation<F,V,W> {};
00039
00040 template<typename F, typename V, typename W>
00041 struct polynomial_variant_helper<modular<modulus<F,V>, W> > {
00042 typedef polynomial_modular<polynomial_dicho<polynomial_naive> > PV;
00043 };
00044
00045
00046
00047
00048
00049 template<typename V, typename W>
00050 struct implementation<polynomial_multiply,V,polynomial_modular<W> >:
00051 public implementation<polynomial_linear,V>
00052 {
00053 typedef implementation<polynomial_multiply,W> Fallback;
00054
00055 template<typename K> static inline void
00056 mul (K* dest, const K* s1, const K* s2, nat n1, nat n2) {
00057 Fallback::mul (dest, s1, s2, n1, n2);
00058 }
00059
00060 template<typename K> static inline void
00061 square (K* dest, const K* s1, nat n1) {
00062 Fallback::square (dest, s1, n1);
00063 }
00064
00065 TMPL static inline void
00066 mul (M* dest, const M* s1, const M* s2, nat n1, nat n2) {
00067 typedef typename Polynomial_variant (C) CV;
00068 typedef implementation<vector_linear,CV> Vec_C;
00069 typedef implementation<polynomial_multiply,CV> Pol_C;
00070
00071 nat nd = n1 + n2 - 1;
00072 nat spc1= aligned_size<C,CV> (n1);
00073 nat spc2= aligned_size<C,CV> (n2);
00074 nat spcd= aligned_size<C,CV> (nd);
00075 nat spc = spc1 + spc2 + spcd;
00076 C* x1= mmx_new<C> (spc);
00077 C* x2= x1 + spc1;
00078 C* xd= x2 + spc2;
00079 Vec_C::template vec_unary<lift_op> (x1, s1, n1);
00080 Vec_C::template vec_unary<lift_op> (x2, s2, n2);
00081 Pol_C::mul (xd, x1, x2, n1, n2);
00082 Vec_C::template vec_unary<project_op> (dest, xd, nd);
00083 mmx_delete<C> (x1, spc);
00084 }
00085
00086 TMPL static inline void
00087 square (M* dest, const M* s1, nat n1) {
00088 typedef typename Polynomial_variant (C) CV;
00089 typedef implementation<vector_linear,CV> Vec_C;
00090 typedef implementation<polynomial_multiply,CV> Pol_C;
00091
00092 nat nd = n1 + n1 - 1;
00093 nat spc1= aligned_size<C,CV> (n1);
00094 nat spcd= aligned_size<C,CV> (nd);
00095 nat spc = spc1 + spcd;
00096 C* x1= mmx_new<C> (spc);
00097 C* xd= x1 + spc1;
00098 Vec_C::template vec_unary<lift_op> (x1, s1, n1);
00099 Pol_C::square (xd, x1, n1);
00100 Vec_C::template vec_unary<project_op> (dest, xd, nd);
00101 mmx_delete<C> (x1, spc);
00102 }
00103
00104 };
00105
00106 #undef TMPL
00107 #undef M
00108 #undef C
00109
00110 }
00111 #endif // __MMX_POLYNOMIAL_MODULAR_HPP