00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__POLYNOMIAL_BALANCED__HPP
00014 #define __MMX__POLYNOMIAL_BALANCED__HPP
00015
00016 namespace mmx {
00017 #define TMPL template<typename C>
00018
00019
00020
00021
00022
00023 template<typename V>
00024 struct polynomial_balanced: public V {
00025 typedef typename V::Vec Vec;
00026 typedef typename V::Naive Naive;
00027 typedef polynomial_balanced<typename V::Positive> Positive;
00028 typedef polynomial_balanced<typename V::No_simd> No_simd;
00029 typedef polynomial_balanced<typename V::No_thread> No_thread;
00030 typedef polynomial_balanced<typename V::No_scaled> No_scaled;
00031 };
00032
00033 template<typename F, typename V, typename W>
00034 struct implementation<F,V,polynomial_balanced<W> >:
00035 public implementation<F,V,W> {};
00036
00037
00038
00039
00040
00041 template<typename V, typename W>
00042 struct implementation<polynomial_multiply,V,polynomial_balanced<W> >:
00043 public implementation<polynomial_linear,V>
00044 {
00045 typedef implementation<vector_linear,V> Vec;
00046 typedef implementation<polynomial_linear,W> Pol;
00047 typedef implementation<polynomial_multiply,W> Fallback;
00048
00049 TMPL static inline void
00050 mul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00051 if (n1 == 0 && n2 == 0)
00052 return;
00053 if (n1 == 0 || n2 == 0) {
00054 Pol::clear (dest, n1+n2-1);
00055 return;
00056 }
00057 if (n1 == n2) {
00058 Fallback::mul (dest, s1, s2, n1, n2);
00059 return;
00060 }
00061 nat n= n1+n2-1;
00062 Pol::clear (dest, n);
00063 if (n1 < n2) {
00064 nat l= aligned_size<C,V> (2*n1-1);
00065 C* temp= mmx_new<C> (l);
00066 while (n2 > 0) {
00067 nat n3= min (n1, n2);
00068 mul (temp, s1, s2, n1, n3);
00069 Vec::add (dest, temp, n1+n3-1);
00070 n2 -= n3; s2 += n3; dest += n3;
00071 }
00072 mmx_delete<C> (temp, l);
00073 }
00074 else {
00075 nat l= aligned_size<C,V> (2*n2-1);
00076 C* temp= mmx_new<C> (l);
00077 while (n1 > 0) {
00078 nat n3= min (n1, n2);
00079 mul (temp, s1, s2, n3, n2);
00080 Vec::add (dest, temp, n2+n3-1);
00081 n1 -= n3; s1 += n3; dest += n3;
00082 }
00083 mmx_delete<C> (temp, l);
00084 }
00085 }
00086
00087 TMPL static inline void
00088 square (C* dest, const C* s, nat n) {
00089 Fallback::square (dest, s, n);
00090 }
00091
00092 };
00093
00094 #undef TMPL
00095 }
00096 #endif //__MMX__POLYNOMIAL_BALANCED__HPP