00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
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 
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 
00060 
00061 
00062 STMPL
00063 struct threshold_helper<integer,base_blocks_threshold> {
00064   typedef fixed_value<nat,32> impl;
00065 };
00066 
00067 
00068 
00069 
00070 
00071 template<typename I>
00072 struct base_integer_transformer {
00073   typedef integer C;
00074 
00075   
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, q_s = square (* p); nat s= 1;
00117     while (quo (q_s, * p) == p_s) {
00118       p_s = q_s; q_s= p_s * * p; s++; }
00119     baser= mmx_new<Baser> (1, mmx_new<Baser_low> (1, p, s));
00120   }
00121 
00122   inline ~base_integer_transformer () {
00123     mmx_delete<Baser> (baser, 1); }
00124 
00125   inline nat direct_transform (I* c, nat n, const C& a) {
00126     return direct_base (c, n, a, * baser); }
00127 
00128   inline void inverse_transform (C& a, const I* c, nat n) {
00129     return inverse_base (a, c, n, * baser); }
00130 };
00131 
00132 #define IMPLEMENTATION_HELPER(I)                                \
00133   STMPL struct base_transformer_helper<integer,I> {             \
00134     typedef base_integer_transformer<I> Baser; };
00135 IMPLEMENTATION_HELPER(signed char)
00136 IMPLEMENTATION_HELPER(short int)
00137 IMPLEMENTATION_HELPER(int)
00138 IMPLEMENTATION_HELPER(long int)
00139 IMPLEMENTATION_HELPER(long long int)
00140 #undef IMPLEMENTATION_HELPER
00141 
00142 
00143 
00144 
00145 
00146 template<typename I>
00147 struct base_unsigned_integer_transformer {
00148   typedef integer C;
00149 
00150   
00151   static const nat internal_size=
00152     sizeof(I) > sizeof(int) ? sizeof(I) : sizeof(int);
00153   typedef typename unsigned_int_with_size_at_least_helper<
00154     internal_size>::type J;
00155 
00156   typedef typename Modulus_variant(I) modulus_base_variant;
00157   typedef modulus<I, modulus_base_variant> M;
00158 
00159   typedef typename Modulus_variant(J) modulus_middle_variant;
00160   typedef modulus<J, modulus_middle_variant> N;
00161 
00162   typedef C base;
00163   typedef I modulus_base;
00164 
00165   struct std_J_I {
00166     typedef J base;
00167     typedef I modulus_base;
00168     typedef typename Modulus_variant(I) modulus_base_variant;
00169   };
00170   typedef base_naive_transformer<J,std_J_I, base_naive> Baser_I;
00171 
00172   struct std_C_J {
00173     typedef C base;
00174     typedef J modulus_base;
00175     typedef modulus_middle_variant modulus_base_variant;
00176   };
00177   typedef base_blocks_transformer<
00178     Baser_I,
00179     base_naive_transformer<C,std_C_J,base_naive> > Baser_low;
00180 
00181   typedef base_dicho_transformer<integer, std_base_dicho<integer>,
00182                                   base_dicho<base_naive> > Baser_high;
00183   typedef base_blocks_transformer<Baser_low, Baser_high> Baser;
00184 
00185   M p;
00186   Baser* baser;
00187 
00188   template<typename K> 
00189   inline base_unsigned_integer_transformer (const K& _p) : p (_p) {
00190     J p_s= * p, q_s = square (* p); nat s= 1;
00191     while (quo (q_s, * p) == p_s) {
00192       p_s = q_s; q_s= p_s * * p; s++; }
00193     baser= mmx_new<Baser> (1, mmx_new<Baser_low> (1, p, s));
00194   }
00195 
00196   inline ~base_unsigned_integer_transformer () {
00197     mmx_delete<Baser> (baser, 1); }
00198 
00199   inline nat direct_transform (I* c, nat n, const C& a) {
00200     ASSERT (a >= 0, "invalid negative argument");
00201     return direct_base (c, n, a, * baser); }
00202 
00203   inline void inverse_transform (C& a, const I* c, nat n) {
00204     return inverse_base (a, c, n, * baser); }
00205 };
00206 
00207 #define IMPLEMENTATION_HELPER(I)                                \
00208   STMPL struct base_transformer_helper<integer,I> {             \
00209     typedef base_unsigned_integer_transformer<I> Baser; };
00210 IMPLEMENTATION_HELPER(unsigned char)
00211 IMPLEMENTATION_HELPER(unsigned short)
00212 IMPLEMENTATION_HELPER(unsigned int)
00213 IMPLEMENTATION_HELPER(unsigned long int)
00214 IMPLEMENTATION_HELPER(unsigned long long int)
00215 #undef IMPLEMENTATION_HELPER
00216 
00217 #define IMPLEMENTATION_HELPER(I)                                \
00218   STMPL struct base_transformer_helper_unsigned<integer,I> {    \
00219     typedef base_unsigned_integer_transformer<I> Baser; };
00220 IMPLEMENTATION_HELPER(signed char)
00221 IMPLEMENTATION_HELPER(short int)
00222 IMPLEMENTATION_HELPER(int)
00223 IMPLEMENTATION_HELPER(long int)
00224 IMPLEMENTATION_HELPER(long long int)
00225 #undef IMPLEMENTATION_HELPER
00226 
00227 } 
00228 #endif // __MMX_BASE_INTEGER_HPP