algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/base_blocks.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines