algebramix_doc 0.3
|
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