algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/polynomial_tangent.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines