algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : polynomial_tangent.hpp 00004 * DESCRIPTION: Multiplication of polynomials with order one jet coefficients 00005 * COPYRIGHT : (C) 2008 Joris van der Hoeven 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 #ifndef __MMX__POLYNOMIAL_TANGENT__HPP 00014 #define __MMX__POLYNOMIAL_TANGENT__HPP 00015 #include <algebramix/polynomial.hpp> 00016 #include <algebramix/polynomial_dicho.hpp> 00017 #include <numerix/tangent.hpp> 00018 00019 namespace mmx { 00020 #define TMPL template<typename C> 00021 00022 /****************************************************************************** 00023 * Default variant for tangent coefficients 00024 ******************************************************************************/ 00025 00026 template<typename V> 00027 struct polynomial_tangent { 00028 typedef typename V::Vec Vec; 00029 typedef typename V::Naive Naive; 00030 typedef polynomial_tangent<typename V::Positive> Positive; 00031 typedef polynomial_tangent<typename V::No_simd> No_simd; 00032 typedef polynomial_tangent<typename V::No_thread> No_thread; 00033 typedef polynomial_tangent<typename V::No_scaled> No_scaled; 00034 }; 00035 00036 template<typename F, typename V, typename W> 00037 struct implementation<F,V,polynomial_tangent<W> >: 00038 public implementation<F,V,W> {}; 00039 00040 template<typename C> 00041 struct polynomial_variant_helper<tangent<C> > { 00042 typedef typename Polynomial_variant(C) CPV; 00043 typedef polynomial_tangent<CPV> PV; 00044 }; 00045 00046 /****************************************************************************** 00047 * Tangent multiplication 00048 ******************************************************************************/ 00049 00050 template<typename V, typename CV> 00051 struct implementation<polynomial_multiply,V,polynomial_tangent<CV> >: 00052 public implementation<polynomial_linear,V> 00053 { 00054 typedef implementation<vector_linear,CV> Vec_C; 00055 typedef implementation<polynomial_multiply,CV> Pol_C; 00056 00057 TMPL static inline void 00058 mul (tangent<C>* dest, const tangent<C>* s1, const tangent<C>* s2, 00059 nat n1, nat n2) 00060 { 00061 nat nd = n1 + n2 - 1; 00062 nat spc1 = aligned_size<C,CV> (n1); 00063 nat spc2 = aligned_size<C,CV> (n2); 00064 nat spcd = aligned_size<C,CV> (nd); 00065 nat spc = 5 * (spc1 + spc2); 00066 C* base_x1 = mmx_new<C> (spc); 00067 C* slope_x1= base_x1 + spc1; 00068 C* base_x2 = slope_x1 + spc1; 00069 C* slope_x2= base_x2 + spc2; 00070 C* base_d = slope_x2 + spc2; 00071 C* slope_d = base_d + spcd; 00072 C* extra_d = slope_d + spcd; 00073 00074 Vec_C::half_copy (base_x1, (C*) ((void*) s1), n1); 00075 Vec_C::half_copy (slope_x1, ((C*) ((void*) s1)) + 1, n1); 00076 Vec_C::half_copy (base_x2, (C*) ((void*) s2), n2); 00077 Vec_C::half_copy (slope_x2, ((C*) ((void*) s2)) + 1, n2); 00078 Pol_C::mul (base_d, base_x1, base_x2, n1, n2); 00079 Pol_C::mul (slope_d, base_x1, slope_x2, n1, n2); 00080 Pol_C::mul (extra_d, slope_x1, base_x2, n1, n2); 00081 Pol_C::add (slope_d, extra_d, nd); 00082 Vec_C::double_copy ((C*) ((void*) dest), base_d, nd); 00083 Vec_C::double_copy (((C*) ((void*) dest)) + 1, slope_d, nd); 00084 00085 mmx_delete<C> (base_x1, spc); 00086 } 00087 00088 TMPL static inline void 00089 square (tangent<C>* dest, const tangent<C>* s1, nat n1) { 00090 nat nd = n1 + n1 - 1; 00091 nat spc1 = aligned_size<C,CV> (n1); 00092 nat spcd = aligned_size<C,CV> (nd); 00093 nat spc = 6 * spc1; 00094 C* base_x1 = mmx_new<C> (spc); 00095 C* slope_x1= base_x1 + spc1; 00096 C* base_d = slope_x1 + spc1; 00097 C* slope_d = base_d + spcd; 00098 00099 Vec_C::half_copy (base_x1, (C*) ((void*) s1), n1); 00100 Vec_C::half_copy (slope_x1, ((C*) ((void*) s1)) + 1, n1); 00101 Pol_C::square (base_d, base_x1, n1); 00102 Pol_C::mul (slope_d, base_x1, slope_x1, n1, n1); 00103 Pol_C::add (slope_d, slope_d, nd); 00104 Vec_C::double_copy ((C*) ((void*) dest), base_d, nd); 00105 Vec_C::double_copy (((C*) ((void*) dest)) + 1, slope_d, nd); 00106 00107 mmx_delete<C> (base_x1, spc); 00108 } 00109 00110 TMPL static inline void 00111 tmul (C* dest, const C* s1, const C* s2, nat n1, nat n2) { 00112 (void) dest; (void) s1; (void) s2; (void) n1; (void) n2; 00113 ERROR ("transposed tangent multiplication not implemented"); 00114 } 00115 00116 }; // implementation<polynomial_multiply,V,polynomial_tangent<CV> > 00117 00118 #undef TMPL 00119 } // namespace mmx 00120 #endif //__MMX__POLYNOMIAL_TANGENT__HPP