algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : base_blocks.hpp 00004 * DESCRIPTION: Implementation change of bases by blocks 00005 * COPYRIGHT : (C) 2009 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_BLOCKS__HPP 00014 #define __MMX__BASE_BLOCKS__HPP 00015 #include <algebramix/base_naive.hpp> 00016 #include <algebramix/base_dicho.hpp> 00017 00018 namespace mmx { 00019 00020 /****************************************************************************** 00021 * Blocks variant 00022 ******************************************************************************/ 00023 00024 #define Base_blocks_variant(C) base_blocks_variant_helper<C>::BV 00025 00026 template<typename V> 00027 struct base_blocks : public V {}; 00028 00029 template<typename F, typename V, typename W> 00030 struct implementation<F,V,base_blocks<W> >: 00031 public implementation<F,V,W> {}; 00032 00033 template<typename C> 00034 struct base_blocks_variant_helper { 00035 typedef base_blocks<typename base_naive_variant_helper<C>::BV> BV; 00036 }; 00037 00038 /****************************************************************************** 00039 * Direct and inverse transforms 00040 ******************************************************************************/ 00041 00042 template<typename V, typename W> 00043 struct implementation<base_transform,V,base_blocks<W> > { 00044 00045 template<typename C, typename I, typename WL, typename WH> static inline nat 00046 direct (I* c, nat n, const C& a, WL* low, WH* high, nat s) { 00047 typedef typename WH::modulus_base J; 00048 if (a == 0) return 0; 00049 nat m= (n + s - 1) / s; 00050 J* aux= mmx_new<J> (m); 00051 nat oh= direct_base (aux, m, a, * high), ol= 0; 00052 for (nat i= 0; i < oh; i++, n -= s) { 00053 ol= direct_base (c + s * i, min (s, n), aux[i], * low); 00054 for (nat j= ol; j < min (s, n); j++) c[s * i + j]= 0; 00055 } 00056 mmx_delete<J> (aux, m); 00057 return oh == 0 ? 0 : (oh - 1) * s + ol; } 00058 00059 template<typename C, typename I, typename WL, typename WH> static inline void 00060 inverse (C& a, const I* c, nat n, WL* low, WH* high, nat s) { 00061 typedef typename WH::modulus_base J; 00062 nat m= (n + s - 1) / s; 00063 J* aux= mmx_new<J> (m); 00064 for (nat i= 0; i < m; i++, n -= s) 00065 inverse_base (aux[i], c + s * i, min (s, n), * low); 00066 inverse_base (a, aux, m, * high); 00067 mmx_delete<J> (aux, m); } 00068 00069 }; 00070 00071 /****************************************************************************** 00072 * Default threshold 00073 ******************************************************************************/ 00074 00075 struct base_blocks_threshold {}; 00076 00077 template<typename C> 00078 struct threshold_helper<C,base_blocks_threshold> { 00079 typedef fixed_value<nat,32> impl; 00080 }; 00081 00082 /****************************************************************************** 00083 * The blocks transformer class 00084 ******************************************************************************/ 00085 00086 template<typename WL, typename WH, 00087 typename V=typename Base_blocks_variant(typename WH::base) > 00088 struct base_blocks_transformer { 00089 typedef typename WH::base base; 00090 typedef typename WL::modulus_base modulus_base; 00091 typedef typename WL::modulus_base_variant modulus_base_variant; 00092 typedef typename WH::modulus_base modulus_middle; 00093 typedef typename WH::modulus_base_variant modulus_middle_variant; 00094 00095 typedef base C; 00096 typedef modulus_base I; 00097 typedef modulus_middle J; 00098 typedef modulus<I, modulus_base_variant> M; 00099 typedef modulus<J, modulus_middle_variant> N; 00100 typedef implementation<base_transform,V> Base; 00101 00102 M p; 00103 nat s; 00104 WL* low; 00105 WH* high; 00106 00107 public: 00108 00109 static const nat th= Threshold(typename WH::base,base_blocks_threshold); 00110 template<typename K> 00111 inline base_blocks_transformer (const K& _p, nat _s= th) 00112 : p(_p), s(_s) { 00113 ASSERT (_p != 0 && _p != 1, "invalid base"); 00114 low= mmx_new<WL> (1, p); 00115 J p_s= binpow (J(* p), s); 00116 high= mmx_new<WH> (1, p_s); } 00117 00118 inline base_blocks_transformer (WL* _low, nat _s= th) 00119 : p(_low->p), s(_s), low(_low) { 00120 J p_s= binpow (J(* p), s); 00121 high= mmx_new<WH> (1, p_s); } 00122 00123 inline ~base_blocks_transformer () { 00124 mmx_delete<WL> (low, 1); 00125 mmx_delete<WH> (high, 1); } 00126 00127 inline nat direct_transform (I* c, nat n, const C& a) { 00128 return Base::direct (c, n, a, low, high, s); } 00129 00130 inline void inverse_transform (C& a, const I* c, nat n) { 00131 Base::inverse (a, c, n, low, high, s); } 00132 }; 00133 00134 } // namespace mmx 00135 #endif //__MMX__BASE_BLOCKS__HPP