algebramix_doc 0.3
|
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