algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/base_integer.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : base_integer.hpp
00004 * DESCRIPTION: Change of base for integers
00005 * COPYRIGHT  : (C) 2009  Joris van der Hoeven and 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_BASE_INTEGER_HPP
00014 #define __MMX_BASE_INTEGER_HPP
00015 #include <numerix/modular_integer.hpp>
00016 #include <algebramix/base.hpp>
00017 #include <algebramix/base_blocks.hpp>
00018 #include <algebramix/base_int.hpp>
00019 
00020 namespace mmx {
00021 
00022 /******************************************************************************
00023 * Variants / Note that default is signed
00024 ******************************************************************************/
00025 
00026 DEFINE_VARIANT(base_naive_integer,base_signed<base_naive>)
00027 DEFINE_VARIANT(base_dicho_integer,base_signed<base_dicho<base_naive> >)
00028 
00029 STMPL
00030 struct base_naive_variant_helper<integer> {
00031   typedef base_naive_integer BV;
00032 };
00033 
00034 STMPL
00035 struct base_dicho_variant_helper<integer> {
00036   typedef base_dicho_integer BV;
00037 };
00038 
00039 STMPL
00040 struct base_transformer_helper<integer,integer> {
00041   typedef base_dicho_transformer<integer> Baser;
00042 };
00043 
00044 STMPL
00045 struct base_transformer_helper_unsigned<integer,integer> {
00046   typedef base_dicho_transformer<integer,std_base_dicho<integer>,
00047                                  base_dicho<base_naive> > Baser;
00048 };
00049 
00050 template<typename I>
00051 struct size_bound_in_base_helper<integer,I> {
00052   static inline nat
00053   size (const integer& s, const I& p) {
00054     ASSERT (bit_size (p) > 1, "invalid base");
00055     return 1 + (1 + bit_size (s)) / (bit_size (p) - 1); }
00056 };
00057 
00058 /******************************************************************************
00059 * Threshold
00060 ******************************************************************************/
00061 
00062 STMPL
00063 struct threshold_helper<integer,base_blocks_threshold> {
00064   typedef fixed_value<nat,32> impl;
00065 };
00066 
00067 /******************************************************************************
00068 * Special transformer
00069 ******************************************************************************/
00070 
00071 template<typename I>
00072 struct base_integer_transformer {
00073   typedef integer C;
00074 
00075   // default internal type is 'int' for speed
00076   static const nat internal_size=
00077     sizeof(I) > sizeof(int) ? sizeof(I) : sizeof(int);
00078   typedef typename unsigned_int_with_size_at_least_helper<
00079     internal_size>::type uJ;
00080   typedef typename signed_of_helper<uJ>::type J;
00081 
00082   typedef typename Modulus_variant(I) modulus_base_variant;
00083   typedef modulus<I, modulus_base_variant> M;
00084 
00085   typedef typename Modulus_variant(J) modulus_middle_variant;
00086   typedef modulus<J, modulus_middle_variant> N;
00087 
00088   typedef C base;
00089   typedef I modulus_base;
00090 
00091   struct std_J_I {
00092     typedef J base;
00093     typedef I modulus_base;
00094     typedef typename Modulus_variant(I) modulus_base_variant;
00095   };
00096   typedef base_naive_transformer<J,std_J_I> Baser_I;
00097 
00098   struct std_C_J {
00099     typedef C base;
00100     typedef J modulus_base;
00101     typedef modulus_middle_variant modulus_base_variant;
00102   };
00103   typedef base_blocks_transformer<
00104     Baser_I,
00105     base_naive_transformer<C,std_C_J> > Baser_low;
00106 
00107   typedef base_dicho_transformer<integer,
00108                                   std_base_dicho<integer> > Baser_high;
00109   typedef base_blocks_transformer<Baser_low, Baser_high> Baser;
00110 
00111   M p;
00112   Baser* baser;
00113 
00114   template<typename K> 
00115   inline base_integer_transformer (const K& _p) : p (_p) {
00116     J p_s= * p; nat s= 1;
00117     while ((p_s * * p) / * p == p_s) { p_s *= * p; s++; }
00118     baser= mmx_new<Baser> (1, mmx_new<Baser_low> (1, p, s));
00119   }
00120 
00121   inline ~base_integer_transformer () {
00122     mmx_delete<Baser> (baser, 1); }
00123 
00124   inline nat direct_transform (I* c, nat n, const C& a) {
00125     return direct_base (c, n, a, * baser); }
00126 
00127   inline void inverse_transform (C& a, const I* c, nat n) {
00128     return inverse_base (a, c, n, * baser); }
00129 };
00130 
00131 #define IMPLEMENTATION_HELPER(I)                                \
00132   STMPL struct base_transformer_helper<integer,I> {             \
00133     typedef base_integer_transformer<I> Baser; };
00134 IMPLEMENTATION_HELPER(signed char)
00135 IMPLEMENTATION_HELPER(short int)
00136 IMPLEMENTATION_HELPER(int)
00137 IMPLEMENTATION_HELPER(long int)
00138 IMPLEMENTATION_HELPER(long long int)
00139 #undef IMPLEMENTATION_HELPER
00140 
00141 /******************************************************************************
00142 * Special transformer for nonnegative integers
00143 ******************************************************************************/
00144 
00145 template<typename I>
00146 struct base_unsigned_integer_transformer {
00147   typedef integer C;
00148 
00149   // default internal type is 'unsigned int' for speed
00150   static const nat internal_size=
00151     sizeof(I) > sizeof(int) ? sizeof(I) : sizeof(int);
00152   typedef typename unsigned_int_with_size_at_least_helper<
00153     internal_size>::type J;
00154 
00155   typedef typename Modulus_variant(I) modulus_base_variant;
00156   typedef modulus<I, modulus_base_variant> M;
00157 
00158   typedef typename Modulus_variant(J) modulus_middle_variant;
00159   typedef modulus<J, modulus_middle_variant> N;
00160 
00161   typedef C base;
00162   typedef I modulus_base;
00163 
00164   struct std_J_I {
00165     typedef J base;
00166     typedef I modulus_base;
00167     typedef typename Modulus_variant(I) modulus_base_variant;
00168   };
00169   typedef base_naive_transformer<J,std_J_I, base_naive> Baser_I;
00170 
00171   struct std_C_J {
00172     typedef C base;
00173     typedef J modulus_base;
00174     typedef modulus_middle_variant modulus_base_variant;
00175   };
00176   typedef base_blocks_transformer<
00177     Baser_I,
00178     base_naive_transformer<C,std_C_J,base_naive> > Baser_low;
00179 
00180   typedef base_dicho_transformer<integer, std_base_dicho<integer>,
00181                                   base_dicho<base_naive> > Baser_high;
00182   typedef base_blocks_transformer<Baser_low, Baser_high> Baser;
00183 
00184   M p;
00185   Baser* baser;
00186 
00187   template<typename K> 
00188   inline base_unsigned_integer_transformer (const K& _p) : p (_p) {
00189     J p_s= * p; nat s= 1;
00190     while ((p_s * * p) / * p == p_s) { p_s *= * p; s++; }
00191     baser= mmx_new<Baser> (1, mmx_new<Baser_low> (1, p, s));
00192   }
00193 
00194   inline ~base_unsigned_integer_transformer () {
00195     mmx_delete<Baser> (baser, 1); }
00196 
00197   inline nat direct_transform (I* c, nat n, const C& a) {
00198     ASSERT (a >= 0, "invalid negative argument");
00199     return direct_base (c, n, a, * baser); }
00200 
00201   inline void inverse_transform (C& a, const I* c, nat n) {
00202     return inverse_base (a, c, n, * baser); }
00203 };
00204 
00205 #define IMPLEMENTATION_HELPER(I)                                \
00206   STMPL struct base_transformer_helper<integer,I> {             \
00207     typedef base_unsigned_integer_transformer<I> Baser; };
00208 IMPLEMENTATION_HELPER(unsigned char)
00209 IMPLEMENTATION_HELPER(unsigned short)
00210 IMPLEMENTATION_HELPER(unsigned int)
00211 IMPLEMENTATION_HELPER(unsigned long int)
00212 IMPLEMENTATION_HELPER(unsigned long long int)
00213 #undef IMPLEMENTATION_HELPER
00214 
00215 #define IMPLEMENTATION_HELPER(I)                                \
00216   STMPL struct base_transformer_helper_unsigned<integer,I> {    \
00217     typedef base_unsigned_integer_transformer<I> Baser; };
00218 IMPLEMENTATION_HELPER(signed char)
00219 IMPLEMENTATION_HELPER(short int)
00220 IMPLEMENTATION_HELPER(int)
00221 IMPLEMENTATION_HELPER(long int)
00222 IMPLEMENTATION_HELPER(long long int)
00223 #undef IMPLEMENTATION_HELPER
00224 
00225 } // namespace mmx
00226 #endif // __MMX_BASE_INTEGER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines