algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : modular__polynomial.hpp 00004 * DESCRIPTION: Modular arithmetic for polynomials 00005 * COPYRIGHT : (C) 2008 Gregoire Lecerf 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_MODULAR_POLYNOMIAL_HPP 00014 #define __MMX_MODULAR_POLYNOMIAL_HPP 00015 #include <numerix/modular.hpp> 00016 #include <algebramix/polynomial.hpp> 00017 00018 namespace mmx { 00019 00020 #define TMPL template<typename C, typename M> 00021 00022 /****************************************************************************** 00023 * Variant 00024 ******************************************************************************/ 00025 00026 template<typename V> 00027 struct modulus_polynomial_inv_naive : public V { 00028 00029 TMPL static inline void 00030 inv_mod (C& a, const M& m) { 00031 if (m.p == 0) { 00032 if (deg (a) == 0) 00033 a= 1 / a [0]; 00034 else 00035 ERROR ("inv_mod: argument is not invertible"); 00036 } 00037 a = invert_modulo (a, m.p); 00038 if (a == 0) 00039 ERROR ("inv_mod: argument is not invertible"); } 00040 00041 TMPL static inline void 00042 inv_mod (C& dest, const C& s, const M& m) { 00043 dest = s; 00044 inv_mod (dest, m); } 00045 }; 00046 00047 struct modulus_polynomial_naive: 00048 public modulus_encoding_naive< 00049 modulus_div_naive< 00050 modulus_polynomial_inv_naive< 00051 modulus_mul_naive< 00052 modulus_add_naive< 00053 modulus_reduction_naive< 00054 modulus_normalization_naive> > > > > > {}; 00055 00056 /****************************************************************************** 00057 * Helper specialization 00058 ******************************************************************************/ 00059 00060 template<typename C, typename V> 00061 struct modulus_variant_helper<polynomial<C,V> > { 00062 typedef modulus_polynomial_naive MV; }; 00063 00064 #undef TMPL 00065 00066 /****************************************************************************** 00067 * Special output 00068 ******************************************************************************/ 00069 00070 template<typename C, typename PV, typename MV, typename MW> inline syntactic 00071 flatten (const modular<modulus<polynomial<C, PV>, MW>, MV>& c) { 00072 generic x= polynomial<C, PV>::get_variable_name (); 00073 generic a= gen (GEN_PRIME, x); 00074 if (x == "x") a= "a"; 00075 if (x == "y") a= "b"; 00076 if (x == "z") a= "c"; 00077 return flatten (*c, as_syntactic (a)); 00078 } 00079 00080 template<typename C, typename PV, typename MV> inline syntactic 00081 flatten (const modulus<polynomial<C, PV>, MV>& c) { 00082 generic x= polynomial<C, PV>::get_variable_name (); 00083 generic a= gen (GEN_PRIME, x); 00084 if (x == "x") a= "a"; 00085 if (x == "y") a= "b"; 00086 if (x == "z") a= "c"; 00087 return flatten (*c, as_syntactic (a)); 00088 } 00089 00090 } // namespace mmx 00091 #endif // __MMX_MODULAR_POLYNOMIAL_HPP