00001
00029 #ifndef SVEC_H
00030 #define SVEC_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/vec.h>
00039 #include <itpp/base/math/min_max.h>
00040 #include <cstdlib>
00041
00042
00043 namespace itpp
00044 {
00045
00046
00047 template <class T> class Vec;
00048
00049 template <class T> class Sparse_Vec;
00050
00051
00052
00054 template <class T>
00055 Sparse_Vec<T> operator+(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00056
00058 template <class T>
00059 T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00060
00062 template <class T>
00063 T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00064
00066 template <class T>
00067 T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00068
00070 template <class T>
00071 Sparse_Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00072
00074 template <class T>
00075 Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00076
00078 template <class T>
00079 Sparse_Vec<T> elem_mult_s(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00080
00082 template <class T>
00083 Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00084
00086 template <class T>
00087 Sparse_Vec<T> elem_mult_s(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00088
00099 template <class T>
00100 class Sparse_Vec
00101 {
00102 public:
00103
00105 Sparse_Vec();
00106
00113 Sparse_Vec(int sz, int data_init = 200);
00114
00120 Sparse_Vec(const Sparse_Vec<T> &v);
00121
00127 Sparse_Vec(const Vec<T> &v);
00128
00134 Sparse_Vec(const Vec<T> &v, T epsilon);
00135
00137 ~Sparse_Vec();
00138
00145 void set_size(int sz, int data_init = -1);
00146
00148 int size() const { return v_size; }
00149
00151 inline int nnz() {
00152 if (check_small_elems_flag) {
00153 remove_small_elements();
00154 }
00155 return used_size;
00156 }
00157
00159 double density();
00160
00162 void set_small_element(const T& epsilon);
00163
00169 void remove_small_elements();
00170
00176 void resize_data(int new_size);
00177
00179 void compact();
00180
00182 void full(Vec<T> &v) const;
00183
00185 Vec<T> full() const;
00186
00188 T operator()(int i) const;
00189
00191 void set(int i, T v);
00192
00194 void set(const ivec &index_vec, const Vec<T> &v);
00195
00197 void set_new(int i, T v);
00198
00200 void set_new(const ivec &index_vec, const Vec<T> &v);
00201
00203 void add_elem(const int i, const T v);
00204
00206 void add(const ivec &index_vec, const Vec<T> &v);
00207
00209 void zeros();
00210
00212 void zero_elem(const int i);
00213
00215 void clear();
00216
00218 void clear_elem(const int i);
00219
00223 inline void get_nz_data(int p, T& data_out) {
00224 if (check_small_elems_flag) {
00225 remove_small_elements();
00226 }
00227 data_out = data[p];
00228 }
00229
00231 inline T get_nz_data(int p) {
00232 if (check_small_elems_flag) {
00233 remove_small_elements();
00234 }
00235 return data[p];
00236 }
00237
00239 inline int get_nz_index(int p) {
00240 if (check_small_elems_flag) {
00241 remove_small_elements();
00242 }
00243 return index[p];
00244 }
00245
00247 inline void get_nz(int p, int &idx, T &dat) {
00248 if (check_small_elems_flag) {
00249 remove_small_elements();
00250 }
00251 idx = index[p];
00252 dat = data[p];
00253 }
00254
00256 ivec get_nz_indices();
00257
00259 Sparse_Vec<T> get_subvector(int i1, int i2) const;
00260
00262 T sqr() const;
00263
00265 void operator=(const Sparse_Vec<T> &v);
00267 void operator=(const Vec<T> &v);
00268
00270 Sparse_Vec<T> operator-() const;
00271
00273 bool operator==(const Sparse_Vec<T> &v);
00274
00276 void operator+=(const Sparse_Vec<T> &v);
00277
00279 void operator+=(const Vec<T> &v);
00280
00282 void operator-=(const Sparse_Vec<T> &v);
00283
00285 void operator-=(const Vec<T> &v);
00286
00288 void operator*=(const T &v);
00289
00291 void operator/=(const T &v);
00292
00294 friend Sparse_Vec<T> operator+<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00296 friend T operator*<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00298 friend T operator*<>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00300 friend T operator*<>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00301
00303 friend Sparse_Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
00304
00306 friend Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00307
00309 friend Sparse_Vec<T> elem_mult_s <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
00310
00312 friend Vec<T> elem_mult <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00313
00315 friend Sparse_Vec<T> elem_mult_s <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
00316
00317 private:
00318 void init();
00319 void alloc();
00320 void free();
00321
00322 int v_size, used_size, data_size;
00323 T *data;
00324 int *index;
00325 T eps;
00326 bool check_small_elems_flag;
00327 };
00328
00329
00334 typedef Sparse_Vec<int> sparse_ivec;
00335
00340 typedef Sparse_Vec<double> sparse_vec;
00341
00346 typedef Sparse_Vec<std::complex<double> > sparse_cvec;
00347
00348
00349
00350 template <class T>
00351 void Sparse_Vec<T>::init()
00352 {
00353 v_size = 0;
00354 used_size = 0;
00355 data_size = 0;
00356 data = 0;
00357 index = 0;
00358 eps = 0;
00359 check_small_elems_flag = true;
00360 }
00361
00362 template <class T>
00363 void Sparse_Vec<T>::alloc()
00364 {
00365 if (data_size != 0) {
00366 data = new T[data_size];
00367 index = new int[data_size];
00368 }
00369 }
00370
00371 template <class T>
00372 void Sparse_Vec<T>::free()
00373 {
00374 delete [] data;
00375 data = 0;
00376 delete [] index;
00377 index = 0;
00378 }
00379
00380 template <class T>
00381 Sparse_Vec<T>::Sparse_Vec()
00382 {
00383 init();
00384 }
00385
00386 template <class T>
00387 Sparse_Vec<T>::Sparse_Vec(int sz, int data_init)
00388 {
00389 init();
00390 v_size = sz;
00391 used_size = 0;
00392 data_size = data_init;
00393 alloc();
00394 }
00395
00396 template <class T>
00397 Sparse_Vec<T>::Sparse_Vec(const Sparse_Vec<T> &v)
00398 {
00399 init();
00400 v_size = v.v_size;
00401 used_size = v.used_size;
00402 data_size = v.data_size;
00403 eps = v.eps;
00404 check_small_elems_flag = v.check_small_elems_flag;
00405 alloc();
00406
00407 for (int i = 0; i < used_size; i++) {
00408 data[i] = v.data[i];
00409 index[i] = v.index[i];
00410 }
00411 }
00412
00413 template <class T>
00414 Sparse_Vec<T>::Sparse_Vec(const Vec<T> &v)
00415 {
00416 init();
00417 v_size = v.size();
00418 used_size = 0;
00419 data_size = std::min(v.size(), 10000);
00420 alloc();
00421
00422 for (int i = 0; i < v_size; i++) {
00423 if (v(i) != T(0)) {
00424 if (used_size == data_size)
00425 resize_data(data_size*2);
00426 data[used_size] = v(i);
00427 index[used_size] = i;
00428 used_size++;
00429 }
00430 }
00431 compact();
00432 }
00433
00434 template <class T>
00435 Sparse_Vec<T>::Sparse_Vec(const Vec<T> &v, T epsilon)
00436 {
00437 init();
00438 v_size = v.size();
00439 used_size = 0;
00440 data_size = std::min(v.size(), 10000);
00441 eps = epsilon;
00442 alloc();
00443
00444 double e = std::abs(epsilon);
00445 for (int i = 0; i < v_size; i++) {
00446 if (std::abs(v(i)) > e) {
00447 if (used_size == data_size)
00448 resize_data(data_size*2);
00449 data[used_size] = v(i);
00450 index[used_size] = i;
00451 used_size++;
00452 }
00453 }
00454 compact();
00455 }
00456
00457 template <class T>
00458 Sparse_Vec<T>::~Sparse_Vec()
00459 {
00460 free();
00461 }
00462
00463 template <class T>
00464 void Sparse_Vec<T>::set_size(int new_size, int data_init)
00465 {
00466 v_size = new_size;
00467 used_size = 0;
00468 if (data_init != -1) {
00469 free();
00470 data_size = data_init;
00471 alloc();
00472 }
00473 }
00474
00475 template <class T>
00476 double Sparse_Vec<T>::density()
00477 {
00478 if (check_small_elems_flag) {
00479 remove_small_elements();
00480 }
00481
00482 return double(used_size) / v_size;
00483 }
00484
00485 template <class T>
00486 void Sparse_Vec<T>::set_small_element(const T& epsilon)
00487 {
00488 eps = epsilon;
00489 remove_small_elements();
00490 }
00491
00492 template <class T>
00493 void Sparse_Vec<T>::remove_small_elements()
00494 {
00495 int i;
00496 int nrof_removed_elements = 0;
00497 double e;
00498
00499
00500 e = std::abs(eps);
00501 for (i = 0;i < used_size;i++) {
00502 if (std::abs(data[i]) <= e) {
00503 nrof_removed_elements++;
00504 }
00505 else if (nrof_removed_elements > 0) {
00506 data[i-nrof_removed_elements] = data[i];
00507 index[i-nrof_removed_elements] = index[i];
00508 }
00509 }
00510
00511
00512 used_size -= nrof_removed_elements;
00513
00514
00515 check_small_elems_flag = false;
00516 }
00517
00518
00519 template <class T>
00520 void Sparse_Vec<T>::resize_data(int new_size)
00521 {
00522 it_assert(new_size >= used_size, "Sparse_Vec<T>::resize_data(int new_size): New size is to small");
00523
00524 if (new_size != data_size) {
00525 if (new_size == 0)
00526 free();
00527 else {
00528 T *tmp_data = data;
00529 int *tmp_pos = index;
00530 data_size = new_size;
00531 alloc();
00532 for (int p = 0; p < used_size; p++) {
00533 data[p] = tmp_data[p];
00534 index[p] = tmp_pos[p];
00535 }
00536 delete [] tmp_data;
00537 delete [] tmp_pos;
00538 }
00539 }
00540 }
00541
00542 template <class T>
00543 void Sparse_Vec<T>::compact()
00544 {
00545 if (check_small_elems_flag) {
00546 remove_small_elements();
00547 }
00548 resize_data(used_size);
00549 }
00550
00551 template <class T>
00552 void Sparse_Vec<T>::full(Vec<T> &v) const
00553 {
00554 v.set_size(v_size);
00555
00556 v = T(0);
00557 for (int p = 0; p < used_size; p++)
00558 v(index[p]) = data[p];
00559 }
00560
00561 template <class T>
00562 Vec<T> Sparse_Vec<T>::full() const
00563 {
00564 Vec<T> r(v_size);
00565 full(r);
00566 return r;
00567 }
00568
00569
00570 template <class T>
00571 T Sparse_Vec<T>::operator()(int i) const
00572 {
00573 it_assert_debug(i >= 0 && i < v_size, "The index of the element is out of range");
00574
00575 bool found = false;
00576 int p;
00577 for (p = 0; p < used_size; p++) {
00578 if (index[p] == i) {
00579 found = true;
00580 break;
00581 }
00582 }
00583 return found ? data[p] : T(0);
00584 }
00585
00586 template <class T>
00587 void Sparse_Vec<T>::set(int i, T v)
00588 {
00589 it_assert_debug(i >= 0 && i < v_size, "The index of the element is out of range");
00590
00591 bool found = false;
00592 bool larger_than_eps;
00593 int p;
00594
00595 for (p = 0; p < used_size; p++) {
00596 if (index[p] == i) {
00597 found = true;
00598 break;
00599 }
00600 }
00601
00602 larger_than_eps = (std::abs(v) > std::abs(eps));
00603
00604 if (found && larger_than_eps)
00605 data[p] = v;
00606 else if (larger_than_eps) {
00607 if (used_size == data_size)
00608 resize_data(data_size*2 + 100);
00609 data[used_size] = v;
00610 index[used_size] = i;
00611 used_size++;
00612 }
00613
00614
00615 if (std::abs(v) <= std::abs(eps)) {
00616 remove_small_elements();
00617 }
00618
00619 }
00620
00621 template <class T>
00622 void Sparse_Vec<T>::set_new(int i, T v)
00623 {
00624 it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
00625
00626
00627 if (std::abs(v) > std::abs(eps)) {
00628 if (used_size == data_size)
00629 resize_data(data_size*2 + 100);
00630 data[used_size] = v;
00631 index[used_size] = i;
00632 used_size++;
00633 }
00634 }
00635
00636 template <class T>
00637 void Sparse_Vec<T>::add_elem(const int i, const T v)
00638 {
00639 bool found = false;
00640 int p;
00641
00642 it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
00643
00644 for (p = 0; p < used_size; p++) {
00645 if (index[p] == i) {
00646 found = true;
00647 break;
00648 }
00649 }
00650 if (found)
00651 data[p] += v;
00652 else {
00653 if (used_size == data_size)
00654 resize_data(data_size*2 + 100);
00655 data[used_size] = v;
00656 index[used_size] = i;
00657 used_size++;
00658 }
00659
00660 check_small_elems_flag = true;
00661
00662 }
00663
00664 template <class T>
00665 void Sparse_Vec<T>::add(const ivec& index_vec, const Vec<T>& v)
00666 {
00667 bool found = false;
00668 int i, p, q;
00669 int nrof_nz = v.size();
00670
00671 it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
00672
00673
00674 for (q = 0; q < nrof_nz; q++) {
00675 i = index_vec(q);
00676 for (p = 0; p < used_size; p++) {
00677 if (index[p] == i) {
00678 found = true;
00679 break;
00680 }
00681 }
00682 if (found)
00683 data[p] += v(q);
00684 else {
00685 if (used_size == data_size)
00686 resize_data(data_size*2 + 100);
00687 data[used_size] = v(q);
00688 index[used_size] = i;
00689 used_size++;
00690 }
00691 found = false;
00692 }
00693
00694 check_small_elems_flag = true;
00695
00696 }
00697
00698 template <class T>
00699 void Sparse_Vec<T>::zeros()
00700 {
00701 used_size = 0;
00702 check_small_elems_flag = false;
00703 }
00704
00705 template <class T>
00706 void Sparse_Vec<T>::zero_elem(const int i)
00707 {
00708 bool found = false;
00709 int p;
00710
00711 it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
00712
00713 for (p = 0; p < used_size; p++) {
00714 if (index[p] == i) {
00715 found = true;
00716 break;
00717 }
00718 }
00719 if (found) {
00720 data[p] = data[used_size-1];
00721 index[p] = index[used_size-1];
00722 used_size--;
00723 }
00724 }
00725
00726 template <class T>
00727 void Sparse_Vec<T>::clear()
00728 {
00729 used_size = 0;
00730 check_small_elems_flag = false;
00731 }
00732
00733 template <class T>
00734 void Sparse_Vec<T>::clear_elem(const int i)
00735 {
00736 bool found = false;
00737 int p;
00738
00739 it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
00740
00741 for (p = 0; p < used_size; p++) {
00742 if (index[p] == i) {
00743 found = true;
00744 break;
00745 }
00746 }
00747 if (found) {
00748 data[p] = data[used_size-1];
00749 index[p] = index[used_size-1];
00750 used_size--;
00751 }
00752 }
00753
00754 template <class T>
00755 void Sparse_Vec<T>::set(const ivec& index_vec, const Vec<T>& v)
00756 {
00757 it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
00758
00759
00760 clear();
00761
00762
00763 add(index_vec, v);
00764 }
00765
00766 template <class T>
00767 void Sparse_Vec<T>::set_new(const ivec& index_vec, const Vec<T>& v)
00768 {
00769 int q;
00770 int nrof_nz = v.size();
00771
00772 it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
00773
00774
00775 clear();
00776
00777 for (q = 0; q < nrof_nz; q++) {
00778 if (std::abs(v[q]) > std::abs(eps)) {
00779 if (used_size == data_size)
00780 resize_data(data_size*2 + 100);
00781 data[used_size] = v(q);
00782 index[used_size] = index_vec(q);
00783 used_size++;
00784 }
00785 }
00786 }
00787
00788 template <class T>
00789 ivec Sparse_Vec<T>::get_nz_indices()
00790 {
00791 int n = nnz();
00792 ivec r(n);
00793 for (int i = 0; i < n; i++) {
00794 r(i) = get_nz_index(i);
00795 }
00796 return r;
00797 }
00798
00799 template <class T>
00800 Sparse_Vec<T> Sparse_Vec<T>::get_subvector(int i1, int i2) const
00801 {
00802 it_assert_debug(v_size > i1 && v_size > i2 && i1 <= i2 && i1 >= 0, "The index of the element exceeds the size of the sparse vector");
00803
00804 Sparse_Vec<T> r(i2 - i1 + 1);
00805
00806 for (int p = 0; p < used_size; p++) {
00807 if (index[p] >= i1 && index[p] <= i2) {
00808 if (r.used_size == r.data_size)
00809 r.resize_data(r.data_size*2 + 100);
00810 r.data[r.used_size] = data[p];
00811 r.index[r.used_size] = index[p] - i1;
00812 r.used_size++;
00813 }
00814 }
00815 r.eps = eps;
00816 r.check_small_elems_flag = check_small_elems_flag;
00817 r.compact();
00818
00819 return r;
00820 }
00821
00822 template <class T>
00823 T Sparse_Vec<T>::sqr() const
00824 {
00825 T sum(0);
00826 for (int p = 0; p < used_size; p++)
00827 sum += data[p] * data[p];
00828
00829 return sum;
00830 }
00831
00832 template <class T>
00833 void Sparse_Vec<T>::operator=(const Sparse_Vec<T> &v)
00834 {
00835 free();
00836 v_size = v.v_size;
00837 used_size = v.used_size;
00838 data_size = v.data_size;
00839 eps = v.eps;
00840 check_small_elems_flag = v.check_small_elems_flag;
00841 alloc();
00842
00843 for (int i = 0; i < used_size; i++) {
00844 data[i] = v.data[i];
00845 index[i] = v.index[i];
00846 }
00847 }
00848
00849 template <class T>
00850 void Sparse_Vec<T>::operator=(const Vec<T> &v)
00851 {
00852 free();
00853 v_size = v.size();
00854 used_size = 0;
00855 data_size = std::min(v.size(), 10000);
00856 eps = T(0);
00857 check_small_elems_flag = false;
00858 alloc();
00859
00860 for (int i = 0; i < v_size; i++) {
00861 if (v(i) != T(0)) {
00862 if (used_size == data_size)
00863 resize_data(data_size*2);
00864 data[used_size] = v(i);
00865 index[used_size] = i;
00866 used_size++;
00867 }
00868 }
00869 compact();
00870 }
00871
00872 template <class T>
00873 Sparse_Vec<T> Sparse_Vec<T>::operator-() const
00874 {
00875 Sparse_Vec r(v_size, used_size);
00876
00877 for (int p = 0; p < used_size; p++) {
00878 r.data[p] = -data[p];
00879 r.index[p] = index[p];
00880 }
00881 r.used_size = used_size;
00882
00883 return r;
00884 }
00885
00886 template <class T>
00887 bool Sparse_Vec<T>::operator==(const Sparse_Vec<T> &v)
00888 {
00889 int p, q;
00890 bool found = false;
00891
00892
00893 if (check_small_elems_flag)
00894 remove_small_elements();
00895
00896 if (v_size != v.v_size) {
00897
00898 return false;
00899 }
00900 else {
00901 for (p = 0;p < used_size;p++) {
00902 for (q = 0;q < v.used_size;q++) {
00903 if (index[p] == v.index[q]) {
00904 found = true;
00905 break;
00906 }
00907 }
00908 if (found == false)
00909
00910 return false;
00911 else if (data[p] != v.data[q])
00912
00913 return false;
00914 else
00915
00916 found = false;
00917 }
00918 }
00919
00920
00921
00922 if (used_size != v.used_size) {
00923 if (used_size > v.used_size) {
00924
00925 return false;
00926 }
00927 else {
00928
00929 int nrof_small_elems = 0;
00930 for (q = 0;q < v.used_size;q++) {
00931 if (std::abs(v.data[q]) <= std::abs(v.eps))
00932 nrof_small_elems++;
00933 }
00934 if (v.used_size - nrof_small_elems != used_size)
00935
00936 return false;
00937 }
00938 }
00939
00940
00941 return true;
00942 }
00943
00944 template <class T>
00945 void Sparse_Vec<T>::operator+=(const Sparse_Vec<T> &v)
00946 {
00947 int i, p;
00948 T tmp_data;
00949 int nrof_nz_v = v.used_size;
00950
00951 it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
00952
00953 for (p = 0; p < nrof_nz_v; p++) {
00954 i = v.index[p];
00955 tmp_data = v.data[p];
00956
00957 add_elem(i, tmp_data);
00958 }
00959
00960 check_small_elems_flag = true;
00961 }
00962
00963 template <class T>
00964 void Sparse_Vec<T>::operator+=(const Vec<T> &v)
00965 {
00966 int i;
00967
00968 it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
00969
00970 for (i = 0; i < v.size(); i++)
00971 if (v(i) != T(0))
00972 add_elem(i, v(i));
00973
00974 check_small_elems_flag = true;
00975 }
00976
00977
00978 template <class T>
00979 void Sparse_Vec<T>::operator-=(const Sparse_Vec<T> &v)
00980 {
00981 int i, p;
00982 T tmp_data;
00983 int nrof_nz_v = v.used_size;
00984
00985 it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
00986
00987 for (p = 0; p < nrof_nz_v; p++) {
00988 i = v.index[p];
00989 tmp_data = v.data[p];
00990
00991 add_elem(i, -tmp_data);
00992 }
00993
00994 check_small_elems_flag = true;
00995 }
00996
00997 template <class T>
00998 void Sparse_Vec<T>::operator-=(const Vec<T> &v)
00999 {
01000 int i;
01001
01002 it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
01003
01004 for (i = 0; i < v.size(); i++)
01005 if (v(i) != T(0))
01006 add_elem(i, -v(i));
01007
01008 check_small_elems_flag = true;
01009 }
01010
01011 template <class T>
01012 void Sparse_Vec<T>::operator*=(const T &v)
01013 {
01014 int p;
01015
01016 for (p = 0; p < used_size; p++) {
01017 data[p] *= v;
01018 }
01019
01020 check_small_elems_flag = true;
01021 }
01022
01023 template <class T>
01024 void Sparse_Vec<T>::operator/=(const T &v)
01025 {
01026 int p;
01027 for (p = 0; p < used_size; p++) {
01028 data[p] /= v;
01029 }
01030
01031 if (std::abs(eps) > 0) {
01032 check_small_elems_flag = true;
01033 }
01034 }
01035
01036 template <class T>
01037 T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
01038 {
01039 it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> * Sparse_Vec<T>");
01040
01041 T sum(0);
01042 Vec<T> v1f(v1.v_size);
01043 v1.full(v1f);
01044 for (int p = 0; p < v2.used_size; p++) {
01045 if (v1f[v2.index[p]] != T(0))
01046 sum += v1f[v2.index[p]] * v2.data[p];
01047 }
01048
01049 return sum;
01050 }
01051
01052 template <class T>
01053 T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2)
01054 {
01055 it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
01056
01057 T sum(0);
01058 for (int p1 = 0; p1 < v1.used_size; p1++)
01059 sum += v1.data[p1] * v2[v1.index[p1]];
01060
01061 return sum;
01062 }
01063
01064 template <class T>
01065 T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2)
01066 {
01067 it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
01068
01069 T sum(0);
01070 for (int p2 = 0; p2 < v2.used_size; p2++)
01071 sum += v1[v2.index[p2]] * v2.data[p2];
01072
01073 return sum;
01074 }
01075
01076 template <class T>
01077 Sparse_Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
01078 {
01079 it_assert_debug(v1.v_size == v2.v_size, "elem_mult(Sparse_Vec<T>, Sparse_Vec<T>)");
01080
01081 Sparse_Vec<T> r(v1.v_size);
01082 ivec pos(v1.v_size);
01083 pos = -1;
01084 for (int p1 = 0; p1 < v1.used_size; p1++)
01085 pos[v1.index[p1]] = p1;
01086 for (int p2 = 0; p2 < v2.used_size; p2++) {
01087 if (pos[v2.index[p2]] != -1) {
01088 if (r.used_size == r.data_size)
01089 r.resize_data(r.used_size*2 + 100);
01090 r.data[r.used_size] = v1.data[pos[v2.index[p2]]] * v2.data[p2];
01091 r.index[r.used_size] = v2.index[p2];
01092 r.used_size++;
01093 }
01094 }
01095 r.compact();
01096
01097 return r;
01098 }
01099
01100 template <class T>
01101 Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2)
01102 {
01103 it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
01104
01105 Vec<T> r(v1.v_size);
01106 r = T(0);
01107 for (int p1 = 0; p1 < v1.used_size; p1++)
01108 r[v1.index[p1]] = v1.data[p1] * v2[v1.index[p1]];
01109
01110 return r;
01111 }
01112
01113 template <class T>
01114 Sparse_Vec<T> elem_mult_s(const Sparse_Vec<T> &v1, const Vec<T> &v2)
01115 {
01116 it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
01117
01118 Sparse_Vec<T> r(v1.v_size);
01119 for (int p1 = 0; p1 < v1.used_size; p1++) {
01120 if (v2[v1.index[p1]] != T(0)) {
01121 if (r.used_size == r.data_size)
01122 r.resize_data(r.used_size*2 + 100);
01123 r.data[r.used_size] = v1.data[p1] * v2[v1.index[p1]];
01124 r.index[r.used_size] = v1.index[p1];
01125 r.used_size++;
01126 }
01127 }
01128 r.compact();
01129
01130 return r;
01131 }
01132
01133 template <class T>
01134 Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2)
01135 {
01136 it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
01137
01138 Vec<T> r(v2.v_size);
01139 r = T(0);
01140 for (int p2 = 0; p2 < v2.used_size; p2++)
01141 r[v2.index[p2]] = v1[v2.index[p2]] * v2.data[p2];
01142
01143 return r;
01144 }
01145
01146 template <class T>
01147 Sparse_Vec<T> elem_mult_s(const Vec<T> &v1, const Sparse_Vec<T> &v2)
01148 {
01149 it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
01150
01151 Sparse_Vec<T> r(v2.v_size);
01152 for (int p2 = 0; p2 < v2.used_size; p2++) {
01153 if (v1[v2.index[p2]] != T(0)) {
01154 if (r.used_size == r.data_size)
01155 r.resize_data(r.used_size*2 + 100);
01156 r.data[r.used_size] = v1[v2.index[p2]] * v2.data[p2];
01157 r.index[r.used_size] = v2.index[p2];
01158 r.used_size++;
01159 }
01160 }
01161 r.compact();
01162
01163 return r;
01164 }
01165
01166 template <class T>
01167 Sparse_Vec<T> operator+(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
01168 {
01169 it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> + Sparse_Vec<T>");
01170
01171 Sparse_Vec<T> r(v1);
01172 ivec pos(v1.v_size);
01173 pos = -1;
01174 for (int p1 = 0; p1 < v1.used_size; p1++)
01175 pos[v1.index[p1]] = p1;
01176 for (int p2 = 0; p2 < v2.used_size; p2++) {
01177 if (pos[v2.index[p2]] == -1) {
01178 if (r.used_size == r.data_size)
01179 r.resize_data(r.used_size*2 + 100);
01180 r.data[r.used_size] = v2.data[p2];
01181 r.index[r.used_size] = v2.index[p2];
01182 r.used_size++;
01183 }
01184 else
01185 r.data[pos[v2.index[p2]]] += v2.data[p2];
01186 }
01187 r.check_small_elems_flag = true;
01188 r.compact();
01189
01190 return r;
01191 }
01192
01194 template <class T>
01195 inline Sparse_Vec<T> sparse(const Vec<T> &v)
01196 {
01197 Sparse_Vec<T> s(v);
01198 return s;
01199 }
01200
01202 template <class T>
01203 inline Sparse_Vec<T> sparse(const Vec<T> &v, T epsilon)
01204 {
01205 Sparse_Vec<T> s(v, epsilon);
01206 return s;
01207 }
01208
01210 template <class T>
01211 inline Vec<T> full(const Sparse_Vec<T> &s)
01212 {
01213 Vec<T> v;
01214 s.full(v);
01215 return v;
01216 }
01217
01219
01220
01221
01222
01223
01224 #ifdef HAVE_EXTERN_TEMPLATE
01225
01226 extern template class Sparse_Vec<int>;
01227 extern template class Sparse_Vec<double>;
01228 extern template class Sparse_Vec<std::complex<double> >;
01229
01230 extern template sparse_ivec operator+(const sparse_ivec &,
01231 const sparse_ivec &);
01232 extern template sparse_vec operator+(const sparse_vec &,
01233 const sparse_vec &);
01234 extern template sparse_cvec operator+(const sparse_cvec &,
01235 const sparse_cvec &);
01236
01237 extern template int operator*(const sparse_ivec &, const sparse_ivec &);
01238 extern template double operator*(const sparse_vec &, const sparse_vec &);
01239 extern template std::complex<double> operator*(const sparse_cvec &,
01240 const sparse_cvec &);
01241
01242 extern template int operator*(const sparse_ivec &, const ivec &);
01243 extern template double operator*(const sparse_vec &, const vec &);
01244 extern template std::complex<double> operator*(const sparse_cvec &,
01245 const cvec &);
01246
01247 extern template int operator*(const ivec &, const sparse_ivec &);
01248 extern template double operator*(const vec &, const sparse_vec &);
01249 extern template std::complex<double> operator*(const cvec &,
01250 const sparse_cvec &);
01251
01252 extern template sparse_ivec elem_mult(const sparse_ivec &,
01253 const sparse_ivec &);
01254 extern template sparse_vec elem_mult(const sparse_vec &, const sparse_vec &);
01255 extern template sparse_cvec elem_mult(const sparse_cvec &,
01256 const sparse_cvec &);
01257
01258 extern template ivec elem_mult(const sparse_ivec &, const ivec &);
01259 extern template vec elem_mult(const sparse_vec &, const vec &);
01260 extern template cvec elem_mult(const sparse_cvec &, const cvec &);
01261
01262 extern template sparse_ivec elem_mult_s(const sparse_ivec &, const ivec &);
01263 extern template sparse_vec elem_mult_s(const sparse_vec &, const vec &);
01264 extern template sparse_cvec elem_mult_s(const sparse_cvec &, const cvec &);
01265
01266 extern template ivec elem_mult(const ivec &, const sparse_ivec &);
01267 extern template vec elem_mult(const vec &, const sparse_vec &);
01268 extern template cvec elem_mult(const cvec &, const sparse_cvec &);
01269
01270 extern template sparse_ivec elem_mult_s(const ivec &, const sparse_ivec &);
01271 extern template sparse_vec elem_mult_s(const vec &, const sparse_vec &);
01272 extern template sparse_cvec elem_mult_s(const cvec &, const sparse_cvec &);
01273
01274 #endif // HAVE_EXTERN_TEMPLATE
01275
01277
01278 }
01279
01280 #endif // #ifndef SVEC_H
01281