IT++ Logo
svec.h
Go to the documentation of this file.
1 
29 #ifndef SVEC_H
30 #define SVEC_H
31 
32 #include <itpp/base/vec.h>
33 #include <itpp/base/math/min_max.h>
34 #include <cstdlib>
35 #include <itpp/itexports.h>
36 
37 namespace itpp
38 {
39 
40 // Declaration of class Vec
41 template <class T> class Vec;
42 // Declaration of class Sparse_Vec
43 template <class T> class Sparse_Vec;
44 
45 // ----------------------- Sparse_Vec Friends -------------------------------
46 
48 template <class T>
49 Sparse_Vec<T> operator+(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
50 
52 template <class T>
53 T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
54 
56 template <class T>
57 T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2);
58 
60 template <class T>
61 T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2);
62 
64 template <class T>
65 Sparse_Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
66 
68 template <class T>
69 Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2);
70 
72 template <class T>
73 Sparse_Vec<T> elem_mult_s(const Sparse_Vec<T> &v1, const Vec<T> &v2);
74 
76 template <class T>
77 Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2);
78 
80 template <class T>
81 Sparse_Vec<T> elem_mult_s(const Vec<T> &v1, const Sparse_Vec<T> &v2);
82 
83 namespace details
84 {
85  //this template selects appropriate type for Eps value used to remove small elements from
86  //sparse containers
87  template <typename NumT> struct Sparse_Eps_Type_Selector;
88  template <> struct Sparse_Eps_Type_Selector<double> {typedef double eps_type;};
89  template <> struct Sparse_Eps_Type_Selector<std::complex<double> > {typedef double eps_type;};
90  template <> struct Sparse_Eps_Type_Selector<int> {typedef int eps_type;};
91  template <> struct Sparse_Eps_Type_Selector<short> {typedef short eps_type;};
92  template <> struct Sparse_Eps_Type_Selector<itpp::bin> {typedef int eps_type;};
93 }
94 
95 
106 template <class T>
108 {
109 public:
110 
112  Sparse_Vec();
113 
120  Sparse_Vec(int sz, int data_init = 200);
121 
127  Sparse_Vec(const Sparse_Vec<T> &v);
128 
134  Sparse_Vec(const Vec<T> &v);
135 
141  Sparse_Vec(const Vec<T> &v, T epsilon);
142 
144  ~Sparse_Vec();
145 
152  void set_size(int sz, int data_init = -1);
153 
155  int size() const { return v_size; }
156 
158  inline int nnz() {
159  if (check_small_elems_flag) {
161  }
162  return used_size;
163  }
164 
166  double density();
167 
169  void set_small_element(const T& epsilon);
170 
176  void remove_small_elements();
177 
183  void resize_data(int new_size);
184 
186  void compact();
187 
189  void full(Vec<T> &v) const;
190 
192  Vec<T> full() const;
193 
195  T operator()(int i) const;
196 
198  void set(int i, T v);
199 
201  void set(const ivec &index_vec, const Vec<T> &v);
202 
204  void set_new(int i, T v);
205 
207  void set_new(const ivec &index_vec, const Vec<T> &v);
208 
210  void add_elem(const int i, const T v);
211 
213  void add(const ivec &index_vec, const Vec<T> &v);
214 
216  void zeros();
217 
219  void zero_elem(const int i);
220 
222  void clear();
223 
225  void clear_elem(const int i);
226 
230  inline void get_nz_data(int p, T& data_out) {
231  if (check_small_elems_flag) {
233  }
234  data_out = data[p];
235  }
236 
238  inline T get_nz_data(int p) {
239  if (check_small_elems_flag) {
241  }
242  return data[p];
243  }
244 
246  inline int get_nz_index(int p) {
247  if (check_small_elems_flag) {
249  }
250  return index[p];
251  }
252 
254  inline void get_nz(int p, int &idx, T &dat) {
255  if (check_small_elems_flag) {
257  }
258  idx = index[p];
259  dat = data[p];
260  }
261 
263  ivec get_nz_indices();
264 
266  Sparse_Vec<T> get_subvector(int i1, int i2) const;
267 
269  T sqr() const;
270 
272  void operator=(const Sparse_Vec<T> &v);
274  void operator=(const Vec<T> &v);
275 
277  Sparse_Vec<T> operator-() const;
278 
280  bool operator==(const Sparse_Vec<T> &v);
281 
283  void operator+=(const Sparse_Vec<T> &v);
284 
286  void operator+=(const Vec<T> &v);
287 
289  void operator-=(const Sparse_Vec<T> &v);
290 
292  void operator-=(const Vec<T> &v);
293 
295  void operator*=(const T &v);
296 
298  void operator/=(const T &v);
299 
301  friend Sparse_Vec<T> operator+<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
303  friend T operator*<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
305  friend T operator*<>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
307  friend T operator*<>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
308 
310  friend Sparse_Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
311 
313  friend Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
314 
316  friend Sparse_Vec<T> elem_mult_s <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
317 
319  friend Vec<T> elem_mult <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
320 
322  friend Sparse_Vec<T> elem_mult_s <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
323 
324 private:
325  void init();
326  void alloc();
327  void free();
328 
329  int v_size, used_size, data_size;
330  T *data;
331  int *index;
332  typename details::Sparse_Eps_Type_Selector<T>::eps_type eps;
333  bool check_small_elems_flag;
334 };
335 
336 
341 typedef Sparse_Vec<int> sparse_ivec;
342 
347 typedef Sparse_Vec<double> sparse_vec;
348 
353 typedef Sparse_Vec<std::complex<double> > sparse_cvec;
354 
355 // ----------------------- Implementation starts here --------------------------------
356 
357 template <class T>
358 void Sparse_Vec<T>::init()
359 {
360  v_size = 0;
361  used_size = 0;
362  data_size = 0;
363  data = 0;
364  index = 0;
365  eps = 0;
366  check_small_elems_flag = true;
367 }
368 
369 template <class T>
370 void Sparse_Vec<T>::alloc()
371 {
372  if (data_size != 0) {
373  data = new T[data_size];
374  index = new int[data_size];
375  }
376 }
377 
378 template <class T>
379 void Sparse_Vec<T>::free()
380 {
381  delete [] data;
382  data = 0;
383  delete [] index;
384  index = 0;
385 }
386 
387 template <class T>
389 {
390  init();
391 }
392 
393 template <class T>
394 Sparse_Vec<T>::Sparse_Vec(int sz, int data_init)
395 {
396  init();
397  v_size = sz;
398  used_size = 0;
399  data_size = data_init;
400  alloc();
401 }
402 
403 template <class T>
405 {
406  init();
407  v_size = v.v_size;
408  used_size = v.used_size;
409  data_size = v.data_size;
410  eps = v.eps;
411  check_small_elems_flag = v.check_small_elems_flag;
412  alloc();
413 
414  for (int i = 0; i < used_size; i++) {
415  data[i] = v.data[i];
416  index[i] = v.index[i];
417  }
418 }
419 
420 template <class T>
422 {
423  init();
424  v_size = v.size();
425  used_size = 0;
426  data_size = std::min(v.size(), 10000);
427  alloc();
428 
429  for (int i = 0; i < v_size; i++) {
430  if (v(i) != T(0)) {
431  if (used_size == data_size)
432  resize_data(data_size*2);
433  data[used_size] = v(i);
434  index[used_size] = i;
435  used_size++;
436  }
437  }
438  compact();
439 }
440 
441 template <class T>
442 Sparse_Vec<T>::Sparse_Vec(const Vec<T> &v, T epsilon)
443 {
444  init();
445  v_size = v.size();
446  used_size = 0;
447  data_size = std::min(v.size(), 10000);
448  eps = std::abs(epsilon);
449  alloc();
450 
451  for (int i = 0; i < v_size; i++) {
452  if (std::abs(v(i)) > eps) {
453  if (used_size == data_size)
454  resize_data(data_size*2);
455  data[used_size] = v(i);
456  index[used_size] = i;
457  used_size++;
458  }
459  }
460  compact();
461 }
462 
463 template <class T>
465 {
466  free();
467 }
468 
469 template <class T>
470 void Sparse_Vec<T>::set_size(int new_size, int data_init)
471 {
472  v_size = new_size;
473  used_size = 0;
474  if (data_init != -1) {
475  free();
476  data_size = data_init;
477  alloc();
478  }
479 }
480 
481 template <class T>
483 {
484  if (check_small_elems_flag) {
485  remove_small_elements();
486  }
487  //return static_cast<double>(used_size) / v_size;
488  return double(used_size) / v_size;
489 }
490 
491 template <class T>
492 void Sparse_Vec<T>::set_small_element(const T& epsilon)
493 {
494  eps = std::abs(epsilon);
495  remove_small_elements();
496 }
497 
498 template <class T>
500 {
501  int i;
502  int nrof_removed_elements = 0;
503 
504  //Remove small elements
505  for (i = 0;i < used_size;i++) {
506  if (std::abs(data[i]) <= eps) {
507  nrof_removed_elements++;
508  }
509  else if (nrof_removed_elements > 0) {
510  data[i-nrof_removed_elements] = data[i];
511  index[i-nrof_removed_elements] = index[i];
512  }
513  }
514 
515  //Set new size after small elements have been removed
516  used_size -= nrof_removed_elements;
517 
518  //Set the flag to indicate that all small elements have been removed
519  check_small_elems_flag = false;
520 }
521 
522 
523 template <class T>
524 void Sparse_Vec<T>::resize_data(int new_size)
525 {
526  it_assert(new_size >= used_size, "Sparse_Vec<T>::resize_data(int new_size): New size is to small");
527 
528  if (new_size != data_size) {
529  if (new_size == 0)
530  free();
531  else {
532  T *tmp_data = data;
533  int *tmp_pos = index;
534  data_size = new_size;
535  alloc();
536  for (int p = 0; p < used_size; p++) {
537  data[p] = tmp_data[p];
538  index[p] = tmp_pos[p];
539  }
540  delete [] tmp_data;
541  delete [] tmp_pos;
542  }
543  }
544 }
545 
546 template <class T>
548 {
549  if (check_small_elems_flag) {
550  remove_small_elements();
551  }
552  resize_data(used_size);
553 }
554 
555 template <class T>
557 {
558  v.set_size(v_size);
559 
560  v = T(0);
561  for (int p = 0; p < used_size; p++)
562  v(index[p]) = data[p];
563 }
564 
565 template <class T>
567 {
568  Vec<T> r(v_size);
569  full(r);
570  return r;
571 }
572 
573 // This is slow. Implement a better search
574 template <class T>
576 {
577  it_assert_debug(i >= 0 && i < v_size, "The index of the element is out of range");
578 
579  bool found = false;
580  int p;
581  for (p = 0; p < used_size; p++) {
582  if (index[p] == i) {
583  found = true;
584  break;
585  }
586  }
587  return found ? data[p] : T(0);
588 }
589 
590 template <class T>
591 void Sparse_Vec<T>::set(int i, T v)
592 {
593  it_assert_debug(i >= 0 && i < v_size, "The index of the element is out of range");
594 
595  bool found = false;
596  bool larger_than_eps;
597  int p;
598 
599  for (p = 0; p < used_size; p++) {
600  if (index[p] == i) {
601  found = true;
602  break;
603  }
604  }
605 
606  larger_than_eps = (std::abs(v) > eps);
607 
608  if (found && larger_than_eps)
609  data[p] = v;
610  else if (larger_than_eps) {
611  if (used_size == data_size)
612  resize_data(data_size*2 + 100);
613  data[used_size] = v;
614  index[used_size] = i;
615  used_size++;
616  }
617 
618  //Check if the stored element is smaller than eps. In that case it should be removed.
619  if (std::abs(v) <= eps) {
620  remove_small_elements();
621  }
622 
623 }
624 
625 template <class T>
626 void Sparse_Vec<T>::set_new(int i, T v)
627 {
628  it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
629 
630  //Check that the new element is larger than eps!
631  if (std::abs(v) > eps) {
632  if (used_size == data_size)
633  resize_data(data_size*2 + 100);
634  data[used_size] = v;
635  index[used_size] = i;
636  used_size++;
637  }
638 }
639 
640 template <class T>
641 void Sparse_Vec<T>::add_elem(const int i, const T v)
642 {
643  bool found = false;
644  int p;
645 
646  it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
647 
648  for (p = 0; p < used_size; p++) {
649  if (index[p] == i) {
650  found = true;
651  break;
652  }
653  }
654  if (found)
655  data[p] += v;
656  else {
657  if (used_size == data_size)
658  resize_data(data_size*2 + 100);
659  data[used_size] = v;
660  index[used_size] = i;
661  used_size++;
662  }
663 
664  check_small_elems_flag = true;
665 
666 }
667 
668 template <class T>
669 void Sparse_Vec<T>::add(const ivec& index_vec, const Vec<T>& v)
670 {
671  bool found = false;
672  int i, p, q;
673  int nrof_nz = v.size();
674 
675  it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
676 
677  //Elements are added if they have identical indices
678  for (q = 0; q < nrof_nz; q++) {
679  i = index_vec(q);
680  for (p = 0; p < used_size; p++) {
681  if (index[p] == i) {
682  found = true;
683  break;
684  }
685  }
686  if (found)
687  data[p] += v(q);
688  else {
689  if (used_size == data_size)
690  resize_data(data_size*2 + 100);
691  data[used_size] = v(q);
692  index[used_size] = i;
693  used_size++;
694  }
695  found = false;
696  }
697 
698  check_small_elems_flag = true;
699 
700 }
701 
702 template <class T>
704 {
705  used_size = 0;
706  check_small_elems_flag = false;
707 }
708 
709 template <class T>
710 void Sparse_Vec<T>::zero_elem(const int i)
711 {
712  bool found = false;
713  int p;
714 
715  it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
716 
717  for (p = 0; p < used_size; p++) {
718  if (index[p] == i) {
719  found = true;
720  break;
721  }
722  }
723  if (found) {
724  data[p] = data[used_size-1];
725  index[p] = index[used_size-1];
726  used_size--;
727  }
728 }
729 
730 template <class T>
732 {
733  used_size = 0;
734  check_small_elems_flag = false;
735 }
736 
737 template <class T>
738 void Sparse_Vec<T>::clear_elem(const int i)
739 {
740  bool found = false;
741  int p;
742 
743  it_assert_debug(v_size > i, "The index of the element exceeds the size of the sparse vector");
744 
745  for (p = 0; p < used_size; p++) {
746  if (index[p] == i) {
747  found = true;
748  break;
749  }
750  }
751  if (found) {
752  data[p] = data[used_size-1];
753  index[p] = index[used_size-1];
754  used_size--;
755  }
756 }
757 
758 template <class T>
759 void Sparse_Vec<T>::set(const ivec& index_vec, const Vec<T>& v)
760 {
761  it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
762 
763  //Clear all old non-zero elements
764  clear();
765 
766  //Add the new non-zero elements
767  add(index_vec, v);
768 }
769 
770 template <class T>
771 void Sparse_Vec<T>::set_new(const ivec& index_vec, const Vec<T>& v)
772 {
773  int q;
774  int nrof_nz = v.size();
775 
776  it_assert_debug(v_size > max(index_vec), "The indices exceeds the size of the sparse vector");
777 
778  //Clear all old non-zero elements
779  clear();
780 
781  for (q = 0; q < nrof_nz; q++) {
782  if (std::abs(v[q]) > eps) {
783  if (used_size == data_size)
784  resize_data(data_size*2 + 100);
785  data[used_size] = v(q);
786  index[used_size] = index_vec(q);
787  used_size++;
788  }
789  }
790 }
791 
792 template <class T>
794 {
795  int n = nnz();
796  ivec r(n);
797  for (int i = 0; i < n; i++) {
798  r(i) = get_nz_index(i);
799  }
800  return r;
801 }
802 
803 template <class T>
805 {
806  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");
807 
808  Sparse_Vec<T> r(i2 - i1 + 1);
809 
810  for (int p = 0; p < used_size; p++) {
811  if (index[p] >= i1 && index[p] <= i2) {
812  if (r.used_size == r.data_size)
813  r.resize_data(r.data_size*2 + 100);
814  r.data[r.used_size] = data[p];
815  r.index[r.used_size] = index[p] - i1;
816  r.used_size++;
817  }
818  }
819  r.eps = eps;
820  r.check_small_elems_flag = check_small_elems_flag;
821  r.compact();
822 
823  return r;
824 }
825 
826 template <class T>
828 {
829  T sum(0);
830  for (int p = 0; p < used_size; p++)
831  sum += data[p] * data[p];
832 
833  return sum;
834 }
835 
836 template <class T>
838 {
839  free();
840  v_size = v.v_size;
841  used_size = v.used_size;
842  data_size = v.data_size;
843  eps = v.eps;
844  check_small_elems_flag = v.check_small_elems_flag;
845  alloc();
846 
847  for (int i = 0; i < used_size; i++) {
848  data[i] = v.data[i];
849  index[i] = v.index[i];
850  }
851 }
852 
853 template <class T>
855 {
856  free();
857  v_size = v.size();
858  used_size = 0;
859  data_size = std::min(v.size(), 10000);
860  eps = std::abs(T(0));
861  check_small_elems_flag = false;
862  alloc();
863 
864  for (int i = 0; i < v_size; i++) {
865  if (v(i) != T(0)) {
866  if (used_size == data_size)
867  resize_data(data_size*2);
868  data[used_size] = v(i);
869  index[used_size] = i;
870  used_size++;
871  }
872  }
873  compact();
874 }
875 
876 template <class T>
878 {
879  Sparse_Vec r(v_size, used_size);
880 
881  for (int p = 0; p < used_size; p++) {
882  r.data[p] = -data[p];
883  r.index[p] = index[p];
884  }
885  r.used_size = used_size;
886 
887  return r;
888 }
889 
890 template <class T>
892 {
893  int p, q;
894  bool found = false;
895 
896  //Remove small elements before comparing the two sparse_vectors
897  if (check_small_elems_flag)
898  remove_small_elements();
899 
900  if (v_size != v.v_size) {
901  //Return false if vector sizes are unequal
902  return false;
903  }
904  else {
905  for (p = 0;p < used_size;p++) {
906  for (q = 0;q < v.used_size;q++) {
907  if (index[p] == v.index[q]) {
908  found = true;
909  break;
910  }
911  }
912  if (found == false)
913  //Return false if non-zero element not found, or if elements are unequal
914  return false;
915  else if (data[p] != v.data[q])
916  //Return false if non-zero element not found, or if elements are unequal
917  return false;
918  else
919  //Check next non-zero element
920  found = false;
921  }
922  }
923 
924  /*Special handling if sizes do not match.
925  Required since v may need to do remove_small_elements() for true comparison*/
926  if (used_size != v.used_size) {
927  if (used_size > v.used_size) {
928  //Return false if number of non-zero elements is less in v
929  return false;
930  }
931  else {
932  //Ensure that the remaining non-zero elements in v are smaller than v.eps
933  int nrof_small_elems = 0;
934  for (q = 0;q < v.used_size;q++) {
935  if (std::abs(v.data[q]) <= v.eps)
936  nrof_small_elems++;
937  }
938  if (v.used_size - nrof_small_elems != used_size)
939  //Return false if the number of "true" non-zero elements are unequal
940  return false;
941  }
942  }
943 
944  //All elements checks => return true
945  return true;
946 }
947 
948 template <class T>
950 {
951  int i, p;
952  T tmp_data;
953  int nrof_nz_v = v.used_size;
954 
955  it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
956 
957  for (p = 0; p < nrof_nz_v; p++) {
958  i = v.index[p];
959  tmp_data = v.data[p];
960  //get_nz(p,i,tmp_data);
961  add_elem(i, tmp_data);
962  }
963 
964  check_small_elems_flag = true;
965 }
966 
967 template <class T>
969 {
970  int i;
971 
972  it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
973 
974  for (i = 0; i < v.size(); i++)
975  if (v(i) != T(0))
976  add_elem(i, v(i));
977 
978  check_small_elems_flag = true;
979 }
980 
981 
982 template <class T>
984 {
985  int i, p;
986  T tmp_data;
987  int nrof_nz_v = v.used_size;
988 
989  it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
990 
991  for (p = 0; p < nrof_nz_v; p++) {
992  i = v.index[p];
993  tmp_data = v.data[p];
994  //v.get_nz(p,i,tmp_data);
995  add_elem(i, -tmp_data);
996  }
997 
998  check_small_elems_flag = true;
999 }
1000 
1001 template <class T>
1003 {
1004  int i;
1005 
1006  it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
1007 
1008  for (i = 0; i < v.size(); i++)
1009  if (v(i) != T(0))
1010  add_elem(i, -v(i));
1011 
1012  check_small_elems_flag = true;
1013 }
1014 
1015 template <class T>
1017 {
1018  int p;
1019 
1020  for (p = 0; p < used_size; p++) {
1021  data[p] *= v;
1022  }
1023 
1024  check_small_elems_flag = true;
1025 }
1026 
1027 template <class T>
1029 {
1030  int p;
1031  for (p = 0; p < used_size; p++) {
1032  data[p] /= v;
1033  }
1034 
1035  if (eps > 0) {
1036  check_small_elems_flag = true;
1037  }
1038 }
1039 
1040 template <class T>
1041 T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
1042 {
1043  it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> * Sparse_Vec<T>");
1044 
1045  T sum(0);
1046  Vec<T> v1f(v1.v_size);
1047  v1.full(v1f);
1048  for (int p = 0; p < v2.used_size; p++) {
1049  if (v1f[v2.index[p]] != T(0))
1050  sum += v1f[v2.index[p]] * v2.data[p];
1051  }
1052 
1053  return sum;
1054 }
1055 
1056 template <class T>
1057 T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2)
1058 {
1059  it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
1060 
1061  T sum(0);
1062  for (int p1 = 0; p1 < v1.used_size; p1++)
1063  sum += v1.data[p1] * v2[v1.index[p1]];
1064 
1065  return sum;
1066 }
1067 
1068 template <class T>
1069 T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2)
1070 {
1071  it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
1072 
1073  T sum(0);
1074  for (int p2 = 0; p2 < v2.used_size; p2++)
1075  sum += v1[v2.index[p2]] * v2.data[p2];
1076 
1077  return sum;
1078 }
1079 
1080 template <class T>
1082 {
1083  it_assert_debug(v1.v_size == v2.v_size, "elem_mult(Sparse_Vec<T>, Sparse_Vec<T>)");
1084 
1085  Sparse_Vec<T> r(v1.v_size);
1086  ivec pos(v1.v_size);
1087  pos = -1;
1088  for (int p1 = 0; p1 < v1.used_size; p1++)
1089  pos[v1.index[p1]] = p1;
1090  for (int p2 = 0; p2 < v2.used_size; p2++) {
1091  if (pos[v2.index[p2]] != -1) {
1092  if (r.used_size == r.data_size)
1093  r.resize_data(r.used_size*2 + 100);
1094  r.data[r.used_size] = v1.data[pos[v2.index[p2]]] * v2.data[p2];
1095  r.index[r.used_size] = v2.index[p2];
1096  r.used_size++;
1097  }
1098  }
1099  r.compact();
1100 
1101  return r;
1102 }
1103 
1104 template <class T>
1105 Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2)
1106 {
1107  it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
1108 
1109  Vec<T> r(v1.v_size);
1110  r = T(0);
1111  for (int p1 = 0; p1 < v1.used_size; p1++)
1112  r[v1.index[p1]] = v1.data[p1] * v2[v1.index[p1]];
1113 
1114  return r;
1115 }
1116 
1117 template <class T>
1119 {
1120  it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
1121 
1122  Sparse_Vec<T> r(v1.v_size);
1123  for (int p1 = 0; p1 < v1.used_size; p1++) {
1124  if (v2[v1.index[p1]] != T(0)) {
1125  if (r.used_size == r.data_size)
1126  r.resize_data(r.used_size*2 + 100);
1127  r.data[r.used_size] = v1.data[p1] * v2[v1.index[p1]];
1128  r.index[r.used_size] = v1.index[p1];
1129  r.used_size++;
1130  }
1131  }
1132  r.compact();
1133 
1134  return r;
1135 }
1136 
1137 template <class T>
1138 Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2)
1139 {
1140  it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
1141 
1142  Vec<T> r(v2.v_size);
1143  r = T(0);
1144  for (int p2 = 0; p2 < v2.used_size; p2++)
1145  r[v2.index[p2]] = v1[v2.index[p2]] * v2.data[p2];
1146 
1147  return r;
1148 }
1149 
1150 template <class T>
1152 {
1153  it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
1154 
1155  Sparse_Vec<T> r(v2.v_size);
1156  for (int p2 = 0; p2 < v2.used_size; p2++) {
1157  if (v1[v2.index[p2]] != T(0)) {
1158  if (r.used_size == r.data_size)
1159  r.resize_data(r.used_size*2 + 100);
1160  r.data[r.used_size] = v1[v2.index[p2]] * v2.data[p2];
1161  r.index[r.used_size] = v2.index[p2];
1162  r.used_size++;
1163  }
1164  }
1165  r.compact();
1166 
1167  return r;
1168 }
1169 
1170 template <class T>
1172 {
1173  it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> + Sparse_Vec<T>");
1174 
1175  Sparse_Vec<T> r(v1);
1176  ivec pos(v1.v_size);
1177  pos = -1;
1178  for (int p1 = 0; p1 < v1.used_size; p1++)
1179  pos[v1.index[p1]] = p1;
1180  for (int p2 = 0; p2 < v2.used_size; p2++) {
1181  if (pos[v2.index[p2]] == -1) {// A new entry
1182  if (r.used_size == r.data_size)
1183  r.resize_data(r.used_size*2 + 100);
1184  r.data[r.used_size] = v2.data[p2];
1185  r.index[r.used_size] = v2.index[p2];
1186  r.used_size++;
1187  }
1188  else
1189  r.data[pos[v2.index[p2]]] += v2.data[p2];
1190  }
1191  r.check_small_elems_flag = true; // added dec 7, 2006
1192  r.compact();
1193 
1194  return r;
1195 }
1196 
1198 template <class T>
1199 inline Sparse_Vec<T> sparse(const Vec<T> &v)
1200 {
1201  Sparse_Vec<T> s(v);
1202  return s;
1203 }
1204 
1206 template <class T>
1207 inline Sparse_Vec<T> sparse(const Vec<T> &v, T epsilon)
1208 {
1209  Sparse_Vec<T> s(v, epsilon);
1210  return s;
1211 }
1212 
1214 template <class T>
1215 inline Vec<T> full(const Sparse_Vec<T> &s)
1216 {
1217  Vec<T> v;
1218  s.full(v);
1219  return v;
1220 }
1221 
1223 
1224 // ---------------------------------------------------------------------
1225 // Instantiations
1226 // ---------------------------------------------------------------------
1227 
1228 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sparse_Vec<int>;
1229 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sparse_Vec<double>;
1230 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sparse_Vec<std::complex<double> >;
1231 
1232 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_ivec operator+(const sparse_ivec &,
1233  const sparse_ivec &);
1234 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_vec operator+(const sparse_vec &,
1235  const sparse_vec &);
1236 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_cvec operator+(const sparse_cvec &,
1237  const sparse_cvec &);
1238 
1239 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT int operator*(const sparse_ivec &, const sparse_ivec &);
1240 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT double operator*(const sparse_vec &, const sparse_vec &);
1241 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::complex<double> operator*(const sparse_cvec &,
1242  const sparse_cvec &);
1243 
1244 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT int operator*(const sparse_ivec &, const ivec &);
1245 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT double operator*(const sparse_vec &, const vec &);
1246 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::complex<double> operator*(const sparse_cvec &,
1247  const cvec &);
1248 
1249 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT int operator*(const ivec &, const sparse_ivec &);
1250 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT double operator*(const vec &, const sparse_vec &);
1251 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::complex<double> operator*(const cvec &,
1252  const sparse_cvec &);
1253 
1254 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_ivec elem_mult(const sparse_ivec &,
1255  const sparse_ivec &);
1256 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_vec elem_mult(const sparse_vec &, const sparse_vec &);
1257 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_cvec elem_mult(const sparse_cvec &,
1258  const sparse_cvec &);
1259 
1260 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT ivec elem_mult(const sparse_ivec &, const ivec &);
1261 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT vec elem_mult(const sparse_vec &, const vec &);
1262 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cvec elem_mult(const sparse_cvec &, const cvec &);
1263 
1264 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_ivec elem_mult_s(const sparse_ivec &, const ivec &);
1265 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_vec elem_mult_s(const sparse_vec &, const vec &);
1266 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_cvec elem_mult_s(const sparse_cvec &, const cvec &);
1267 
1268 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT ivec elem_mult(const ivec &, const sparse_ivec &);
1269 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT vec elem_mult(const vec &, const sparse_vec &);
1270 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cvec elem_mult(const cvec &, const sparse_cvec &);
1271 
1272 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_ivec elem_mult_s(const ivec &, const sparse_ivec &);
1273 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_vec elem_mult_s(const vec &, const sparse_vec &);
1274 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT sparse_cvec elem_mult_s(const cvec &, const sparse_cvec &);
1275 
1277 
1278 } // namespace itpp
1279 
1280 #endif // #ifndef SVEC_H
1281 
SourceForge Logo

Generated on Sat May 25 2013 16:32:20 for IT++ by Doxygen 1.8.2