00001 #ifndef __LINALG_H_
00002 #define __LINALG_H_
00003
00004 #define __LINALG_RANGE_CHECK 0
00005
00006 #include <mtl/mtl.h>
00007 #include <mtl/matrix.h>
00008 #include <mtl/scaled1D.h>
00009 #include <mtl/utils.h>
00010 #include <typeinfo>
00011
00012 template <class _Tp>
00013 class matrix : public mtl::matrix<_Tp, mtl::rectangle<>, mtl::compressed<>, mtl::row_major>::type
00014 {
00015 typedef matrix<_Tp> _Self;
00016 typedef typename mtl::matrix<_Tp, mtl::rectangle<>, mtl::compressed<>, mtl::row_major>::type _Base;
00017 public:
00018 typedef typename _Base::OneD Row;
00019
00020 matrix() : _Base() {}
00021 matrix(const _Self& __m) : _Base(__m) {}
00022 matrix(const size_t& n, const size_t& m) : _Base(n,m) {}
00023 };
00024
00025 template <class _Tp>
00026 class c_matrix : public mtl::matrix<_Tp, mtl::rectangle<>, mtl::compressed<>, mtl::column_major>::type
00027 {
00028 typedef matrix<_Tp> _Self;
00029 typedef typename mtl::matrix<_Tp, mtl::rectangle<>, mtl::compressed<>, mtl::column_major>::type _Base;
00030 public:
00031 typedef typename _Base::OneD Col;
00032
00033 c_matrix() : _Base() {}
00034 c_matrix(const _Self& __m) : _Base(__m) {}
00035 c_matrix(const size_t& n, const size_t& m) : _Base(n,m) {}
00036 };
00037
00038 template <class _Tp>
00039 class sparse_vector : public mtl::compressed1D<_Tp>
00040 {
00041 typedef sparse_vector<_Tp> _Self;
00042 typedef mtl::compressed1D<_Tp> _Base;
00043 };
00044
00045 template <class _Tp>
00046 bool operator==(const sparse_vector<_Tp>& a, const sparse_vector<_Tp>& b)
00047 {
00048 typename sparse_vector<_Tp>::const_iterator _b1, _b2, _e1, _e2;
00049
00050 _b1 = a.begin();
00051 _b2 = b.begin();
00052 _e1 = a.end();
00053 _e2 = b.end();
00054 while(_b1 != _e1 || _b2 != _e2)
00055 {
00056 if(_b1 == _e1)
00057 {
00058 if(*_b2 == _Tp())
00059 {
00060 ++_b2;
00061 continue;
00062 }
00063 else
00064 return false;
00065 }
00066 else if(_b2 == _e2)
00067 {
00068 if(*_b1 == _Tp())
00069 {
00070 ++_b1;
00071 continue;
00072 }
00073 else
00074 return false;
00075 }
00076 else if(_b1.index() < _b2.index())
00077 {
00078 if(*_b1 == _Tp())
00079 {
00080 ++_b1;
00081 continue;
00082 }
00083 else
00084 return false;
00085 }
00086 else if(_b2.index() < _b1.index())
00087 {
00088 if(*_b2 == _Tp())
00089 {
00090 ++_b2;
00091 continue;
00092 }
00093 else
00094 return false;
00095 }
00096 else if(*_b1 != *_b2)
00097 return false;
00098 ++_b1;
00099 ++_b2;
00100 }
00101 return true;
00102 }
00103
00104 #define linalg_scale(X, Y) mtl::scaled(X, Y)
00105
00106
00107 template <class _S>
00108 class __linalg_cvec : std::vector<_S>
00109 {
00110 private:
00111 typedef std::vector<_S> _Base;
00112 typedef __linalg_cvec<_S> _Self;
00113 const std::vector<_S>& vec;
00114
00115 public:
00116 enum { N = 0 };
00117
00118 typedef typename std::vector<_S>::value_type value_type;
00119 typedef typename std::vector<_S>::reference reference;
00120 typedef typename std::vector<_S>::pointer pointer;
00121 typedef typename std::vector<_S>::const_reference const_reference;
00122 typedef typename std::vector<_S>::const_pointer const_pointer;
00123 typedef typename std::vector<_S>::size_type size_type;
00124 typedef typename std::vector<_S>::difference_type difference_type;
00125 typedef typename std::vector<_S>::allocator_type allocator_type;
00126 typedef typename std::vector<_S>::iterator iterator;
00127 typedef typename std::vector<_S>::const_iterator const_iterator;
00128 typedef typename std::vector<_S>::reverse_iterator reverse_iterator;
00129 typedef typename std::vector<_S>::const_reverse_iterator const_reverse_iterator;
00130
00131 typedef mtl::dense_tag sparsity;
00132 typedef mtl::oned_tag dimension;
00133
00134 typedef mtl::scaled1D<_Self> scaled_type;
00135
00136 typedef mtl::light1D<_S> subrange_type;
00137 typedef _Self IndexArray;
00138 typedef _Self IndexArrayRef;
00139
00140 __linalg_cvec(const std::vector<_S>& s) : vec(s) {}
00141 ~__linalg_cvec() {}
00142
00143 iterator begin() { return vec.begin(); }
00144 iterator end() { return vec.end(); }
00145
00146 const_iterator begin() const { return vec.begin(); }
00147 const_iterator end() const { return vec.end(); }
00148 };
00149
00150 template <class _S>
00151 class __linalg_vec : std::vector<_S>
00152 {
00153 private:
00154 typedef std::vector<_S> _Base;
00155 typedef __linalg_vec<_S> _Self;
00156 std::vector<_S>& vec;
00157
00158 public:
00159 enum { N = 0 };
00160
00161 typedef typename std::vector<_S>::value_type value_type;
00162 typedef typename std::vector<_S>::reference reference;
00163 typedef typename std::vector<_S>::pointer pointer;
00164 typedef typename std::vector<_S>::const_reference const_reference;
00165 typedef typename std::vector<_S>::const_pointer const_pointer;
00166 typedef typename std::vector<_S>::size_type size_type;
00167 typedef typename std::vector<_S>::difference_type difference_type;
00168 typedef typename std::vector<_S>::allocator_type allocator_type;
00169 typedef typename std::vector<_S>::iterator iterator;
00170 typedef typename std::vector<_S>::const_iterator const_iterator;
00171 typedef typename std::vector<_S>::reverse_iterator reverse_iterator;
00172 typedef typename std::vector<_S>::const_reverse_iterator const_reverse_iterator;
00173
00174 typedef mtl::dense_tag sparsity;
00175 typedef mtl::oned_tag dimension;
00176
00177 typedef mtl::scaled1D<_Self> scaled_type;
00178
00179 typedef mtl::light1D<_S> subrange_type;
00180 typedef _Self IndexArray;
00181 typedef _Self IndexArrayRef;
00182
00183
00184 __linalg_vec(std::vector<_S>& s) : vec(s) {}
00185 ~__linalg_vec() {}
00186
00187 iterator begin() { return vec.begin(); }
00188 iterator end() { return vec.end(); }
00189
00190 const_iterator begin() const { return vec.begin(); }
00191 const_iterator end() const { return vec.end(); }
00192 };
00193
00194 template <class _S>
00195 inline _S linalg_dot(const std::vector<_S>& a, const std::vector<_S>& b, _S s)
00196 {
00197 return mtl::dot(__linalg_cvec<_S>(a), __linalg_cvec<_S>(b), s);
00198 }
00199
00200 template <class _Va, class _S>
00201 inline _S linalg_dot(const _Va& a, const std::vector<_S>& b, _S s)
00202 {
00203 __linalg_cvec<_S> _b(b);
00204 return mtl::dot(a, _b, s);
00205 }
00206
00207 template <class _Vb, class _S>
00208 inline _S linalg_dot(const std::vector<_S>& a, const _Vb& b, _S s)
00209 {
00210 return mtl::dot(__linalg_cvec<_S>(a), b, s);
00211 }
00212
00213 template <class _Va, class _Vb, class _S>
00214 inline _S linalg_dot(const _Va& a, const _Vb& b, _S s)
00215 {
00216 return mtl::dot(a, b, s);
00217 }
00218
00219 template <class _S>
00220 inline void linalg_add(const std::vector<_S>& a, const std::vector<_S>& b, std::vector<_S>& c)
00221 {
00222 mtl::add(__linalg_cvec<_S>(a), __linalg_cvec<_S>(b), __linalg_vec<_S>(c));
00223 }
00224
00225 template <class _Va, class _S>
00226 inline void linalg_add(const _Va& a, const std::vector<_S>& b, std::vector<_S>& c)
00227 {
00228 mtl::add((a), __linalg_cvec<_S>(b), __linalg_vec<_S>(c));
00229 }
00230
00231 template <class _Vb, class _S>
00232 inline void linalg_add(const std::vector<_S>& a, const _Vb& b, std::vector<_S>& c)
00233 {
00234 mtl::add(__linalg_cvec<_S>(a), (b), __linalg_vec<_S>(c));
00235 }
00236
00237 template <class _S, class _Vc>
00238 inline void linalg_add(const std::vector<_S>& a, const std::vector<_S>& b, _Vc& c)
00239 {
00240 mtl::add(__linalg_cvec<_S>(a), __linalg_cvec<_S>(b), (c));
00241 }
00242
00243 template <class _Va, class _Vb, class _S>
00244 inline void linalg_add(const _Va& a, const _Vb& b, std::vector<_S>& c)
00245 {
00246 mtl::add((a), (b), __linalg_vec<_S>(c));
00247 }
00248
00249 template <class _Va, class _S, class _Vc>
00250 inline void linalg_add(const _Va& a, const std::vector<_S>& b, _Vc& c)
00251 {
00252 mtl::add((a), __linalg_cvec<_S>(b), (c));
00253 }
00254
00255 template <class _S, class _Vb, class _Vc>
00256 inline void linalg_add(const std::vector<_S>& a, const _Vb& b, _Vc& c)
00257 {
00258 mtl::add(__linalg_cvec<_S>(a), (b), (c));
00259 }
00260
00261 template <class _Va, class _Vb, class _Vc>
00262 inline void linalg_add(const _Va& a, const _Vb& b, _Vc& c)
00263 {
00264 mtl::add((a), (b), (c));
00265 }
00266
00267
00268 template <class _Matrix, class _S>
00269 inline void linalg_matvec(const _Matrix& A, const std::vector<_S>& a,
00270 std::vector<_S>& c)
00271 {
00272 mtl::mult((A), __linalg_cvec<_S>(a), __linalg_vec<_S>(c));
00273 }
00274
00275 template <class _Matrix, class _S, class _Va>
00276 inline void linalg_matvec(const _Matrix& A, const _Va& a,
00277 std::vector<_S>& c)
00278 {
00279 mtl::mult((A), (a), __linalg_vec<_S>(c));
00280 }
00281
00282 template <class _Matrix, class _S, class _Vc>
00283 inline void linalg_matvec(const _Matrix& A, const std::vector<_S>& a,
00284 _Vc& c)
00285 {
00286 mtl::mult((A), __linalg_cvec<_S>(a), __linalg_cvec<_S>(b), (c));
00287 }
00288
00289 template <class _Matrix, class _Va, class _Vc>
00290 inline void linalg_matvec(const _Matrix& A, const _Va& a, _Vc& c)
00291 {
00292 mtl::mult((A), (a), (c));
00293 }
00294
00295 template <class _Matrix, class _S>
00296 inline void linalg_matvecv(const _Matrix& A, const std::vector<_S>& a,
00297 const std::vector<_S>& b, std::vector<_S>& c)
00298 {
00299 mtl::mult((A), __linalg_cvec<_S>(a), __linalg_cvec<_S>(b),
00300 __linalg_vec<_S>(c));
00301 }
00302
00303 template <class _Matrix, class _S, class _Va>
00304 inline void linalg_matvecv(const _Matrix& A, const _Va& a,
00305 const std::vector<_S>& b, std::vector<_S>& c)
00306 {
00307 mtl::mult((A), (a), __linalg_cvec<_S>(b), __linalg_vec<_S>(c));
00308 }
00309
00310 template <class _Matrix, class _S, class _Vb>
00311 inline void linalg_matvecv(const _Matrix& A, const std::vector<_S>& a,
00312 const _Vb& b, std::vector<_S>& c)
00313 {
00314 mtl::mult((A), __linalg_cvec<_S>(a), (b), __linalg_vec<_S>(c));
00315 }
00316
00317 template <class _Matrix, class _S, class _Vc>
00318 inline void linalg_matvecv(const _Matrix& A, const std::vector<_S>& a,
00319 const std::vector<_S>& b, _Vc& c)
00320 {
00321 mtl::mult((A), __linalg_cvec<_S>(a), __linalg_cvec<_S>(b), (c));
00322 }
00323
00324 template <class _Matrix, class _Va, class _Vb, class _S>
00325 inline void linalg_matvecv(const _Matrix& A, _Va& a,
00326 const _Vb& b, const std::vector<_S>& c)
00327 {
00328 mtl::mult((A), (a), (b), __linalg_vec<_S>(c));
00329 }
00330
00331 template <class _Matrix, class _Va, class _S, class _Vc>
00332 inline void linalg_matvecv(const _Matrix& A, const _Va& a,
00333 const std::vector<_S>& b, _Vc& c)
00334 {
00335 mtl::mult((A), (a), __linalg_cvec<_S>(b), (c));
00336 }
00337
00338 template <class _Matrix, class _S, class _Vb, class _Vc>
00339 inline void linalg_matvecv(const _Matrix& A, const std::vector<_S>& a,
00340 const _Vb& b, _Vc& c)
00341 {
00342 mtl::mult((A), __linalg_cvec<_S>(a), (b), (c));
00343 }
00344
00345 template <class _Matrix, class _Va, class _Vb, class _Vc>
00346 inline void linalg_matvecv(const _Matrix& A, const _Va& a, const _Vb& b,
00347 _Vc& c)
00348 {
00349 mtl::mult((A), (a), (b), (c));
00350 }
00351
00352 #define linalg_trans(A) mtl::trans((A))
00353
00354
00355 template <class _Ve>
00356 inline std::vector<_Ve>& linalg_ssum(std::vector<_Ve>& a, _Ve b, const std::vector<_Ve>& c)
00357 {
00358 #if __LINALG_RANGE_CHECK
00359 if(a.size() != b.size())
00360 throw "linalg: a and c have different size in linalg_ssum";
00361 #endif
00362 typename std::vector<_Ve>::iterator _a(a.begin()), e_a(a.end());
00363 typename std::vector<_Ve>::const_iterator _c(c.begin());
00364
00365 while(_a != e_a)
00366 *_a++ += b * *_c++;
00367 return a;
00368 }
00369
00370 template <class _Ve>
00371 inline std::vector<_Ve>& linalg_smult(std::vector<_Ve>& a, _Ve b)
00372 {
00373 typename std::vector<_Ve>::iterator _a(a.begin()), e_a(a.end());
00374
00375 while(_a != e_a)
00376 *_a++ *= b;
00377 return a;
00378 }
00379
00380 #endif