00001
00029 #ifndef SMAT_H
00030 #define SMAT_H
00031
00032 #ifndef _MSC_VER
00033 # include <itpp/config.h>
00034 #else
00035 # include <itpp/config_msvc.h>
00036 #endif
00037
00038 #include <itpp/base/svec.h>
00039
00040
00041 namespace itpp
00042 {
00043
00044
00045 template <class T> class Vec;
00046
00047 template <class T> class Mat;
00048
00049 template <class T> class Sparse_Vec;
00050
00051 template <class T> class Sparse_Mat;
00052
00053
00054
00056 template <class T>
00057 Sparse_Mat<T> operator+(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00058
00060 template <class T>
00061 Sparse_Mat<T> operator*(const T &c, const Sparse_Mat<T> &m);
00062
00064 template <class T>
00065 Sparse_Mat<T> operator*(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00066
00068 template <class T>
00069 Sparse_Vec<T> operator*(const Sparse_Mat<T> &m, const Sparse_Vec<T> &v);
00070
00072 template <class T>
00073 Vec<T> operator*(const Sparse_Mat<T> &m, const Vec<T> &v);
00074
00076 template <class T>
00077 Vec<T> operator*(const Vec<T> &v, const Sparse_Mat<T> &m);
00078
00080 template <class T>
00081 Mat<T> trans_mult(const Sparse_Mat<T> &m);
00082
00084 template <class T>
00085 Sparse_Mat<T> trans_mult_s(const Sparse_Mat<T> &m);
00086
00088 template <class T>
00089 Sparse_Mat<T> trans_mult(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00090
00092 template <class T>
00093 Vec<T> trans_mult(const Sparse_Mat<T> &m, const Vec<T> &v);
00094
00096 template <class T>
00097 Sparse_Mat<T> mult_trans(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00098
00112 template <class T>
00113 class Sparse_Mat
00114 {
00115 public:
00116
00118 Sparse_Mat();
00119
00130 Sparse_Mat(int rows, int cols, int row_data_init = 200);
00131
00133 Sparse_Mat(const Sparse_Mat<T> &m);
00134
00136 Sparse_Mat(const Mat<T> &m);
00137
00143 Sparse_Mat(const Mat<T> &m, T epsilon);
00144
00146 ~Sparse_Mat();
00147
00158 void set_size(int rows, int cols, int row_data_init = -1);
00159
00161 int rows() const { return n_rows; }
00162
00164 int cols() const { return n_cols; }
00165
00167 int nnz();
00168
00170 double density();
00171
00173 void compact();
00174
00176 void full(Mat<T> &m) const;
00177
00179 Mat<T> full() const;
00180
00182 T operator()(int r, int c) const;
00183
00185 void set(int r, int c, T v);
00186
00188 void set_new(int r, int c, T v);
00189
00191 void add_elem(const int r, const int c, const T v);
00192
00194 void zeros();
00195
00197 void zero_elem(const int r, const int c);
00198
00200 void clear();
00201
00203 void clear_elem(const int r, const int c);
00204
00206 void set_submatrix(int r1, int r2, int c1, int c2, const Mat<T> &m);
00207
00209 void set_submatrix(int r, int c, const Mat<T>& m);
00210
00212 Sparse_Mat<T> get_submatrix(int r1, int r2, int c1, int c2) const;
00213
00215 Sparse_Mat<T> get_submatrix_cols(int c1, int c2) const;
00216
00218 void get_col(int c, Sparse_Vec<T> &v) const;
00219
00221 Sparse_Vec<T> get_col(int c) const;
00222
00224 void set_col(int c, const Sparse_Vec<T> &v);
00225
00230 void transpose(Sparse_Mat<T> &m) const;
00231
00236 Sparse_Mat<T> transpose() const;
00237
00242
00243
00245 void operator=(const Sparse_Mat<T> &m);
00246
00248 void operator=(const Mat<T> &m);
00249
00251 Sparse_Mat<T> operator-() const;
00252
00254 bool operator==(const Sparse_Mat<T> &m) const;
00255
00257 void operator+=(const Sparse_Mat<T> &v);
00258
00260 void operator+=(const Mat<T> &v);
00261
00263 void operator-=(const Sparse_Mat<T> &v);
00264
00266 void operator-=(const Mat<T> &v);
00267
00269 void operator*=(const T &v);
00270
00272 void operator/=(const T &v);
00273
00275 friend Sparse_Mat<T> operator+<>(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00276
00278 friend Sparse_Mat<T> operator*<>(const T &c, const Sparse_Mat<T> &m);
00279
00281 friend Sparse_Mat<T> operator*<>(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00282
00284 friend Sparse_Vec<T> operator*<>(const Sparse_Mat<T> &m, const Sparse_Vec<T> &v);
00285
00287 friend Vec<T> operator*<>(const Sparse_Mat<T> &m, const Vec<T> &v);
00288
00290 friend Vec<T> operator*<>(const Vec<T> &v, const Sparse_Mat<T> &m);
00291
00293 friend Mat<T> trans_mult <>(const Sparse_Mat<T> &m);
00294
00296 friend Sparse_Mat<T> trans_mult_s <>(const Sparse_Mat<T> &m);
00297
00299 friend Sparse_Mat<T> trans_mult <>(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00300
00302 friend Vec<T> trans_mult <>(const Sparse_Mat<T> &m, const Vec<T> &v);
00303
00305 friend Sparse_Mat<T> mult_trans <>(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2);
00306
00307 private:
00308 void init();
00309 void alloc_empty();
00310 void alloc(int row_data_size = 200);
00311 void free();
00312
00313 int n_rows, n_cols;
00314 Sparse_Vec<T> *col;
00315 };
00316
00321 typedef Sparse_Mat<int> sparse_imat;
00322
00327 typedef Sparse_Mat<double> sparse_mat;
00328
00333 typedef Sparse_Mat<std::complex<double> > sparse_cmat;
00334
00335
00336
00337 template <class T>
00338 void Sparse_Mat<T>::init()
00339 {
00340 n_rows = 0;
00341 n_cols = 0;
00342 col = 0;
00343 }
00344
00345 template <class T>
00346 void Sparse_Mat<T>::alloc_empty()
00347 {
00348 if (n_cols == 0)
00349 col = 0;
00350 else
00351 col = new Sparse_Vec<T>[n_cols];
00352 }
00353
00354 template <class T>
00355 void Sparse_Mat<T>::alloc(int row_data_init)
00356 {
00357 if (n_cols == 0)
00358 col = 0;
00359 else
00360 col = new Sparse_Vec<T>[n_cols];
00361 for (int c = 0; c < n_cols; c++)
00362 col[c].set_size(n_rows, row_data_init);
00363 }
00364
00365 template <class T>
00366 void Sparse_Mat<T>::free()
00367 {
00368 delete [] col;
00369 col = 0;
00370 }
00371
00372 template <class T>
00373 Sparse_Mat<T>::Sparse_Mat()
00374 {
00375 init();
00376 }
00377
00378 template <class T>
00379 Sparse_Mat<T>::Sparse_Mat(int rows, int cols, int row_data_init)
00380 {
00381 init();
00382 n_rows = rows;
00383 n_cols = cols;
00384 alloc(row_data_init);
00385 }
00386
00387 template <class T>
00388 Sparse_Mat<T>::Sparse_Mat(const Sparse_Mat<T> &m)
00389 {
00390 init();
00391 n_rows = m.n_rows;
00392 n_cols = m.n_cols;
00393 alloc_empty();
00394
00395 for (int c = 0; c < n_cols; c++)
00396 col[c] = m.col[c];
00397 }
00398
00399 template <class T>
00400 Sparse_Mat<T>::Sparse_Mat(const Mat<T> &m)
00401 {
00402 init();
00403 n_rows = m.rows();
00404 n_cols = m.cols();
00405 alloc();
00406
00407 for (int c = 0; c < n_cols; c++) {
00408 for (int r = 0; r < n_rows; r++) {
00409
00410 if (m(r, c) != T(0))
00411 col[c].set_new(r, m(r, c));
00412 }
00413 col[c].compact();
00414 }
00415 }
00416
00417 template <class T>
00418 Sparse_Mat<T>::Sparse_Mat(const Mat<T> &m, T epsilon)
00419 {
00420 init();
00421 n_rows = m.rows();
00422 n_cols = m.cols();
00423 alloc();
00424
00425 for (int c = 0; c < n_cols; c++) {
00426 for (int r = 0; r < n_rows; r++) {
00427 if (std::abs(m(r, c)) > std::abs(epsilon))
00428 col[c].set_new(r, m(r, c));
00429 }
00430 col[c].compact();
00431 }
00432 }
00433
00434 template <class T>
00435 Sparse_Mat<T>::~Sparse_Mat()
00436 {
00437 free();
00438 }
00439
00440 template <class T>
00441 void Sparse_Mat<T>::set_size(int rows, int cols, int row_data_init)
00442 {
00443 n_rows = rows;
00444
00445
00446 if (cols != n_cols || row_data_init != -1) {
00447 n_cols = cols;
00448 free();
00449 alloc(row_data_init);
00450 }
00451 }
00452
00453 template <class T>
00454 int Sparse_Mat<T>::nnz()
00455 {
00456 int n = 0;
00457 for (int c = 0; c < n_cols; c++)
00458 n += col[c].nnz();
00459
00460 return n;
00461 }
00462
00463 template <class T>
00464 double Sparse_Mat<T>::density()
00465 {
00466
00467 return double(nnz()) / (n_rows*n_cols);
00468 }
00469
00470 template <class T>
00471 void Sparse_Mat<T>::compact()
00472 {
00473 for (int c = 0; c < n_cols; c++)
00474 col[c].compact();
00475 }
00476
00477 template <class T>
00478 void Sparse_Mat<T>::full(Mat<T> &m) const
00479 {
00480 m.set_size(n_rows, n_cols);
00481 m = T(0);
00482 for (int c = 0; c < n_cols; c++) {
00483 for (int p = 0; p < col[c].nnz(); p++)
00484 m(col[c].get_nz_index(p), c) = col[c].get_nz_data(p);
00485 }
00486 }
00487
00488 template <class T>
00489 Mat<T> Sparse_Mat<T>::full() const
00490 {
00491 Mat<T> r(n_rows, n_cols);
00492 full(r);
00493 return r;
00494 }
00495
00496 template <class T>
00497 T Sparse_Mat<T>::operator()(int r, int c) const
00498 {
00499 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00500 return col[c](r);
00501 }
00502
00503 template <class T>
00504 void Sparse_Mat<T>::set(int r, int c, T v)
00505 {
00506 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00507 col[c].set(r, v);
00508 }
00509
00510 template <class T>
00511 void Sparse_Mat<T>::set_new(int r, int c, T v)
00512 {
00513 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00514 col[c].set_new(r, v);
00515 }
00516
00517 template <class T>
00518 void Sparse_Mat<T>::add_elem(int r, int c, T v)
00519 {
00520 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00521 col[c].add_elem(r, v);
00522 }
00523
00524 template <class T>
00525 void Sparse_Mat<T>::zeros()
00526 {
00527 for (int c = 0; c < n_cols; c++)
00528 col[c].zeros();
00529 }
00530
00531 template <class T>
00532 void Sparse_Mat<T>::zero_elem(const int r, const int c)
00533 {
00534 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00535 col[c].zero_elem(r);
00536 }
00537
00538 template <class T>
00539 void Sparse_Mat<T>::clear()
00540 {
00541 for (int c = 0; c < n_cols; c++)
00542 col[c].clear();
00543 }
00544
00545 template <class T>
00546 void Sparse_Mat<T>::clear_elem(const int r, const int c)
00547 {
00548 it_assert_debug(r >= 0 && r<n_rows && c >= 0 && c < n_cols, "Incorrect input indexes given");
00549 col[c].clear_elem(r);
00550 }
00551
00552 template <class T>
00553 void Sparse_Mat<T>::set_submatrix(int r1, int r2, int c1, int c2, const Mat<T>& m)
00554 {
00555 if (r1 == -1) r1 = n_rows - 1;
00556 if (r2 == -1) r2 = n_rows - 1;
00557 if (c1 == -1) c1 = n_cols - 1;
00558 if (c2 == -1) c2 = n_cols - 1;
00559
00560 it_assert_debug(r1 >= 0 && r2 >= 0 && r1 < n_rows && r2 < n_rows &&
00561 c1 >= 0 && c2 >= 0 && c1 < n_cols && c2 < n_cols, "Sparse_Mat<Num_T>::set_submatrix(): index out of range");
00562
00563 it_assert_debug(r2 >= r1 && c2 >= c1, "Sparse_Mat<Num_T>::set_submatrix: r2<r1 or c2<c1");
00564 it_assert_debug(m.rows() == r2 - r1 + 1 && m.cols() == c2 - c1 + 1, "Mat<Num_T>::set_submatrix(): sizes don't match");
00565
00566 for (int i = 0 ; i < m.rows() ; i++) {
00567 for (int j = 0 ; j < m.cols() ; j++) {
00568 set(r1 + i, c1 + j, m(i, j));
00569 }
00570 }
00571 }
00572
00573 template <class T>
00574 void Sparse_Mat<T>::set_submatrix(int r, int c, const Mat<T>& m)
00575 {
00576 it_assert_debug(r >= 0 && r + m.rows() <= n_rows &&
00577 c >= 0 && c + m.cols() <= n_cols, "Sparse_Mat<Num_T>::set_submatrix(): index out of range");
00578
00579 for (int i = 0 ; i < m.rows() ; i++) {
00580 for (int j = 0 ; j < m.cols() ; j++) {
00581 set(r + i, c + j, m(i, j));
00582 }
00583 }
00584 }
00585
00586 template <class T>
00587 Sparse_Mat<T> Sparse_Mat<T>::get_submatrix(int r1, int r2, int c1, int c2) const
00588 {
00589 it_assert_debug(r1 <= r2 && r1 >= 0 && r1 < n_rows && c1 <= c2 && c1 >= 0 && c1 < n_cols,
00590 "Sparse_Mat<T>::get_submatrix(): illegal input variables");
00591
00592 Sparse_Mat<T> r(r2 - r1 + 1, c2 - c1 + 1);
00593
00594 for (int c = c1; c <= c2; c++)
00595 r.col[c-c1] = col[c].get_subvector(r1, r2);
00596 r.compact();
00597
00598 return r;
00599 }
00600
00601 template <class T>
00602 Sparse_Mat<T> Sparse_Mat<T>::get_submatrix_cols(int c1, int c2) const
00603 {
00604 it_assert_debug(c1 <= c2 && c1 >= 0 && c1 < n_cols, "Sparse_Mat<T>::get_submatrix_cols()");
00605 Sparse_Mat<T> r(n_rows, c2 - c1 + 1, 0);
00606
00607 for (int c = c1; c <= c2; c++)
00608 r.col[c-c1] = col[c];
00609 r.compact();
00610
00611 return r;
00612 }
00613
00614 template <class T>
00615 void Sparse_Mat<T>::get_col(int c, Sparse_Vec<T> &v) const
00616 {
00617 it_assert(c >= 0 && c < n_cols, "Sparse_Mat<T>::get_col()");
00618 v = col[c];
00619 }
00620
00621 template <class T>
00622 Sparse_Vec<T> Sparse_Mat<T>::get_col(int c) const
00623 {
00624 it_assert(c >= 0 && c < n_cols, "Sparse_Mat<T>::get_col()");
00625 return col[c];
00626 }
00627
00628 template <class T>
00629 void Sparse_Mat<T>::set_col(int c, const Sparse_Vec<T> &v)
00630 {
00631 it_assert(c >= 0 && c < n_cols, "Sparse_Mat<T>::set_col()");
00632 col[c] = v;
00633 }
00634
00635 template <class T>
00636 void Sparse_Mat<T>::transpose(Sparse_Mat<T> &m) const
00637 {
00638 m.set_size(n_cols, n_rows);
00639 for (int c = 0; c < n_cols; c++) {
00640 for (int p = 0; p < col[c].nnz(); p++)
00641 m.col[col[c].get_nz_index(p)].set_new(c, col[c].get_nz_data(p));
00642 }
00643 }
00644
00645 template <class T>
00646 Sparse_Mat<T> Sparse_Mat<T>::transpose() const
00647 {
00648 Sparse_Mat<T> m;
00649 transpose(m);
00650 return m;
00651 }
00652
00653 template <class T>
00654 void Sparse_Mat<T>::operator=(const Sparse_Mat<T> &m)
00655 {
00656 free();
00657 n_rows = m.n_rows;
00658 n_cols = m.n_cols;
00659 alloc_empty();
00660
00661 for (int c = 0; c < n_cols; c++)
00662 col[c] = m.col[c];
00663 }
00664
00665 template <class T>
00666 void Sparse_Mat<T>::operator=(const Mat<T> &m)
00667 {
00668 free();
00669 n_rows = m.rows();
00670 n_cols = m.cols();
00671 alloc();
00672
00673 for (int c = 0; c < n_cols; c++) {
00674 for (int r = 0; r < n_rows; r++) {
00675 if (m(r, c) != T(0))
00676 col[c].set_new(r, m(r, c));
00677 }
00678 col[c].compact();
00679 }
00680 }
00681
00682 template <class T>
00683 Sparse_Mat<T> Sparse_Mat<T>::operator-() const
00684 {
00685 Sparse_Mat r(n_rows, n_cols, 0);
00686
00687 for (int c = 0; c < n_cols; c++) {
00688 r.col[c].resize_data(col[c].nnz());
00689 for (int p = 0; p < col[c].nnz(); p++)
00690 r.col[c].set_new(col[c].get_nz_index(p), -col[c].get_nz_data(p));
00691 }
00692
00693 return r;
00694 }
00695
00696 template <class T>
00697 bool Sparse_Mat<T>::operator==(const Sparse_Mat<T> &m) const
00698 {
00699 if (n_rows != m.n_rows || n_cols != m.n_cols)
00700 return false;
00701 for (int c = 0; c < n_cols; c++) {
00702 if (!(col[c] == m.col[c]))
00703 return false;
00704 }
00705
00706 return true;
00707 }
00708
00709 template <class T>
00710 void Sparse_Mat<T>::operator+=(const Sparse_Mat<T> &m)
00711 {
00712 it_assert_debug(m.rows() == n_rows && m.cols() == n_cols, "Addition of unequal sized matrices is not allowed");
00713
00714 Sparse_Vec<T> v;
00715 for (int c = 0; c < n_cols; c++) {
00716 m.get_col(c, v);
00717 col[c] += v;
00718 }
00719 }
00720
00721 template <class T>
00722 void Sparse_Mat<T>::operator+=(const Mat<T> &m)
00723 {
00724 it_assert_debug(m.rows() == n_rows && m.cols() == n_cols, "Addition of unequal sized matrices is not allowed");
00725
00726 for (int c = 0; c < n_cols; c++)
00727 col[c] += (m.get_col(c));
00728 }
00729
00730 template <class T>
00731 void Sparse_Mat<T>::operator-=(const Sparse_Mat<T> &m)
00732 {
00733 it_assert_debug(m.rows() == n_rows && m.cols() == n_cols, "Subtraction of unequal sized matrices is not allowed");
00734
00735 Sparse_Vec<T> v;
00736 for (int c = 0; c < n_cols; c++) {
00737 m.get_col(c, v);
00738 col[c] -= v;
00739 }
00740 }
00741
00742 template <class T>
00743 void Sparse_Mat<T>::operator-=(const Mat<T> &m)
00744 {
00745 it_assert_debug(m.rows() == n_rows && m.cols() == n_cols, "Subtraction of unequal sized matrices is not allowed");
00746
00747 for (int c = 0; c < n_cols; c++)
00748 col[c] -= (m.get_col(c));
00749 }
00750
00751 template <class T>
00752 void Sparse_Mat<T>::operator*=(const T &m)
00753 {
00754 for (int c = 0; c < n_cols; c++)
00755 col[c] *= m;
00756 }
00757
00758 template <class T>
00759 void Sparse_Mat<T>::operator/=(const T &m)
00760 {
00761 for (int c = 0; c < n_cols; c++)
00762 col[c] /= m;
00763 }
00764
00765 template <class T>
00766 Sparse_Mat<T> operator+(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2)
00767 {
00768 it_assert_debug(m1.n_cols == m2.n_cols && m1.n_rows == m2.n_rows , "Sparse_Mat<T> + Sparse_Mat<T>");
00769
00770 Sparse_Mat<T> m(m1.n_rows, m1.n_cols, 0);
00771
00772 for (int c = 0; c < m.n_cols; c++)
00773 m.col[c] = m1.col[c] + m2.col[c];
00774
00775 return m;
00776 }
00777
00778
00779 template <class T>
00780 Sparse_Mat<T> operator*(const T &c, const Sparse_Mat<T> &m)
00781 {
00782 int i, j;
00783 Sparse_Mat<T> ret(m.n_rows, m.n_cols);
00784 for (j = 0; j < m.n_cols; j++) {
00785 for (i = 0; i < m.col[j].nnz(); i++) {
00786 T x = c * m.col[j].get_nz_data(i);
00787 int k = m.col[j].get_nz_index(i);
00788 ret.set_new(k, j, x);
00789 }
00790 }
00791 return ret;
00792 }
00793
00794 template <class T>
00795 Sparse_Mat<T> operator*(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2)
00796 {
00797 it_assert_debug(m1.n_cols == m2.n_rows, "Sparse_Mat<T> * Sparse_Mat<T>");
00798
00799 Sparse_Mat<T> ret(m1.n_rows, m2.n_cols);
00800
00801 for (int c = 0; c < m2.n_cols; c++) {
00802 Sparse_Vec<T> &m2colc = m2.col[c];
00803 for (int p2 = 0; p2 < m2colc.nnz(); p2++) {
00804 Sparse_Vec<T> &mcol = m1.col[m2colc.get_nz_index(p2)];
00805 T x = m2colc.get_nz_data(p2);
00806 for (int p1 = 0; p1 < mcol.nnz(); p1++) {
00807 int r = mcol.get_nz_index(p1);
00808 T inc = mcol.get_nz_data(p1) * x;
00809 ret.col[c].add_elem(r, inc);
00810 }
00811 }
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 ret.compact();
00825 return ret;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 template <class T>
00866 Sparse_Vec<T> operator*(const Sparse_Mat<T> &m, const Sparse_Vec<T> &v)
00867 {
00868 it_assert_debug(m.n_cols == v.size(), "Sparse_Mat<T> * Sparse_Vec<T>");
00869
00870 Sparse_Vec<T> ret(m.n_rows);
00871
00872
00873
00874
00875 Sparse_Vec<T> vv = v;
00876
00877 for (int p2 = 0; p2 < vv.nnz(); p2++) {
00878 Sparse_Vec<T> &mcol = m.col[vv.get_nz_index(p2)];
00879 T x = vv.get_nz_data(p2);
00880 for (int p1 = 0; p1 < mcol.nnz(); p1++) {
00881 int r = mcol.get_nz_index(p1);
00882 T inc = mcol.get_nz_data(p1) * x;
00883 ret.add_elem(r, inc);
00884 }
00885 }
00886 ret.compact();
00887 return ret;
00888 }
00889
00890
00891 template <class T>
00892 Vec<T> operator*(const Sparse_Mat<T> &m, const Vec<T> &v)
00893 {
00894 it_assert_debug(m.n_cols == v.size(), "Sparse_Mat<T> * Vec<T>");
00895
00896 Vec<T> r(m.n_rows);
00897 r.clear();
00898
00899 for (int c = 0; c < m.n_cols; c++) {
00900 for (int p = 0; p < m.col[c].nnz(); p++)
00901 r(m.col[c].get_nz_index(p)) += m.col[c].get_nz_data(p) * v(c);
00902 }
00903
00904 return r;
00905 }
00906
00907 template <class T>
00908 Vec<T> operator*(const Vec<T> &v, const Sparse_Mat<T> &m)
00909 {
00910 it_assert_debug(v.size() == m.n_rows, "Vec<T> * Sparse_Mat<T>");
00911
00912 Vec<T> r(m.n_cols);
00913 r.clear();
00914
00915 for (int c = 0; c < m.n_cols; c++)
00916 r[c] = v * m.col[c];
00917
00918 return r;
00919 }
00920
00921 template <class T>
00922 Mat<T> trans_mult(const Sparse_Mat<T> &m)
00923 {
00924 Mat<T> ret(m.n_cols, m.n_cols);
00925 Vec<T> col;
00926 for (int c = 0; c < ret.cols(); c++) {
00927 m.col[c].full(col);
00928 for (int r = 0; r < c; r++) {
00929 T tmp = m.col[r] * col;
00930 ret(r, c) = tmp;
00931 ret(c, r) = tmp;
00932 }
00933 ret(c, c) = m.col[c].sqr();
00934 }
00935
00936 return ret;
00937 }
00938
00939 template <class T>
00940 Sparse_Mat<T> trans_mult_s(const Sparse_Mat<T> &m)
00941 {
00942 Sparse_Mat<T> ret(m.n_cols, m.n_cols);
00943 Vec<T> col;
00944 T tmp;
00945 for (int c = 0; c < ret.n_cols; c++) {
00946 m.col[c].full(col);
00947 for (int r = 0; r < c; r++) {
00948 tmp = m.col[r] * col;
00949 if (tmp != T(0)) {
00950 ret.col[c].set_new(r, tmp);
00951 ret.col[r].set_new(c, tmp);
00952 }
00953 }
00954 tmp = m.col[c].sqr();
00955 if (tmp != T(0))
00956 ret.col[c].set_new(c, tmp);
00957 }
00958
00959 return ret;
00960 }
00961
00962 template <class T>
00963 Sparse_Mat<T> trans_mult(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2)
00964 {
00965 it_assert_debug(m1.n_rows == m2.n_rows, "trans_mult()");
00966
00967 Sparse_Mat<T> ret(m1.n_cols, m2.n_cols);
00968 Vec<T> col;
00969 for (int c = 0; c < ret.n_cols; c++) {
00970 m2.col[c].full(col);
00971 for (int r = 0; r < ret.n_rows; r++)
00972 ret.col[c].set_new(r, m1.col[r] * col);
00973 }
00974
00975 return ret;
00976 }
00977
00978 template <class T>
00979 Vec<T> trans_mult(const Sparse_Mat<T> &m, const Vec<T> &v)
00980 {
00981 Vec<T> r(m.n_cols);
00982 for (int c = 0; c < m.n_cols; c++)
00983 r(c) = m.col[c] * v;
00984
00985 return r;
00986 }
00987
00988 template <class T>
00989 Sparse_Mat<T> mult_trans(const Sparse_Mat<T> &m1, const Sparse_Mat<T> &m2)
00990 {
00991 return trans_mult(m1.transpose(), m2.transpose());
00992 }
00993
00995 template <class T>
00996 inline Sparse_Mat<T> sparse(const Mat<T> &m, T epsilon)
00997 {
00998 Sparse_Mat<T> s(m, epsilon);
00999 return s;
01000 }
01001
01003 template <class T>
01004 inline Mat<T> full(const Sparse_Mat<T> &s)
01005 {
01006 Mat<T> m;
01007 s.full(m);
01008 return m;
01009 }
01010
01012 template <class T>
01013 inline Sparse_Mat<T> transpose(const Sparse_Mat<T> &s)
01014 {
01015 Sparse_Mat<T> m;
01016 s.transpose(m);
01017 return m;
01018 }
01019
01021
01022
01023
01024
01025
01026 #ifdef HAVE_EXTERN_TEMPLATE
01027
01028 extern template class Sparse_Mat<int>;
01029 extern template class Sparse_Mat<double>;
01030 extern template class Sparse_Mat<std::complex<double> >;
01031
01032 extern template sparse_imat operator+(const sparse_imat &, const sparse_imat &);
01033 extern template sparse_mat operator+(const sparse_mat &, const sparse_mat &);
01034 extern template sparse_cmat operator+(const sparse_cmat &, const sparse_cmat &);
01035
01036 extern template sparse_imat operator*(const sparse_imat &, const sparse_imat &);
01037 extern template sparse_mat operator*(const sparse_mat &, const sparse_mat &);
01038 extern template sparse_cmat operator*(const sparse_cmat &, const sparse_cmat &);
01039
01040 extern template ivec operator*(const ivec &, const sparse_imat &);
01041 extern template vec operator*(const vec &, const sparse_mat &);
01042 extern template cvec operator*(const cvec &, const sparse_cmat &);
01043
01044 extern template ivec operator*(const sparse_imat &, const ivec &);
01045 extern template vec operator*(const sparse_mat &, const vec &);
01046 extern template cvec operator*(const sparse_cmat &, const cvec &);
01047
01048 extern template imat trans_mult(const sparse_imat &);
01049 extern template mat trans_mult(const sparse_mat &);
01050 extern template cmat trans_mult(const sparse_cmat &);
01051
01052 extern template sparse_imat trans_mult_s(const sparse_imat &);
01053 extern template sparse_mat trans_mult_s(const sparse_mat &);
01054 extern template sparse_cmat trans_mult_s(const sparse_cmat &);
01055
01056 extern template sparse_imat trans_mult(const sparse_imat &, const sparse_imat &);
01057 extern template sparse_mat trans_mult(const sparse_mat &, const sparse_mat &);
01058 extern template sparse_cmat trans_mult(const sparse_cmat &, const sparse_cmat &);
01059
01060 extern template ivec trans_mult(const sparse_imat &, const ivec &);
01061 extern template vec trans_mult(const sparse_mat &, const vec &);
01062 extern template cvec trans_mult(const sparse_cmat &, const cvec &);
01063
01064 extern template sparse_imat mult_trans(const sparse_imat &, const sparse_imat &);
01065 extern template sparse_mat mult_trans(const sparse_mat &, const sparse_mat &);
01066 extern template sparse_cmat mult_trans(const sparse_cmat &, const sparse_cmat &);
01067
01068 #endif // HAVE_EXTERN_TEMPLATE
01069
01071
01072 }
01073
01074 #endif // #ifndef SMAT_H
01075