algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/polynomial_quotient.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : polynomial_quotient.hpp
00004 * DESCRIPTION: Multiply polynomials by reduction to a common denominator
00005 * COPYRIGHT  : (C) 2004  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_QUOTIENT_HPP
00014 #define __MMX_POLYNOMIAL_QUOTIENT_HPP
00015 #include <algebramix/quotient.hpp>
00016 #include <algebramix/polynomial_dicho.hpp>
00017 namespace mmx {
00018 #define TMPL template<typename C>
00019 #define NC Numerator_type(C)
00020 #define DC Denominator_type(C)
00021 
00022 /******************************************************************************
00023 * Variants for polynomials with fractional coefficients
00024 ******************************************************************************/
00025 
00026 template<typename V>
00027 struct polynomial_quotient: public V {
00028   typedef typename V::Vec Vec;
00029   typedef typename V::Naive Naive;
00030   typedef polynomial_quotient<typename V::Positive> Positive;
00031   typedef polynomial_quotient<typename V::No_simd> No_simd;
00032   typedef polynomial_quotient<typename V::No_thread> No_thread;
00033   typedef polynomial_quotient<typename V::No_scaled> No_scaled;
00034 };
00035 
00036 template<typename F, typename V, typename W>
00037 struct implementation<F,V,polynomial_quotient<W> >:
00038     public implementation<F,V,W> {};
00039 
00040 /******************************************************************************
00041 * Default variant
00042 ******************************************************************************/
00043 
00044 template<typename C, typename V>
00045 struct polynomial_variant_helper<quotient<polynomial<C,V>,
00046                                           polynomial<C,V> > > {
00047   typedef polynomial_quotient<polynomial_naive> PV;
00048 };
00049 
00050 /******************************************************************************
00051 * Variable names, default is C(x)[y]
00052 ******************************************************************************/
00053 
00054 template<typename V,typename W>
00055 struct implementation<polynomial_defaults,V,polynomial_quotient<W> > {
00056 
00057   template<typename P>
00058   class global_variables {
00059     static inline generic& dyn_name () {
00060       static generic name = "x";
00061       return name; }
00062   public:
00063     static inline void set_variable_name (const generic& x) { dyn_name () = x; }
00064     static inline generic get_variable_name () { return dyn_name (); }
00065   };
00066 
00067   template<typename C, typename V1, typename V2>
00068   class global_variables<polynomial<
00069                            quotient<polynomial<C,V1>,
00070                                     polynomial<C,V1> >, V2> > {
00071     static inline generic& dyn_name () {
00072       static generic name = "y";
00073       return name; }
00074   public:
00075     static inline void set_variable_name (const generic& x) {
00076       dyn_name () = x; }
00077     static inline generic get_variable_name () {
00078       return dyn_name (); }
00079   };
00080 };
00081 
00082 /******************************************************************************
00083 * Low level subroutines
00084 ******************************************************************************/
00085 
00086 TMPL DC
00087 least_common_denominator (const C* src, nat n) {
00088   switch (n) {
00089   case 0: return 1;
00090   case 1: return denominator (src[0]);
00091   case 2: return lcm (denominator (src[0]), denominator (src[1]));
00092   case 3: return lcm (denominator (src[0]), lcm (denominator (src[1]),
00093                                                  denominator (src[2])));
00094   default: return lcm (least_common_denominator (src, n>>1),
00095                        least_common_denominator (src + (n>>1), n - (n>>1)));
00096   }
00097 }
00098 
00099 TMPL void
00100 denominator_mul (NC* dest, const C* src, nat n, const DC& d) {
00101   for (nat i=0; i<n; i++)
00102     dest[i]= numerator (src[i]) * (d / denominator (src[i]));
00103 }
00104 
00105 TMPL void
00106 denominator_div (C* dest, const NC* src, nat n, const DC& d) {
00107   for (nat i=0; i<n; i++)
00108     dest[i]= C (src[i]) / d;
00109 }
00110 
00111 /******************************************************************************
00112 * Multiply polynomials by putting the coefficients under a common denominator
00113 ******************************************************************************/
00114 
00115 template<typename V, typename W>
00116 struct implementation<polynomial_multiply,V,polynomial_quotient<W> >:
00117   public implementation<polynomial_linear,V>
00118 {
00119   typedef polynomial_multiply_threshold<polynomial_quotient<W> > Th;
00120   typedef implementation<polynomial_multiply,W> Fallback;
00121 
00122 TMPL static void
00123 mul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00124   typedef typename Polynomial_variant(NC) NV;
00125   typedef implementation<polynomial_multiply,NV> Pol_N;
00126   if (min (n1, n2) < Threshold(C,Th))
00127     Fallback::mul (dest, s1, s2, n1, n2);
00128   else {
00129     DC  d1  = least_common_denominator (s1, n1);
00130     DC  d2  = least_common_denominator (s2, n2);
00131     /*
00132       mmout << "d1= " << d1 << ", " << "d2= " << d2 << "\n";
00133       for (nat i=0; i<n1; i++)
00134       mmout << "  s" << i << "\t" << s1[i] << "\n";
00135       for (nat i=0; i<n2; i++)
00136       mmout << "  t" << i << "\t" << s2[i] << "\n";
00137     */
00138     NC* Src1= mmx_new<NC> (n1);
00139     NC* Src2= mmx_new<NC> (n2);
00140     NC* Dest= mmx_new<NC> (n1+n2-1);
00141     denominator_mul (Src1, s1, n1, d1);
00142     denominator_mul (Src2, s2, n2, d2);
00143     Pol_N::mul (Dest, Src1, Src2, n1, n2);
00144     denominator_div (dest, Dest, n1+n2-1, d1*d2);
00145     mmx_delete<NC> (Src1, n1);
00146     mmx_delete<NC> (Src2, n2);
00147     mmx_delete<NC> (Dest, n1+n2-1);
00148   }
00149 }
00150 
00151 TMPL static void
00152 square (C* dest, const C* s1, nat n1) {
00153   typedef typename Polynomial_variant(NC) NV;
00154   typedef implementation<polynomial_multiply,NV> Pol_N;
00155   if (n1 < Threshold(C,Th))
00156     Fallback::square (dest, s1, n1);
00157   else {
00158     DC  d1  = least_common_denominator (s1, n1);
00159     NC* Src1= mmx_new<NC> (n1);
00160     NC* Dest= mmx_new<NC> (n1+n1-1);
00161     denominator_mul (Src1, s1, n1, d1);
00162     Pol_N::square (Dest, Src1, n1);
00163     denominator_div (dest, Dest, n1+n1-1, square_op::op (d1));
00164     mmx_delete<NC> (Src1, n1);
00165     mmx_delete<NC> (Dest, n1+n1-1);
00166   }
00167 }
00168 
00169 TMPL static inline void
00170 tmul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00171   (void) dest; (void) s1; (void) s2; (void) n1; (void) n2;
00172   ERROR ("transposed quotient multiplication not implemented");
00173 }
00174 
00175 }; // implementation<polynomial_multiply,V,polynomial_quotient<NV> >
00176 
00177 #undef TMPL
00178 #undef NC
00179 #undef DC
00180 }
00181 #endif // __MMX_POLYNOMIAL_QUOTIENT_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines