root/win32/itpp-4.0.1/itpp/base/svec.h @ 35

Revision 35, 33.4 kB (checked in by mido, 16 years ago)

zasadni zmeny ve /win32

Line 
1/*!
2 * \file
3 * \brief Sparse Vector Class definitions
4 * \author Tony Ottosson and Tobias Ringstrom
5 *
6 * -------------------------------------------------------------------------
7 *
8 * IT++ - C++ library of mathematical, signal processing, speech processing,
9 *        and communications classes and functions
10 *
11 * Copyright (C) 1995-2007  (see AUTHORS file for a list of contributors)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 *
27 * -------------------------------------------------------------------------
28 */
29
30#ifndef SVEC_H
31#define SVEC_H
32
33#ifndef _MSC_VER
34#  include <itpp/config.h>
35#else
36#  include <itpp/config_msvc.h>
37#endif
38
39#include <itpp/base/vec.h>
40#include <itpp/base/math/min_max.h>
41#include <cstdlib>
42
43
44namespace itpp {
45
46  // Declaration of class Vec
47  template <class T> class Vec;
48  // Declaration of class Sparse_Vec
49  template <class T> class Sparse_Vec;
50
51  // ----------------------- Sparse_Vec Friends -------------------------------
52
53  //! v1+v2 where v1 and v2 are sparse vector
54  template <class T>
55    Sparse_Vec<T> operator+(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
56
57  //! v1*v2 where v1 and v2 are sparse vectors
58  template <class T>
59    T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
60
61  //! v1*v2 where v1 is a sparse vector and v2 is a dense vector
62  template <class T>
63    T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2);
64
65  //! v1*v2 where v1 is a dense vector and v2 is a sparse vector
66  template <class T>
67    T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2);
68
69  //! Elementwise multiplication of two sparse vectors returning a sparse vector
70  template <class T>
71    Sparse_Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
72
73  //! Elementwise multiplication of a sparse vector and a dense vector returning a dense vector
74  template <class T>
75    Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2);
76
77  //! Elementwise multiplication of a sparse vector and a dense vector returning a sparse vector
78  template <class T>
79    Sparse_Vec<T> elem_mult_s(const Sparse_Vec<T> &v1, const Vec<T> &v2);
80
81  //! Elementwise multiplication of a dense vector and a sparse vector returning a dense vector
82  template <class T>
83    Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2);
84
85  //! Elementwise multiplication of a dense vector and a sparse vector returning a sparse vector
86  template <class T>
87    Sparse_Vec<T> elem_mult_s(const Vec<T> &v1, const Sparse_Vec<T> &v2);
88
89  /*!
90    \brief Templated sparse vector class
91    \author Tony Ottosson and Tobias Ringstrom
92
93    A sparse vector is a vector where most elements are zero. The
94    maximum number of none-zero elements is a parameter to the
95    constructor. The elements are stored in random order, i.e. they
96    are not sorted.
97
98  */
99  template <class T>
100    class Sparse_Vec {
101    public:
102
103    //! Default constructor
104    Sparse_Vec();
105
106    /*!
107      \brief Initiate an empty sparse vector
108
109      \param sz Size of the sparse vector (i.e. maximum index is (\c sz - 1))
110      \param data_init Maximum number of non-zero elements in the sparse vector (default value 200)
111    */
112    Sparse_Vec(int sz, int data_init=200);
113
114    /*!
115      \brief Initiate a new sparse vector.
116
117      \param v The elements of \c v are copied into the new sparse vector
118    */
119    Sparse_Vec(const Sparse_Vec<T> &v);
120
121    /*!
122      \brief Initiate a new sparse vector from a dense vector.
123
124      \param v The elements of \c v are copied into the new sparse vector
125    */
126    Sparse_Vec(const Vec<T> &v);
127
128    /*!
129      \brief Initiate a new sparse vector from a dense vector. Elements of \c v larger than \c epsilon are copied into the new sparse vector.
130
131      \note If the type T is complex<double>, then the elements of \c v larger than \c abs(epsilon) are copied into the new sparse vector.
132    */
133    Sparse_Vec(const Vec<T> &v, T epsilon);
134
135    //! Destructor
136    ~Sparse_Vec();
137
138    /*!
139      \brief Set the size \c sz of the sparse vector. Default value \c data_init=-1 \c => allocated size for the data is not changed.
140
141      \param sz Size of the sparse vector (i.e. maximum index is (\c sz - 1))
142      \param data_init Maximum number of non-zero elements in the sparse vector (default value -1 \c => allocated size for the data is not changed)
143    */
144    void set_size(int sz, int data_init=-1);
145
146    //! Returns the size of the sparse vector
147    int size() const { return v_size; }
148
149    //! Number of non-zero elements in the sparse vector
150    inline int nnz()
151      {
152        if (check_small_elems_flag) {
153          remove_small_elements();
154        }
155        return used_size;
156      }
157
158    //! Returns the density of the sparse vector: (number of non-zero elements)/(size of the vector)
159    double density();
160
161    //! Set that all elements smaller than \a epsilon should be set to zero.
162    void set_small_element(const T& epsilon);
163
164    /*!
165      Removes all elements that are smaller than \a epsilon from the non-zero elements.
166
167      \note The small element \a epsilon can be set by the member function set_small_element. If no small value is set, the default value is always \c epsilon=0.
168    */
169    void remove_small_elements();
170
171    /*!
172      \brief Set the maximum number of non-zero elements to \c new_size
173
174      \param new_size The new maximum number of non-zero elements.
175    */
176    void resize_data(int new_size);
177
178    //! Set the maximum number of non-zero elements equal to the actual number of non-zero elements
179    void compact();
180
181    //! Returns a full, dense vector in \c v
182    void full(Vec<T> &v) const;
183
184    //! Returns a full, dense vector
185    Vec<T> full() const;
186
187    //! Returns the element with index \c i
188    T operator()(int i) const;
189
190    //! Set element \c i equal to \c v
191    void set(int i, T v);
192
193    //! Set the elements of the sparse vector with indices \c index_vec to the values in \c v
194    void set(const ivec &index_vec, const Vec<T> &v);
195
196    //! Set a new element with index \c i equal to \c v
197    void set_new(int i, T v);
198
199    //! Set new elements with indices \c index_vec equal to the values in \c v (no check whether the same index is used several times)
200    void set_new(const ivec &index_vec, const Vec<T> &v);
201
202    //! Add element \c i with \c v
203    void add_elem(const int i, const T v);
204
205    //! Add \c v to the elements specified by \c index_vec with \c v
206    void add(const ivec &index_vec, const Vec<T> &v);
207
208    //! Set the sparse vector to the all zero vector (removes all non-zero elements)
209    void zeros();
210
211    //! Set the i-th element to zero (i.e. clear that element if it contains a non-zero value)
212    void zero_elem(const int i);
213
214    //! Clear all non-zero elements of the sparse vector
215    void clear();
216
217    //! Clear the i-th element (if it contains a non-zero value)
218    void clear_elem(const int i);
219
220    /*!
221      \brief Extract the reference to the p-th non-zero data element
222    */
223    inline void get_nz_data(int p, T& data_out)
224      {
225        if (check_small_elems_flag) {
226          remove_small_elements();
227        }
228        data_out = data[p];
229      }
230
231    //! Returns the p-th non-zero data element
232    inline T get_nz_data(int p)
233      {
234        if (check_small_elems_flag) {
235          remove_small_elements();
236        }
237        return data[p];
238      }
239
240    //! Returns the vector index of the p-th non-zero element
241    inline int get_nz_index(int p)
242      {
243        if (check_small_elems_flag) {
244          remove_small_elements();
245        }
246        return index[p];
247      }
248
249    //! Returns the p-th non-zero value in \c dat and the corresponding vector index in \c idx
250    inline void get_nz(int p, int &idx, T &dat)
251      {
252        if (check_small_elems_flag) {
253          remove_small_elements();
254        }
255        idx=index[p];
256        dat=data[p];
257      }
258
259    //! Retrun the indices of non-zero values
260    ivec get_nz_indices();
261
262    //! Return sparse subvector from index \c i1 to index \c i2
263    Sparse_Vec<T> get_subvector(int i1, int i2) const;
264
265    //! Returns the sum of all values squared
266    T sqr() const;
267
268    //! Assign sparse vector the value and length of the sparse vector \c v
269    void operator=(const Sparse_Vec<T> &v);
270    //! Assign sparse vector the value and length of the dense vector \c v
271    void operator=(const Vec<T> &v);
272
273   //! Returns the sign inverse of all elements in the sparse vector
274    Sparse_Vec<T> operator-() const;
275
276    //! Compare two sparse vectors. False if wrong sizes or different values
277    bool operator==(const Sparse_Vec<T> &v);
278
279    //! Add sparse vector \c v to all non-zero elements of the sparse vector
280    void operator+=(const Sparse_Vec<T> &v);
281
282    //! Add vector \c v to all non-zero elements of the sparse vector
283    void operator+=(const Vec<T> &v);
284
285    //! Subtract sparse vector \c v from all non-zero elements of the sparse vector
286    void operator-=(const Sparse_Vec<T> &v);
287
288    //! Subtract vector \c v from all non-zero elements of the sparse vector
289    void operator-=(const Vec<T> &v);
290
291    //! Multiply the scalar \c v to all non-zero elements of the sparse vector
292    void operator*=(const T &v);
293
294    //! Divide all non-zero elements of the sparse vector with the scalar \c v
295    void operator/=(const T &v);
296
297   //! Addition v1+v2 where v1 and v2 are sparse vector
298    friend Sparse_Vec<T> operator+<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
299    //! Scalar product v1*v2 where v1 and v2 are sparse vectors
300    friend T operator*<>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
301    //! Scalar product v1*v2 where v1 is a sparse vector and v2 is a dense vector
302    friend T operator*<>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
303    //! Scalar product v1*v2 where v1 is a dense vector and v2 is a sparse vector
304    friend T operator*<>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
305
306    //! Element wise multiplication of two sparse vectors
307    friend Sparse_Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2);
308
309    //! Element wise multiplication of a sparse vector and a dense vector
310    friend Vec<T> elem_mult <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
311
312    //! Element wise multiplication of a sparse vector and a dense vector returning a sparse vector
313    friend Sparse_Vec<T> elem_mult_s <>(const Sparse_Vec<T> &v1, const Vec<T> &v2);
314
315    //! Element wise multiplication of a a dense vector and a sparse vector
316    friend Vec<T> elem_mult <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
317
318    //! Element wise multiplication of a a dense vector and a sparse vector returning a sparse vector
319    friend Sparse_Vec<T> elem_mult_s <>(const Vec<T> &v1, const Sparse_Vec<T> &v2);
320
321    private:
322    void init();
323    void alloc();
324    void free();
325
326    int v_size, used_size, data_size;
327    T *data;
328    int *index;
329    T eps;
330    bool check_small_elems_flag;
331  };
332
333
334  /*!
335    \relates Sparse_Vec
336    \brief Type definition of an integer sparse vector
337  */
338  typedef Sparse_Vec<int> sparse_ivec;
339
340  /*!
341    \relates Sparse_Vec
342    \brief Type definition of a double sparse vector
343  */
344  typedef Sparse_Vec<double> sparse_vec;
345
346  /*!
347    \relates Sparse_Vec
348    \brief Type definition of a complex<double> sparse vector
349  */
350  typedef Sparse_Vec<std::complex<double> > sparse_cvec;
351
352  // ----------------------- Implementation starts here --------------------------------
353
354  template <class T>
355    void Sparse_Vec<T>::init()
356    {
357      v_size = 0;
358      used_size = 0;
359      data_size = 0;
360      data = 0;
361      index = 0;
362      eps = 0;
363      check_small_elems_flag = true;
364    }
365
366  template <class T>
367    void Sparse_Vec<T>::alloc()
368    {
369      if (data_size != 0) {
370        data = new T[data_size];
371        index = new int[data_size];
372      }
373    }
374
375  template <class T>
376    void Sparse_Vec<T>::free()
377    {
378      delete [] data;
379      data = 0;
380      delete [] index;
381      index = 0;
382    }
383
384  template <class T>
385    Sparse_Vec<T>::Sparse_Vec()
386    {
387      init();
388    }
389
390  template <class T>
391    Sparse_Vec<T>::Sparse_Vec(int sz, int data_init)
392    {
393      init();
394      v_size = sz;
395      used_size = 0;
396      data_size = data_init;
397      alloc();
398    }
399
400  template <class T>
401    Sparse_Vec<T>::Sparse_Vec(const Sparse_Vec<T> &v)
402    {
403      init();
404      v_size = v.v_size;
405      used_size = v.used_size;
406      data_size = v.data_size;
407      eps = v.eps;
408      check_small_elems_flag = v.check_small_elems_flag;
409      alloc();
410
411      for (int i=0; i<used_size; i++) {
412        data[i] = v.data[i];
413        index[i] = v.index[i];
414      }
415    }
416
417  template <class T>
418    Sparse_Vec<T>::Sparse_Vec(const Vec<T> &v)
419    {
420      init();
421      v_size = v.size();
422      used_size = 0;
423      data_size = std::min(v.size(), 10000);
424      alloc();
425
426      for (int i=0; i<v_size; i++) {
427        if (v(i) != T(0)) {
428          if (used_size == data_size)
429            resize_data(data_size*2);
430          data[used_size] = v(i);
431          index[used_size] = i;
432          used_size++;
433        }
434      }
435      compact();
436    }
437
438  template <class T>
439    Sparse_Vec<T>::Sparse_Vec(const Vec<T> &v, T epsilon)
440    {
441      init();
442      v_size = v.size();
443      used_size = 0;
444      data_size = std::min(v.size(), 10000);
445      eps = epsilon;
446      alloc();
447
448    double e = std::abs(epsilon);
449    for (int i=0; i<v_size; i++) {
450        if (std::abs(v(i)) > e) {
451          if (used_size == data_size)
452            resize_data(data_size*2);
453          data[used_size] = v(i);
454          index[used_size] = i;
455          used_size++;
456        }
457      }
458      compact();
459    }
460
461  template <class T>
462    Sparse_Vec<T>::~Sparse_Vec()
463    {
464      free();
465    }
466
467  template <class T>
468    void Sparse_Vec<T>::set_size(int new_size, int data_init)
469    {
470      v_size = new_size;
471      used_size = 0;
472      if (data_init != -1){
473        free();
474        data_size = data_init;
475        alloc();
476      }
477    }
478
479  template <class T>
480    double Sparse_Vec<T>::density()
481    {
482      if (check_small_elems_flag) {
483        remove_small_elements();
484      }
485      //return static_cast<double>(used_size) / v_size;
486      return double(used_size) / v_size;
487    }
488
489  template <class T>
490    void Sparse_Vec<T>::set_small_element(const T& epsilon)
491    {
492      eps=epsilon;
493      remove_small_elements();
494    }
495
496  template <class T>
497    void Sparse_Vec<T>::remove_small_elements()
498    {
499      int i;
500      int nrof_removed_elements = 0;
501      double e;
502
503      //Remove small elements
504      e = std::abs(eps);
505      for (i=0;i<used_size;i++) {
506        if (std::abs(data[i]) <= e) {
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>
547    void Sparse_Vec<T>::compact()
548    {
549      if (check_small_elems_flag) {
550        remove_small_elements();
551      }
552      resize_data(used_size);
553    }
554
555  template <class T>
556    void Sparse_Vec<T>::full(Vec<T> &v) const
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>
566    Vec<T> Sparse_Vec<T>::full() const
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>
575    T Sparse_Vec<T>::operator()(int i) const
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) > std::abs(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) <= std::abs(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) > std::abs(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>
703    void Sparse_Vec<T>::zeros()
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>
731    void Sparse_Vec<T>::clear()
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]) > std::abs(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>
793  ivec Sparse_Vec<T>::get_nz_indices()
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>
804    Sparse_Vec<T> Sparse_Vec<T>::get_subvector(int i1, int i2) const
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>
827    T Sparse_Vec<T>::sqr() const
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>
837    void Sparse_Vec<T>::operator=(const Sparse_Vec<T> &v)
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>
854    void Sparse_Vec<T>::operator=(const Vec<T> &v)
855    {
856      free();
857      v_size = v.size();
858      used_size = 0;
859      data_size = std::min(v.size(), 10000);
860      eps = 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>
877    Sparse_Vec<T> Sparse_Vec<T>::operator-() const
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>
891    bool Sparse_Vec<T>::operator==(const Sparse_Vec<T> &v)
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      } else {
904        for(p=0;p<used_size;p++) {
905          for(q=0;q<v.used_size;q++) {
906            if (index[p] == v.index[q]) {
907              found = true;
908              break;
909            }
910          }
911          if (found==false)
912            //Return false if non-zero element not found, or if elements are unequal
913            return false;
914          else if (data[p]!=v.data[q])
915            //Return false if non-zero element not found, or if elements are unequal
916            return false;
917          else
918            //Check next non-zero element
919            found = false;
920        }
921      }
922
923      /*Special handling if sizes do not match.
924        Required since v may need to do remove_small_elements() for true comparison*/
925      if (used_size!=v.used_size) {
926        if (used_size > v.used_size) {
927          //Return false if number of non-zero elements is less in v
928          return false;
929        }
930        else {
931          //Ensure that the remaining non-zero elements in v are smaller than v.eps
932          int nrof_small_elems = 0;
933          for(q=0;q<v.used_size;q++) {
934            if (std::abs(v.data[q]) <= std::abs(v.eps))
935              nrof_small_elems++;
936          }
937          if (v.used_size-nrof_small_elems != used_size)
938            //Return false if the number of "true" non-zero elements are unequal
939            return false;
940        }
941      }
942
943      //All elements checks => return true
944      return true;
945    }
946
947  template <class T>
948    void Sparse_Vec<T>::operator+=(const Sparse_Vec<T> &v)
949    {
950      int i,p;
951      T tmp_data;
952      int nrof_nz_v=v.used_size;
953
954      it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
955
956      for (p=0; p<nrof_nz_v; p++) {
957        i = v.index[p];
958        tmp_data = v.data[p];
959        //get_nz(p,i,tmp_data);
960        add_elem(i,tmp_data);
961      }
962
963      check_small_elems_flag = true;
964    }
965
966  template <class T>
967    void Sparse_Vec<T>::operator+=(const Vec<T> &v)
968    {
969      int i;
970
971      it_assert_debug(v_size == v.size(), "Attempted addition of unequal sized sparse vectors");
972
973      for (i=0; i<v.size(); i++)
974        if (v(i)!=T(0))
975          add_elem(i,v(i));
976
977      check_small_elems_flag = true;
978    }
979
980
981  template <class T>
982    void Sparse_Vec<T>::operator-=(const Sparse_Vec<T> &v)
983    {
984      int i,p;
985      T tmp_data;
986      int nrof_nz_v=v.used_size;
987
988      it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
989
990      for (p=0; p<nrof_nz_v; p++) {
991        i = v.index[p];
992        tmp_data = v.data[p];
993        //v.get_nz(p,i,tmp_data);
994        add_elem(i,-tmp_data);
995      }
996
997      check_small_elems_flag = true;
998    }
999
1000  template <class T>
1001    void Sparse_Vec<T>::operator-=(const Vec<T> &v)
1002    {
1003      int i;
1004
1005      it_assert_debug(v_size == v.size(), "Attempted subtraction of unequal sized sparse vectors");
1006
1007      for (i=0; i<v.size(); i++)
1008        if (v(i)!=T(0))
1009          add_elem(i,-v(i));
1010
1011      check_small_elems_flag = true;
1012    }
1013
1014  template <class T>
1015    void Sparse_Vec<T>::operator*=(const T &v)
1016    {
1017      int p;
1018
1019      for (p=0; p<used_size; p++) {
1020        data[p]*=v;}
1021
1022      check_small_elems_flag = true;
1023    }
1024
1025  template <class T>
1026    void Sparse_Vec<T>::operator/=(const T &v)
1027    {
1028      int p;
1029      for (p=0; p<used_size; p++) {
1030        data[p]/=v;}
1031
1032      if (std::abs(eps) > 0) {
1033        check_small_elems_flag = true;
1034      }
1035    }
1036
1037  template <class T>
1038    T operator*(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
1039    {
1040      it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> * Sparse_Vec<T>");
1041
1042      T sum(0);
1043      Vec<T> v1f(v1.v_size);
1044      v1.full(v1f);
1045      for (int p=0; p<v2.used_size; p++) {
1046        if (v1f[v2.index[p]] != T(0))
1047          sum += v1f[v2.index[p]] * v2.data[p];
1048      }
1049
1050      return sum;
1051    }
1052
1053  template <class T>
1054    T operator*(const Sparse_Vec<T> &v1, const Vec<T> &v2)
1055    {
1056      it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
1057
1058      T sum(0);
1059      for (int p1=0; p1<v1.used_size; p1++)
1060        sum += v1.data[p1] * v2[v1.index[p1]];
1061
1062      return sum;
1063    }
1064
1065  template <class T>
1066    T operator*(const Vec<T> &v1, const Sparse_Vec<T> &v2)
1067    {
1068      it_assert_debug(v1.size() == v2.size(), "Multiplication of unequal sized vectors attempted");
1069
1070      T sum(0);
1071      for (int p2=0; p2<v2.used_size; p2++)
1072        sum += v1[v2.index[p2]] * v2.data[p2];
1073
1074      return sum;
1075    }
1076
1077  template <class T>
1078    Sparse_Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
1079    {
1080      it_assert_debug(v1.v_size == v2.v_size, "elem_mult(Sparse_Vec<T>, Sparse_Vec<T>)");
1081
1082      Sparse_Vec<T> r(v1.v_size);
1083      ivec pos(v1.v_size);
1084      pos = -1;
1085      for (int p1=0; p1<v1.used_size; p1++)
1086        pos[v1.index[p1]] = p1;
1087      for (int p2=0; p2<v2.used_size; p2++) {
1088        if (pos[v2.index[p2]] != -1) {
1089          if (r.used_size == r.data_size)
1090            r.resize_data(r.used_size*2+100);
1091          r.data[r.used_size] = v1.data[pos[v2.index[p2]]] * v2.data[p2];
1092          r.index[r.used_size] = v2.index[p2];
1093          r.used_size++;
1094        }
1095      }
1096      r.compact();
1097
1098      return r;
1099    }
1100
1101  template <class T>
1102    Vec<T> elem_mult(const Sparse_Vec<T> &v1, const Vec<T> &v2)
1103    {
1104      it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
1105
1106      Vec<T> r(v1.v_size);
1107      r = T(0);
1108      for (int p1=0; p1<v1.used_size; p1++)
1109        r[v1.index[p1]] = v1.data[p1] * v2[v1.index[p1]];
1110
1111      return r;
1112    }
1113
1114  template <class T>
1115    Sparse_Vec<T> elem_mult_s(const Sparse_Vec<T> &v1, const Vec<T> &v2)
1116    {
1117      it_assert_debug(v1.v_size == v2.size(), "elem_mult(Sparse_Vec<T>, Vec<T>)");
1118
1119      Sparse_Vec<T> r(v1.v_size);
1120      for (int p1=0; p1<v1.used_size; p1++) {
1121        if (v2[v1.index[p1]] != T(0)) {
1122          if (r.used_size == r.data_size)
1123            r.resize_data(r.used_size*2+100);
1124          r.data[r.used_size] = v1.data[p1] * v2[v1.index[p1]];
1125          r.index[r.used_size] = v1.index[p1];
1126          r.used_size++;
1127        }
1128      }
1129      r.compact();
1130
1131      return r;
1132    }
1133
1134  template <class T>
1135    Vec<T> elem_mult(const Vec<T> &v1, const Sparse_Vec<T> &v2)
1136    {
1137      it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
1138
1139      Vec<T> r(v2.v_size);
1140      r = T(0);
1141      for (int p2=0; p2<v2.used_size; p2++)
1142        r[v2.index[p2]] = v1[v2.index[p2]] * v2.data[p2];
1143
1144      return r;
1145    }
1146
1147  template <class T>
1148    Sparse_Vec<T> elem_mult_s(const Vec<T> &v1, const Sparse_Vec<T> &v2)
1149    {
1150      it_assert_debug(v1.size() == v2.v_size, "elem_mult(Vec<T>, Sparse_Vec<T>)");
1151
1152      Sparse_Vec<T> r(v2.v_size);
1153      for (int p2=0; p2<v2.used_size; p2++) {
1154        if (v1[v2.index[p2]] != T(0)) {
1155          if (r.used_size == r.data_size)
1156            r.resize_data(r.used_size*2+100);
1157          r.data[r.used_size] = v1[v2.index[p2]] * v2.data[p2];
1158          r.index[r.used_size] = v2.index[p2];
1159          r.used_size++;
1160        }
1161      }
1162      r.compact();
1163
1164      return r;
1165    }
1166
1167  template <class T>
1168    Sparse_Vec<T> operator+(const Sparse_Vec<T> &v1, const Sparse_Vec<T> &v2)
1169    {
1170      it_assert_debug(v1.v_size == v2.v_size, "Sparse_Vec<T> + Sparse_Vec<T>");
1171
1172      Sparse_Vec<T> r(v1);
1173      ivec pos(v1.v_size);
1174      pos = -1;
1175      for (int p1=0; p1<v1.used_size; p1++)
1176        pos[v1.index[p1]] = p1;
1177      for (int p2=0; p2<v2.used_size; p2++) {
1178        if (pos[v2.index[p2]] == -1) {// A new entry
1179          if (r.used_size == r.data_size)
1180            r.resize_data(r.used_size*2+100);
1181          r.data[r.used_size] = v2.data[p2];
1182          r.index[r.used_size] = v2.index[p2];
1183          r.used_size++;
1184        }
1185        else
1186          r.data[pos[v2.index[p2]]] += v2.data[p2];
1187      }
1188      r.check_small_elems_flag = true;  // added dec 7, 2006
1189      r.compact();
1190
1191      return r;
1192    }
1193
1194  //! Convert a dense vector \c v into its sparse representation
1195  template <class T>
1196    inline Sparse_Vec<T> sparse(const Vec<T> &v)
1197    {
1198      Sparse_Vec<T> s(v);
1199      return s;
1200    }
1201
1202  //! Convert a dense vector \c v into its sparse representation
1203  template <class T>
1204    inline Sparse_Vec<T> sparse(const Vec<T> &v, T epsilon)
1205    {
1206      Sparse_Vec<T> s(v, epsilon);
1207      return s;
1208    }
1209
1210  //! Convert a sparse vector \c s into its dense representation
1211  template <class T>
1212    inline Vec<T> full(const Sparse_Vec<T> &s)
1213    {
1214      Vec<T> v;
1215      s.full(v);
1216      return v;
1217    }
1218
1219  //! \cond
1220
1221  // ---------------------------------------------------------------------
1222  // Instantiations
1223  // ---------------------------------------------------------------------
1224
1225#ifdef HAVE_EXTERN_TEMPLATE
1226
1227  extern template class Sparse_Vec<int>;
1228  extern template class Sparse_Vec<double>;
1229  extern template class Sparse_Vec<std::complex<double> >;
1230
1231  extern template sparse_ivec operator+(const sparse_ivec &,
1232                                        const sparse_ivec &);
1233  extern template sparse_vec operator+(const sparse_vec &,
1234                                       const sparse_vec &);
1235  extern template sparse_cvec operator+(const sparse_cvec &,
1236                                        const sparse_cvec &);
1237
1238  extern template int operator*(const sparse_ivec &, const sparse_ivec &);
1239  extern template double operator*(const sparse_vec &, const sparse_vec &);
1240  extern template std::complex<double> operator*(const sparse_cvec &,
1241                                                 const sparse_cvec &);
1242
1243  extern template int operator*(const sparse_ivec &, const ivec &);
1244  extern template double operator*(const sparse_vec &, const vec &);
1245  extern template std::complex<double> operator*(const sparse_cvec &,
1246                                                 const cvec &);
1247
1248  extern template int operator*(const ivec &, const sparse_ivec &);
1249  extern template double operator*(const vec &, const sparse_vec &);
1250  extern template std::complex<double> operator*(const cvec &,
1251                                                 const sparse_cvec &);
1252
1253  extern template sparse_ivec elem_mult(const sparse_ivec &,
1254                                        const sparse_ivec &);
1255  extern template sparse_vec elem_mult(const sparse_vec &, const sparse_vec &);
1256  extern template sparse_cvec elem_mult(const sparse_cvec &,
1257                                        const sparse_cvec &);
1258
1259  extern template ivec elem_mult(const sparse_ivec &, const ivec &);
1260  extern template vec elem_mult(const sparse_vec &, const vec &);
1261  extern template cvec elem_mult(const sparse_cvec &, const cvec &);
1262
1263  extern template sparse_ivec elem_mult_s(const sparse_ivec &, const ivec &);
1264  extern template sparse_vec elem_mult_s(const sparse_vec &, const vec &);
1265  extern template sparse_cvec elem_mult_s(const sparse_cvec &, const cvec &);
1266
1267  extern template ivec elem_mult(const ivec &, const sparse_ivec &);
1268  extern template vec elem_mult(const vec &, const sparse_vec &);
1269  extern template cvec elem_mult(const cvec &, const sparse_cvec &);
1270
1271  extern template sparse_ivec elem_mult_s(const ivec &, const sparse_ivec &);
1272  extern template sparse_vec elem_mult_s(const vec &, const sparse_vec &);
1273  extern template sparse_cvec elem_mult_s(const cvec &, const sparse_cvec &);
1274
1275#endif // HAVE_EXTERN_TEMPLATE
1276
1277  //! \endcond
1278
1279} // namespace itpp
1280
1281#endif // #ifndef SVEC_H
Note: See TracBrowser for help on using the browser.