algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/crt_blocks.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : crt_blocks.hpp
00004 * DESCRIPTION: Crt 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__CRT_BLOCKS__HPP
00014 #define __MMX__CRT_BLOCKS__HPP
00015 #include <algebramix/crt_dicho.hpp>
00016 
00017 namespace mmx {
00018 
00019 /******************************************************************************
00020 * Variant
00021 ******************************************************************************/
00022 
00023 #define Crt_blocks_variant(C) crt_blocks_variant_helper<C>::CV
00024 
00025 template<typename V>
00026 struct crt_blocks: public V {};
00027 
00028 template<typename F, typename V, typename W>
00029 struct implementation<F,V,crt_blocks<W> >:
00030   public implementation<F,V,W> {};
00031 
00032 template<typename C>
00033 struct crt_blocks_variant_helper {
00034   typedef crt_blocks<typename crt_naive_variant_helper<C>::CV> CV;
00035 };
00036 
00037 /******************************************************************************
00038 * Stack of two CRTs
00039 ******************************************************************************/
00040 
00041 template<typename V,typename W>
00042 struct implementation<crt_transform,V,crt_blocks<W> > :
00043     public implementation<crt_project,V> {
00044   typedef implementation<crt_project,V> Crt;
00045 
00046   template<typename I, typename C, typename CL, typename CH>
00047   static inline void
00048   direct (I* c, const C& a, CL** low, CH* high,
00049           C* aux, nat m, nat s) {
00050     high -> direct_transform (aux, a);
00051     for (nat i= 0; i < m; i++) 
00052       low[i] -> direct_transform (c + i * s, aux[i]); }
00053   
00054   template<typename C, typename I, typename CL, typename CH>
00055   static inline void
00056   combine (C& a, const I* c, CL* low, CH* high, C* aux, nat m, nat s) {
00057     for (nat i= 0; i < m; i++) 
00058       low[i] -> combine (aux[i], c + i * s);
00059     high -> combine (a, aux); }
00060 
00061   template<typename C, typename I, typename CL, typename CH>
00062   static inline void
00063   inverse (C& a, const I* c, CL* low, CH* high, C* aux, nat m, nat s) {
00064     for (nat i= 0; i < m; i++) 
00065       low[i] -> inverse_transform (aux[i], c + i * s);
00066     high -> inverse_transform (a, aux); }
00067 };
00068 
00069 /******************************************************************************
00070 * Default threshold
00071 ******************************************************************************/
00072 
00073 struct crt_blocks_threshold {};
00074 
00075 template<typename C>
00076 struct threshold_helper<C,crt_blocks_threshold> {
00077   typedef fixed_value<nat,32> impl;
00078 };
00079 
00080 /******************************************************************************
00081 * Transformer
00082 ******************************************************************************/
00083   
00084 template<typename WL, typename WH,
00085          nat s=Threshold(typename WH::base,crt_blocks_threshold),
00086          typename V=typename Crt_blocks_variant(typename WH::base) >
00087 struct crt_blocks_transformer {
00088 
00089   typedef typename WL::base base;
00090   typedef typename WL::modulus_variant modulus_variant;
00091   typedef typename WL::modulus_base modulus_base;
00092   typedef typename WL::modulus_base_variant modulus_base_variant;
00093 
00094 private:
00095   typedef base C;
00096   typedef modulus_base I;
00097   typedef modulus<I, modulus_base_variant> M;
00098   typedef modulus<C, modulus_variant> Modulus;
00099   typedef implementation<crt_transform,V> Crt;
00100 
00101 public:
00102   
00103   nat n, m;
00104   WL** low;
00105   WH* high;
00106   C* aux;
00107   Modulus P;
00108   C H;
00109   bool setup;
00110 
00111   inline void setup_comoduli () {}
00112 
00113   inline void
00114   setup_inverse () {
00115     if (setup) return;
00116     high -> setup_inverse ();
00117     for (nat i= 0; i < m; i++)
00118       low[i] -> setup_inverse ();
00119     setup= true; }
00120 
00121   inline crt_blocks_transformer (const vector<M>& p, bool lazy= true) {
00122     n= N(p); m= (n + s - 1) / s; setup= !lazy;
00123     if (n == 0) { P= 1; H= 0; return; }
00124     low= mmx_new<WL*> (m);
00125     vector<Modulus> v (Modulus (), m);
00126     for (nat i= 0; i < m; i++) {
00127       low[i]= mmx_new<WL> (1, range (p, i * s, min (n, (i+1) * s)), lazy);
00128       v[i]= low[i] -> product ();
00129     }
00130     high= mmx_new<WH> (1, v, lazy);
00131     P= high -> product ();
00132     H= Crt::half (P);
00133     aux= mmx_new<C> (m); }
00134 
00135   inline ~crt_blocks_transformer () {
00136     if (n == 0) return;
00137     for (nat i= 0; i < m; i++) mmx_delete<WL> (low[i], 1);
00138     mmx_delete<WL*> (low, m);
00139     mmx_delete<WH> (high, 1);
00140     mmx_delete<C> (aux, m); }
00141 
00142   inline M operator[] (nat i) const {
00143     VERIFY (i < n, "index out of range");
00144     return low[i / s]-> operator [] (i % s); }
00145 
00146   inline nat size () const {
00147     return n; }
00148 
00149   inline Modulus product () const {
00150     return P; }
00151 
00152   inline C comodulus (nat i) const {
00153     VERIFY (i < n, "index out of range");
00154     return high -> comodulus(i / s) * low[i / s] -> comodulus(i % s); }
00155     
00156   inline void direct_transform (I* c, const C& a) {
00157     if (n == 0) return;
00158     C b= Crt::encode (a, P);
00159     Crt::direct (c, b, low, high, aux, m, s); }
00160 
00161   inline void combine (C& a, const I* c) {
00162     if (n == 0) { a= 0; return; }
00163     setup_comoduli ();
00164     Crt::combine (a, c, low, high, aux, m, s); }
00165 
00166   inline void inverse_transform (C& a, const I* c) {
00167     if (n == 0) { a= 0; return; }
00168     setup_inverse ();
00169     Crt::inverse (a, c, low, high, aux, m, s);
00170     a= Crt::decode (a, P, H); }
00171 
00172 };
00173 
00174 template<typename WL, typename WH, nat s, typename V> inline nat
00175 N (const crt_blocks_transformer<WL,WH,s,V>& crter) {
00176   return crter.size (); 
00177 }
00178 
00179 } // namespace mmx
00180 #endif //__MMX__CRT_BLOCKS__HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines