00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
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 
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 
00050 
00051 
00052 TMPL_DEF
00053 class sparse_vector_rep REP_STRUCT {
00054   Pair* a;   
00055   nat   n;   
00056   nat   l;   
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     static C zero; set_zero (zero);
00078     if (Eq::op (v, zero)) rep= new Sparse_vector_rep (mmx_new<Pair > (0), 0);
00079     else rep= new Sparse_vector_rep (mmx_new<Pair > (1, Pair (k, v)), 1); }
00080   inline sparse_vector (const Pair& p) {
00081     rep= new Sparse_vector_rep (mmx_new<Pair > (1, p), 1); }
00082   inline sparse_vector (Pair* a, nat n) {
00083     rep= new Sparse_vector_rep (a, n); }
00084   inline sparse_vector (Pair* a, nat n, nat l) {
00085     rep= new Sparse_vector_rep (a, n, l); }
00086   inline Pair operator [] (nat i) const {
00087     VERIFY (i<rep->n, "index out of range");
00088     return rep->a[i]; }
00089   inline Pair& operator [] (nat i) {
00090     VERIFY (i<rep->n, "index out of range");
00091     secure ();
00092     return rep->a[i]; }
00093   friend nat N LESSGTR (const Sparse_vector& v);
00094 };
00095 INDIRECT_IMPL_3 (sparse_vector, sparse_vector_rep,
00096                  typename C, C, typename T, T, typename V, V)
00097 
00098 TMPL inline nat N (const Sparse_vector& v) { return v.rep->n; }
00099 
00100 
00101 
00102 
00103 
00104 TMPL syntactic
00105 flatten (const Sparse_vector& v) {
00106   vector<syntactic> r;
00107   for (nat i=0; i<N(v); i++)
00108     r << flatten (v[i]);
00109   return apply ("sparse_vector", r);
00110 }
00111 
00112 TMPL
00113 struct binary_helper<Sparse_vector >:
00114   public void_binary_helper<Sparse_vector >
00115 {
00116   static inline string short_type_name () {
00117     return "Sv" * Short_type_name (C); }
00118   static inline generic full_type_name () {
00119     return gen ("Sparse_vector", Full_type_name (C)); }
00120   static inline nat size (const Sparse_vector& v) {
00121     return N(v); }
00122   static inline generic access (const Sparse_vector& v, nat i) {
00123     return as<generic> (v[i]); }
00124   static inline generic disassemble (const Sparse_vector& v) {
00125     vector<generic> r;
00126     for (nat i=0; i<N(v); i++) r << as<generic> (v[i]);
00127     return as<generic> (r); }
00128   static inline Sparse_vector assemble (const generic& x) {
00129     vector<generic> v= as<vector<generic> > (x);
00130     Pair* r= mmx_new<Pair > (N(v));
00131     for (nat i=0; i<N(v); i++) r[i]= as<Pair > (v);
00132     return Sparse_vector (r, N(v)); }
00133   static inline void write (const port& out, const Sparse_vector& v) {
00134     binary_write<nat> (out, N(v));
00135     for (nat i=0; i<N(v); i++)
00136       binary_write<Pair > (out, v[i]); }
00137   static Sparse_vector read (const port& in, nat n) {
00138     if (n == 0) return Sparse_vector ();
00139     else if (n == 1) return Sparse_vector (binary_read<Pair > (in));
00140     else return read (in, (n+1) >> 1) + read (in, n >> 1); }
00141   static inline Sparse_vector read (const port& in) {
00142     nat n= binary_read<nat> (in);
00143     return read (in, n); }
00144 };
00145 
00146 
00147 
00148 
00149 
00150 template<typename Op, typename C, typename T, typename V> nat
00151 unary_hash (const Sparse_vector& v) {
00152   nat h=1236321;
00153   for (nat i=0; i<N(v); i++)
00154     h = (h << 5) ^ (h >> 27) ^ Op::op (v[i]);
00155   return h;
00156 }
00157 
00158 template<typename Op, typename C, typename T, typename V> bool
00159 binary_test (const Sparse_vector& v1, const Sparse_vector& v2) {
00160   nat n1= N(v1), n2= N(v2);
00161   if (n1 != n2) return false;
00162   for (nat i=0; i<n1; i++)
00163     if (!Op::op (v1[i], v2[i]))
00164       return false;
00165   return true;
00166 }
00167 
00168 TRUE_IDENTITY_OP_SUGAR(TMPL,Sparse_vector)
00169 EXACT_IDENTITY_OP_SUGAR(TMPL,Sparse_vector)
00170 
00171 
00172 
00173 
00174 
00175 template<typename Op, typename C, typename T, typename V> Sparse_vector
00176 unary_map (const Sparse_vector& v) {
00177   typedef typename V::val_op Eq;
00178   static C zero; set_zero (zero);
00179   nat i, j, n= N(v);
00180   Pair* r= mmx_new<Pair > (n);
00181   for (i= j= 0; i < n; i++) {
00182     Pair e (v[i].x1, Op::op (v[i].x2));
00183     if (Eq::not_op (e.x2, zero)) r[j++]= e;
00184   }
00185   return Sparse_vector (r, j, n);
00186 }
00187 
00188 TMPL inline Sparse_vector
00189 operator - (const Sparse_vector& t) {
00190   return unary_map<neg_op,C,T,V> (t); }
00191 
00192 
00193 
00194 
00195 
00196 template<typename Op, typename C, typename T, typename V> Sparse_vector
00197 binary_map (const Sparse_vector& v1, const Sparse_vector& v2) {
00198   typedef typename V::val_op Eq;
00199   typedef typename V::l_op Less;
00200   static C zero; set_zero (zero);
00201   nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2;
00202   Pair* r= mmx_new<Pair > (n);
00203   for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) {
00204     if (Less::op (v1[i1].x1, v2[i2].x1)) {
00205       Pair e (v1[i1].x1, Op::op (v1[i1].x2, zero));
00206       i1++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00207     }
00208     else if (Less::op (v2[i2].x1, v1[i1].x1)) {
00209       Pair e (v2[i2].x1, Op::op (zero, v2[i2].x2));
00210       i2++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00211     }
00212     else {
00213       Pair e (v2[i2].x1, Op::op (v1[i1].x2, v2[i2].x2));
00214       i1++; i2++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00215     }
00216   }
00217   while (i1 < n1) {
00218     Pair e (v1[i1].x1, Op::op (v1[i1].x2, zero));
00219     i1++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00220   }
00221   while (i2 < n2) {
00222     Pair e (v2[i2].x1, Op::op (zero, v2[i2].x2));
00223     i2++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00224   }
00225   return Sparse_vector (r, j, n);
00226 }
00227 
00228 template<typename Op, typename C, typename T, typename V> Sparse_vector
00229 binary_map_optimized (const Sparse_vector& v1, const Sparse_vector& v2) {
00230   
00231   typedef typename V::val_op Eq;
00232   typedef typename V::l_op Less;
00233   static C zero; set_zero (zero);
00234   nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2;
00235   Pair* r= mmx_new<Pair > (n);
00236   for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) {
00237     if (Less::op (v1[i1].x1, v2[i2].x1)) {
00238       typedef typename Op::lop Lop;
00239       r[j++]= Pair (v1[i1].x1, Lop::op (v1[i1].x2)); i1++;
00240     }
00241     else if (Less::op (v2[i2].x1, v1[i1].x1)) {
00242       typedef typename Op::rop Rop;
00243       r[j++]= Pair (v2[i2].x1, Rop::op (v2[i2].x2)); i2++;
00244     }
00245     else {
00246       Pair e (v2[i2].x1, Op::op (v1[i1].x2, v2[i2].x2));
00247       i1++; i2++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00248     }
00249   }
00250   while (i1 < n1) {
00251     typedef typename Op::lop Lop;
00252     r[j++]= Pair (v1[i1].x1, Lop::op (v1[i1].x2)); i1++;
00253   }
00254   while (i2 < n2) {
00255     typedef typename Op::rop Rop;
00256     r[j++]= Pair (v2[i2].x1, Rop::op (v2[i2].x2)); i2++;
00257   }
00258   return Sparse_vector (r, j, n);
00259 }
00260 
00261 TMPL inline Sparse_vector
00262 operator + (const Sparse_vector& t, const Sparse_vector& u) {
00263   return binary_map_optimized<add_op,C,T,V> (t, u); }
00264 TMPL inline Sparse_vector
00265 operator - (const Sparse_vector& t, const Sparse_vector& u) {
00266   return binary_map_optimized<sub_op,C,T,V> (t, u); }
00267 TMPL inline Sparse_vector
00268 operator * (const Sparse_vector& t, const Sparse_vector& u) {
00269   return binary_map<mul_op,C,T,V> (t, u); }
00270 TMPL inline Sparse_vector
00271 sup (const Sparse_vector& t, const Sparse_vector& u) {
00272   return binary_map<sup_op,C,T,V> (t, u); }
00273 TMPL inline Sparse_vector
00274 inf (const Sparse_vector& t, const Sparse_vector& u) {
00275   return binary_map<inf_op,C,T,V> (t, u); }
00276 
00277 
00278 
00279 
00280 
00281 template<typename Op, typename C, typename T, typename V>
00282 Sparse_vector
00283 binary_map_scalar (const Sparse_vector& v, const C& x) {
00284   typedef typename V::val_op Eq;
00285   static C zero; set_zero (zero);
00286   nat i, j, n= N(v);
00287   Pair* r= mmx_new<Pair > (n);
00288   for (i=0, j=0; i<n; i++) {
00289     Pair e (v[i].x1, Op::op (v[i].x2, x));
00290     if (Eq::not_op (e.x2, zero)) r[j++]= e;
00291   }
00292   return Sparse_vector (r, j, n);
00293 }
00294 
00295 TMPL inline Sparse_vector
00296 operator * (const Sparse_vector& t, const C& sc) {
00297   return binary_map_scalar<rmul_op> (t, sc); }
00298 TMPL inline Sparse_vector
00299 operator * (const C& sc, const Sparse_vector& t) {
00300   return binary_map_scalar<lmul_op> (t, sc); }
00301 TMPL inline Sparse_vector
00302 operator / (const Sparse_vector& t, const C& sc) {
00303   return binary_map_scalar<rdiv_op> (t, sc); }
00304 TMPL inline Sparse_vector
00305 operator / (const C& sc, const Sparse_vector& t) {
00306   return binary_map_scalar<ldiv_op> (t, sc); }
00307 
00308 
00309 
00310 
00311 
00312 template<typename Mul, typename C, typename T, typename V> Sparse_vector
00313 _mul_add (const Sparse_vector& v1, const Sparse_vector& v2, const C& x) {
00314   
00315   typedef typename V::val_op Eq;
00316   typedef typename V::l_op Less;
00317   static C zero; set_zero (zero);
00318   if (exact_eq (x, zero)) return v1;
00319   nat i1, i2, n1= N(v1), n2= N(v2), j, n= n1 + n2;
00320   Pair* r= mmx_new<Pair > (n);
00321   for (i1= i2= j= 0; i1 < n1 && i2 < n2; ) {
00322     if (Less::op (v1[i1].x1, v2[i2].x1)) {
00323       r[j++]= v1[i1]; i1++;
00324     }
00325     else if (Less::op (v2[i2].x1, v1[i1].x1)) {
00326       r[j++]= Pair (v2[i2].x1, Mul::op (x, v2[i2].x2)); i2++;
00327     }
00328     else {
00329       Pair e (v2[i2].x1, v1[i1].x2 + Mul::op (x, v2[i2].x2));
00330       i1++; i2++; if (Eq::not_op (e.x2, zero)) r[j++]= e;
00331     }
00332   }
00333   while (i1 < n1) {
00334     r[j++]= Pair (v1[i1].x1, v1[i1].x2); i1++;
00335   }
00336   while (i2 < n2) {
00337     r[j++]= Pair (v2[i2].x1,  Mul::op (x, v2[i2].x2)); i2++;
00338   }
00339   return Sparse_vector (r, j, n);
00340 }
00341 
00342 template<typename C, typename T, typename V> inline Sparse_vector
00343 sparse_mul_add (const Sparse_vector& v1, const Sparse_vector& v2, const C& x) {
00344   return _mul_add<mul_op> (v1, v2, x); }
00345 
00346 
00347 
00348 
00349 
00350 #define TCM template<typename C, typename M>
00351 
00352 TCM sparse_vector<C,symbol<M>,hard_eq_sparse_vector>
00353 make_formal_vector (const C& c, const M& m) {
00354   return sparse_vector<C,symbol<M>,hard_eq_sparse_vector> (symbol<M> (m), c);
00355 }
00356 
00357 TCM C
00358 get_co (const sparse_vector<C,symbol<M>,hard_eq_sparse_vector>& v, nat i) {
00359   return v[i].x2;
00360 }
00361 
00362 TCM M
00363 get_mo (const sparse_vector<C,symbol<M>,hard_eq_sparse_vector>& v, nat i) {
00364   return *v[i].x1;
00365 }
00366 
00367 #undef TCM
00368 
00369 #undef TMPL_DEF
00370 #undef TMPL
00371 #undef Sparse_vector
00372 #undef Sparse_vector_rep
00373 #undef Pair
00374 } 
00375 #endif // __MMX_SPARSE_VECTOR_HPP