basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/sparse_vector.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines