basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : sparse_vector.hpp 00004 * DESCRIPTION: Hash sparse_vectors 00005 * COPYRIGHT : (C) 2004 Joris van der Hoeven 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_SPARSE_VECTOR_HPP 00014 #define __MMX_SPARSE_VECTOR_HPP 00015 #include <basix/pair.hpp> 00016 #include <basix/symbol.hpp> 00017 00019 00020 namespace mmx { 00021 struct eq_sparse_vector; 00022 #define TMPL_DEF \ 00023 template<typename C, typename T, typename V= exact_eq_sparse_vector> 00024 #define TMPL template<typename C, typename T, typename V> 00025 #define Sparse_vector sparse_vector<C,T,V> 00026 #define Sparse_vector_rep sparse_vector_rep<C,T,V> 00027 #define Pair pair<T,C> 00028 TMPL class sparse_vector_rep; 00029 TMPL class sparse_vector; 00030 TMPL inline nat N (const Sparse_vector& v); 00031 00032 /****************************************************************************** 00033 * Variants of sparse vectors 00034 ******************************************************************************/ 00035 00036 struct hard_eq_sparse_vector { 00037 typedef hard_eq_op key_op; 00038 typedef equal_op val_op; 00039 typedef hard_less_op l_op; 00040 }; 00041 00042 struct exact_eq_sparse_vector { 00043 typedef exact_eq_op key_op; 00044 typedef equal_op val_op; 00045 typedef less_op l_op; 00046 }; 00047 00048 /****************************************************************************** 00049 * Sparse_vector class and its representation class 00050 ******************************************************************************/ 00051 00052 TMPL_DEF 00053 class sparse_vector_rep REP_STRUCT { 00054 Pair* a; // the entries 00055 nat n; // number of entries 00056 nat l; // allocated number of entries 00057 00058 public: 00059 inline sparse_vector_rep (Pair* a2, nat n2): 00060 a (a2), n (n2), l (n2) {} 00061 inline sparse_vector_rep (Pair* a2, nat n2, nat l2): 00062 a (a2), n (n2), l (l2) {} 00063 inline ~sparse_vector_rep () { 00064 mmx_delete<Pair > (a, l); } 00065 00066 friend class Sparse_vector; 00067 friend nat N LESSGTR (const Sparse_vector& v); 00068 }; 00069 00070 TMPL_DEF 00071 class sparse_vector { 00072 INDIRECT_PROTO_3 (sparse_vector, sparse_vector_rep, C, T, V) 00073 inline sparse_vector () { 00074 rep= new Sparse_vector_rep (mmx_new<Pair > (0), 0); } 00075 inline sparse_vector (const T& k, const C& v) { 00076 typedef typename V::val_op Eq; 00077 if (Eq::op (v, C (0))) rep= new Sparse_vector_rep (mmx_new<Pair > (0), 0); 00078 else rep= new Sparse_vector_rep (mmx_new<Pair > (1, Pair (k, v)), 1); } 00079 inline sparse_vector (const Pair& p) { 00080 rep= new Sparse_vector_rep (mmx_new<Pair > (1, p), 1); } 00081 inline sparse_vector (Pair* a, nat n) { 00082 rep= new Sparse_vector_rep (a, n); } 00083 inline sparse_vector (Pair* a, nat n, nat l) { 00084 rep= new Sparse_vector_rep (a, n, l); } 00085 inline Pair operator [] (nat i) const { 00086 VERIFY (i<rep->n, "index out of range"); 00087 return rep->a[i]; } 00088 inline Pair& operator [] (nat i) { 00089 VERIFY (i<rep->n, "index out of range"); 00090 secure (); 00091 return rep->a[i]; } 00092 friend nat N LESSGTR (const Sparse_vector& v); 00093 }; 00094 INDIRECT_IMPL_3 (sparse_vector, sparse_vector_rep, 00095 typename C, C, typename T, T, typename V, V) 00096 00097 TMPL inline nat N (const Sparse_vector& v) { return v.rep->n; } 00098 00099 /****************************************************************************** 00100 * Printing sparse_vectors 00101 ******************************************************************************/ 00102 00103 TMPL syntactic 00104 flatten (const Sparse_vector& v) { 00105 vector<syntactic> r; 00106 for (nat i=0; i<N(v); i++) 00107 r << flatten (v[i]); 00108 return apply ("sparse_vector", r); 00109 } 00110 00111 TMPL 00112 struct binary_helper<Sparse_vector >: 00113 public void_binary_helper<Sparse_vector > 00114 { 00115 static inline string short_type_name () { 00116 return "Sv" * Short_type_name (C); } 00117 static inline generic full_type_name () { 00118 return gen ("Sparse_vector", Full_type_name (C)); } 00119 static inline nat size (const Sparse_vector& v) { 00120 return N(v); } 00121 static inline generic access (const Sparse_vector& v, nat i) { 00122 return as<generic> (v[i]); } 00123 static inline generic disassemble (const Sparse_vector& v) { 00124 vector<generic> r; 00125 for (nat i=0; i<N(v); i++) r << as<generic> (v[i]); 00126 return as<generic> (r); } 00127 static inline Sparse_vector assemble (const generic& x) { 00128 vector<generic> v= as<vector<generic> > (x); 00129 Pair* r= mmx_new<Pair > (N(v)); 00130 for (nat i=0; i<N(v); i++) r[i]= as<Pair > (v); 00131 return Sparse_vector (r, N(v)); } 00132 static inline void write (const port& out, const Sparse_vector& v) { 00133 binary_write<nat> (out, N(v)); 00134 for (nat i=0; i<N(v); i++) 00135 binary_write<Pair > (out, v[i]); } 00136 static Sparse_vector read (const port& in, nat n) { 00137 if (n == 0) return Sparse_vector (); 00138 else if (n == 1) return Sparse_vector (binary_read<Pair > (in)); 00139 else return read (in, (n+1) >> 1) + read (in, n >> 1); } 00140 static inline Sparse_vector read (const port& in) { 00141 nat n= binary_read<nat> (in); 00142 return read (in, n); } 00143 }; 00144 00145 /****************************************************************************** 00146 * Hashing and equality testing 00147 ******************************************************************************/ 00148 00149 template<typename Op, typename C, typename T, typename V> nat 00150 unary_hash (const Sparse_vector& v) { 00151 nat h=1236321; 00152 for (nat i=0; i<N(v); i++) 00153 h = (h << 5) ^ (h >> 27) ^ Op::op (v[i]); 00154 return h; 00155 } 00156 00157 template<typename Op, typename C, typename T, typename V> bool 00158 binary_test (const Sparse_vector& v1, const Sparse_vector& v2) { 00159 nat n1= N(v1), n2= N(v2); 00160 if (n1 != n2) return false; 00161 for (nat i=0; i<n1; i++) 00162 if (!Op::op (v1[i], v2[i])) 00163 return false; 00164 return true; 00165 } 00166 00167 TRUE_IDENTITY_OP_SUGAR(TMPL,Sparse_vector) 00168 EXACT_IDENTITY_OP_SUGAR(TMPL,Sparse_vector) 00169 00170 /****************************************************************************** 00171 * Unary operations 00172 ******************************************************************************/ 00173 00174 template<typename Op, typename C, typename T, typename V> Sparse_vector 00175 unary_map (const Sparse_vector& v) { 00176 typedef typename V::val_op Eq; 00177 nat i, j, n= N(v); 00178 Pair* r= mmx_new<Pair > (n); 00179 for (i= j= 0; i < n; i++) { 00180 Pair e (v[i].x1, Op::op (v[i].x2)); 00181 if (Eq::not_op (e.x2, C (0))) r[j++]= e; 00182 } 00183 return Sparse_vector (r, j, n); 00184 } 00185 00186 TMPL inline Sparse_vector 00187 operator - (const Sparse_vector& t) { 00188 return unary_map<neg_op,C,T,V> (t); } 00189 00190 /****************************************************************************** 00191 * Binary operations 00192 ******************************************************************************/ 00193 00194 template<typename Op, typename C, typename T, typename V> Sparse_vector 00195 binary_map (const Sparse_vector& v1, const Sparse_vector& v2) { 00196 typedef typename V::val_op Eq; 00197 typedef typename V::l_op Less; 00198 nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2; 00199 Pair* r= mmx_new<Pair > (n); 00200 for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) { 00201 if (Less::op (v1[i1].x1, v2[i2].x1)) { 00202 Pair e (v1[i1].x1, Op::op (v1[i1].x2, C(0))); 00203 i1++; if (Eq::not_op (e.x2, C(0))) r[j++]= e; 00204 } 00205 else if (Less::op (v2[i2].x1, v1[i1].x1)) { 00206 Pair e (v2[i2].x1, Op::op (C(0), v2[i2].x2)); 00207 i2++; if (Eq::not_op (e.x2, C(0))) r[j++]= e; 00208 } 00209 else { 00210 Pair e (v2[i2].x1, Op::op (v1[i1].x2, v2[i2].x2)); 00211 i1++; i2++; if (Eq::not_op (e.x2, C (0))) r[j++]= e; 00212 } 00213 } 00214 while (i1 < n1) { 00215 Pair e (v1[i1].x1, Op::op (v1[i1].x2, C(0))); 00216 i1++; if (Eq::not_op (e.x2, C(0))) r[j++]= e; 00217 } 00218 while (i2 < n2) { 00219 Pair e (v2[i2].x1, Op::op (C(0), v2[i2].x2)); 00220 i2++; if (Eq::not_op (e.x2, C(0))) r[j++]= e; 00221 } 00222 return Sparse_vector (r, j, n); 00223 } 00224 00225 template<typename Op, typename C, typename T, typename V> Sparse_vector 00226 binary_map_optimized (const Sparse_vector& v1, const Sparse_vector& v2) { 00227 // With optimizations for addition and subtraction 00228 typedef typename V::val_op Eq; 00229 typedef typename V::l_op Less; 00230 nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2; 00231 Pair* r= mmx_new<Pair > (n); 00232 for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) { 00233 if (Less::op (v1[i1].x1, v2[i2].x1)) { 00234 typedef typename Op::lop Lop; 00235 r[j++]= Pair (v1[i1].x1, Lop::op (v1[i1].x2)); i1++; 00236 } 00237 else if (Less::op (v2[i2].x1, v1[i1].x1)) { 00238 typedef typename Op::rop Rop; 00239 r[j++]= Pair (v2[i2].x1, Rop::op (v2[i2].x2)); i2++; 00240 } 00241 else { 00242 Pair e (v2[i2].x1, Op::op (v1[i1].x2, v2[i2].x2)); 00243 i1++; i2++; if (Eq::not_op (e.x2, C (0))) r[j++]= e; 00244 } 00245 } 00246 while (i1 < n1) { 00247 typedef typename Op::lop Lop; 00248 r[j++]= Pair (v1[i1].x1, Lop::op (v1[i1].x2)); i1++; 00249 } 00250 while (i2 < n2) { 00251 typedef typename Op::rop Rop; 00252 r[j++]= Pair (v2[i2].x1, Rop::op (v2[i2].x2)); i2++; 00253 } 00254 return Sparse_vector (r, j, n); 00255 } 00256 00257 TMPL inline Sparse_vector 00258 operator + (const Sparse_vector& t, const Sparse_vector& u) { 00259 return binary_map_optimized<add_op,C,T,V> (t, u); } 00260 TMPL inline Sparse_vector 00261 operator - (const Sparse_vector& t, const Sparse_vector& u) { 00262 return binary_map_optimized<sub_op,C,T,V> (t, u); } 00263 TMPL inline Sparse_vector 00264 operator * (const Sparse_vector& t, const Sparse_vector& u) { 00265 return binary_map<mul_op,C,T,V> (t, u); } 00266 TMPL inline Sparse_vector 00267 sup (const Sparse_vector& t, const Sparse_vector& u) { 00268 return binary_map<sup_op,C,T,V> (t, u); } 00269 TMPL inline Sparse_vector 00270 inf (const Sparse_vector& t, const Sparse_vector& u) { 00271 return binary_map<inf_op,C,T,V> (t, u); } 00272 00273 /****************************************************************************** 00274 * Scalar operations 00275 ******************************************************************************/ 00276 00277 template<typename Op, typename C, typename T, typename V> 00278 Sparse_vector 00279 binary_map_scalar (const Sparse_vector& v, const C& x) { 00280 typedef typename V::val_op Eq; 00281 nat i, j, n= N(v); 00282 Pair* r= mmx_new<Pair > (n); 00283 for (i=0, j=0; i<n; i++) { 00284 Pair e (v[i].x1, Op::op (v[i].x2, x)); 00285 if (Eq::not_op (e.x2, C (0))) r[j++]= e; 00286 } 00287 return Sparse_vector (r, j, n); 00288 } 00289 00290 TMPL inline Sparse_vector 00291 operator * (const Sparse_vector& t, const C& sc) { 00292 return binary_map_scalar<rmul_op> (t, sc); } 00293 TMPL inline Sparse_vector 00294 operator * (const C& sc, const Sparse_vector& t) { 00295 return binary_map_scalar<lmul_op> (t, sc); } 00296 TMPL inline Sparse_vector 00297 operator / (const Sparse_vector& t, const C& sc) { 00298 return binary_map_scalar<rdiv_op> (t, sc); } 00299 TMPL inline Sparse_vector 00300 operator / (const C& sc, const Sparse_vector& t) { 00301 return binary_map_scalar<ldiv_op> (t, sc); } 00302 00303 /****************************************************************************** 00304 * Composed operations 00305 ******************************************************************************/ 00306 00307 template<typename Mul, typename C, typename T, typename V> Sparse_vector 00308 _mul_add (const Sparse_vector& v1, const Sparse_vector& v2, const C& x) { 00309 // v1 + x * v2 00310 typedef typename V::val_op Eq; 00311 typedef typename V::l_op Less; 00312 if (is_exact_zero (x)) return v1; 00313 nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2; 00314 Pair* r= mmx_new<Pair > (n); 00315 for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) { 00316 if (Less::op (v1[i1].x1, v2[i2].x1)) { 00317 r[j++]= v1[i1]; i1++; 00318 } 00319 else if (Less::op (v2[i2].x1, v1[i1].x1)) { 00320 r[j++]= Pair (v2[i2].x1, Mul::op (x, v2[i2].x2)); i2++; 00321 } 00322 else { 00323 Pair e (v2[i2].x1, v1[i1].x2 + Mul::op (x, v2[i2].x2)); 00324 i1++; i2++; if (Eq::not_op (e.x2, C (0))) r[j++]= e; 00325 } 00326 } 00327 while (i1 < n1) { 00328 r[j++]= Pair (v1[i1].x1, v1[i1].x2); i1++; 00329 } 00330 while (i2 < n2) { 00331 r[j++]= Pair (v2[i2].x1, Mul::op (x, v2[i2].x2)); i2++; 00332 } 00333 return Sparse_vector (r, j, n); 00334 } 00335 00336 template<typename C, typename T, typename V> inline Sparse_vector 00337 sparse_mul_add (const Sparse_vector& v1, const Sparse_vector& v2, const C& x) { 00338 return _mul_add<mul_op> (v1, v2, x); } 00339 00340 #undef TMPL_DEF 00341 #undef TMPL 00342 #undef Sparse_vector 00343 #undef Sparse_vector_rep 00344 #undef Pair 00345 } // namespace mmx 00346 #endif // __MMX_SPARSE_VECTOR_HPP