SHOGUN  3.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SGVector.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2013 Thoralf Klein
8  * Written (W) 2011-2013 Heiko Strathmann
9  * Written (W) 2013 Soumyajit De
10  * Written (W) 2012 Fernando José Iglesias García
11  * Written (W) 2010,2012 Soeren Sonnenburg
12  * Copyright (C) 2010 Berlin Institute of Technology
13  * Copyright (C) 2012 Soeren Sonnenburg
14  */
15 
16 #include <shogun/lib/config.h>
17 #include <shogun/lib/SGVector.h>
18 #include <shogun/lib/SGMatrix.h>
21 #include <shogun/io/File.h>
22 
25 #include <algorithm>
26 
28 
29 #define COMPLEX128_ERROR_NOARG(function) \
30 template <> \
31 void SGVector<complex128_t>::function() \
32 { \
33  SG_SERROR("SGVector::%s():: Not supported for complex128_t\n",\
34  #function);\
35 }
36 
37 #define BOOL_ERROR_ONEARG(function) \
38 template <> \
39 void SGVector<bool>::function(bool a) \
40 { \
41  SG_SERROR("SGVector::%s():: Not supported for bool\n",\
42  #function);\
43 }
44 
45 #define COMPLEX128_ERROR_ONEARG(function) \
46 template <> \
47 void SGVector<complex128_t>::function(complex128_t a) \
48 { \
49  SG_SERROR("SGVector::%s():: Not supported for complex128_t\n",\
50  #function);\
51 }
52 
53 #define COMPLEX128_ERROR_TWOARGS(function) \
54 template <> \
55 void SGVector<complex128_t>::function(complex128_t a, complex128_t b) \
56 { \
57  SG_SERROR("SGVector::%s():: Not supported for complex128_t\n",\
58  #function);\
59 }
60 
61 #define COMPLEX128_ERROR_THREEARGS(function) \
62 template <> \
63 void SGVector<complex128_t>::function(complex128_t a, complex128_t b,\
64  complex128_t c) \
65 { \
66  SG_SERROR("SGVector::%s():: Not supported for complex128_t\n",\
67  #function);\
68 }
69 
70 namespace shogun {
71 
72 template<class T>
74 {
75  init_data();
76 }
77 
78 template<class T>
79 SGVector<T>::SGVector(T* v, index_t len, bool ref_counting)
80 : SGReferencedData(ref_counting), vector(v), vlen(len)
81 {
82 }
83 
84 template<class T>
85 SGVector<T>::SGVector(index_t len, bool ref_counting)
86 : SGReferencedData(ref_counting), vlen(len)
87 {
88  vector=SG_MALLOC(T, len);
89 }
90 
91 template<class T>
93 {
94  copy_data(orig);
95 }
96 
97 template<class T>
99 {
100  *this = SGVector<T>(orig);
101 }
102 
103 template<class T>
105 {
106  unref();
107 }
108 
109 #ifdef HAVE_EIGEN3
110 template <class T>
111 SGVector<T>::SGVector(EigenVectorXt& vec)
112 : SGReferencedData(false), vector(vec.data()), vlen(vec.size())
113 {
114 
115 }
116 
117 template <class T>
118 SGVector<T>::SGVector(EigenRowVectorXt& vec)
119 : SGReferencedData(false), vector(vec.data()), vlen(vec.size())
120 {
121 
122 }
123 
124 template <class T>
125 SGVector<T>::operator EigenVectorXtMap() const
126 {
127  return EigenVectorXtMap(vector, vlen);
128 }
129 
130 template <class T>
131 SGVector<T>::operator EigenRowVectorXtMap() const
132 {
133  return EigenRowVectorXtMap(vector, vlen);
134 }
135 #endif
136 
137 template<class T>
139 {
140  if (vector && vlen)
141  set_const(0);
142 }
143 
144 template <>
146 {
147  if (vector && vlen)
148  set_const(complex128_t(0.0));
149 }
150 
151 template<class T>
152 void SGVector<T>::set_const(T const_elem)
153 {
154  for (index_t i=0; i<vlen; i++)
155  vector[i]=const_elem ;
156 }
157 
158 #if HAVE_CATLAS
159 template<>
161 {
162  catlas_dset(vlen, const_elem, vector, 1);
163 }
164 
165 template<>
166 void SGVector<float32_t>::set_const(float32_t const_elem)
167 {
168  catlas_sset(vlen, const_elem, vector, 1);
169 }
170 #endif // HAVE_CATLAS
171 
172 template<class T>
174 {
175  range_fill_vector(vector, vlen, start);
176 }
177 
178 COMPLEX128_ERROR_ONEARG(range_fill)
179 
180 template<class T>
181 void SGVector<T>::random(T min_value, T max_value)
182 {
183  random_vector(vector, vlen, min_value, max_value);
184 }
185 
187 
188 template<class T>
189 void SGVector<T>::randperm()
190 {
191  randperm(vector, vlen);
192 }
193 
194 COMPLEX128_ERROR_NOARG(randperm)
195 
196 template <class T>
197 void SGVector<T>::qsort()
198 {
199  CMath::qsort<T>(vector, vlen);
200 }
201 
203 
204 
205 template<class T>
207 {
209  IndexSorter(const SGVector<T> *vec) { data = vec->vector; }
210 
212  bool operator() (index_t i, index_t j) const
213  {
214  return CMath::abs(data[i]-data[j])>std::numeric_limits<T>::epsilon()
215  && data[i]<data[j];
216  }
217 
219  const T* data;
220 };
221 
222 template<class T>
224 {
225  IndexSorter<T> cmp(this);
226  SGVector<index_t> idx(vlen);
227  for (index_t i=0; i < vlen; ++i)
228  idx[i] = i;
229 
230  std::sort(idx.vector, idx.vector+vlen, cmp);
231 
232  return idx;
233 }
234 
235 template <>
237 {
238  SG_SERROR("SGVector::argsort():: Not supported for complex128_t\n");
239  SGVector<index_t> idx(vlen);
240  return idx;
241 }
242 
243 template <class T>
245 {
246  if (vlen < 2)
247  return true;
248 
249  for(int32_t i=1; i<vlen; i++)
250  {
251  if (vector[i-1] > vector[i])
252  return false;
253  }
254 
255  return true;
256 }
257 
258 template <>
260 {
261  SG_SERROR("SGVector::is_sorted():: Not supported for complex128_t\n");
262  return false;
263 }
264 
265 template <class T>
267 {
268  index_t i;
269  for (i=0; i<vlen; ++i)
270  {
271  if (vector[i]>element)
272  break;
273  }
274  return i;
275 }
276 
277 template <>
279 {
280  SG_SERROR("SGVector::find_position_to_insert():: \
281  Not supported for complex128_t\n");
282  return index_t(-1);
283 }
284 
285 template<class T>
287 {
288  return SGVector<T>(clone_vector(vector, vlen), vlen);
289 }
290 
291 template<class T>
292 T* SGVector<T>::clone_vector(const T* vec, int32_t len)
293 {
294  T* result = SG_MALLOC(T, len);
295  memcpy(result, vec, sizeof(T)*len);
296  return result;
297 }
298 
299 template<class T>
300 void SGVector<T>::fill_vector(T* vec, int32_t len, T value)
301 {
302  for (int32_t i=0; i<len; i++)
303  vec[i]=value;
304 }
305 
306 template<class T>
307 void SGVector<T>::range_fill_vector(T* vec, int32_t len, T start)
308 {
309  for (int32_t i=0; i<len; i++)
310  vec[i]=i+start;
311 }
312 
313 template <>
315  int32_t len, complex128_t start)
316 {
317  SG_SERROR("SGVector::range_fill_vector():: \
318  Not supported for complex128_t\n");
319 }
320 
321 template<class T>
323 {
324  ASSERT(vector && (index>=0) && (index<vlen))
325  return vector[index];
326 }
327 
328 template<class T>
329 void SGVector<T>::set_element(const T& p_element, index_t index)
330 {
331  ASSERT(vector && (index>=0) && (index<vlen))
332  vector[index]=p_element;
333 }
334 
335 template<class T>
337 {
338  vector=SG_REALLOC(T, vector, vlen, n);
339 
340  if (n > vlen)
341  memset(&vector[vlen], 0, (n-vlen)*sizeof(T));
342  vlen=n;
343 }
344 
346 template<class T>
348 {
349  ASSERT(x.vector && vector)
350  ASSERT(x.vlen == vlen)
351 
352  SGVector<T> result=clone();
353  result.add(x);
354  return result;
355 }
356 
357 template<class T>
359 {
360  ASSERT(x.vector && vector)
361  ASSERT(x.vlen == vlen)
362 
363  for (int32_t i=0; i<vlen; i++)
364  vector[i]+=x.vector[i];
365 }
366 
367 template<class T>
368 void SGVector<T>::add(const T x)
369 {
370  ASSERT(vector)
371 
372  for (int32_t i=0; i<vlen; i++)
373  vector[i]+=x;
374 }
375 
376 template<class T>
378 {
379  if (x.features)
380  {
381  for (int32_t i=0; i < x.num_feat_entries; i++)
382  {
383  index_t idx = x.features[i].feat_index;
384  ASSERT(idx < vlen)
385  vector[idx] += x.features[i].entry;
386  }
387  }
388 }
389 
390 template<class T>
392 {
393  SG_SPRINT("SGVector '%p' of size: %d\n", vector, vlen)
394 }
395 
396 template<class T>
398 {
399  vector=((SGVector*)(&orig))->vector;
400  vlen=((SGVector*)(&orig))->vlen;
401 }
402 
403 template<class T>
405 {
406  vector=NULL;
407  vlen=0;
408 }
409 
410 template<class T>
412 {
413  SG_FREE(vector);
414  vector=NULL;
415  vlen=0;
416 }
417 
418 template<class T>
420 {
421  if (other.vlen!=vlen)
422  return false;
423 
424  for (index_t i=0; i<vlen; ++i)
425  {
426  if (other.vector[i]!=vector[i])
427  return false;
428  }
429 
430  return true;
431 }
432 
433 template<class T>
434 void SGVector<T>::display_vector(const char* name,
435  const char* prefix) const
436 {
437  display_vector(vector, vlen, name, prefix);
438 }
439 
440 template <class T>
441 void SGVector<T>::display_vector(const SGVector<T> vector, const char* name,
442  const char* prefix)
443 {
444  vector.display_vector(prefix);
445 }
446 
447 template <>
448 void SGVector<bool>::display_vector(const bool* vector, int32_t n, const char* name,
449  const char* prefix)
450 {
451  ASSERT(n>=0)
452  SG_SPRINT("%s%s=[", prefix, name)
453  for (int32_t i=0; i<n; i++)
454  SG_SPRINT("%s%d%s", prefix, vector[i] ? 1 : 0, i==n-1? "" : ",")
455  SG_SPRINT("%s]\n", prefix)
456 }
457 
458 template <>
459 void SGVector<char>::display_vector(const char* vector, int32_t n, const char* name,
460  const char* prefix)
461 {
462  ASSERT(n>=0)
463  SG_SPRINT("%s%s=[", prefix, name)
464  for (int32_t i=0; i<n; i++)
465  SG_SPRINT("%s%c%s", prefix, vector[i], i==n-1? "" : ",")
466  SG_SPRINT("%s]\n", prefix)
467 }
468 
469 template <>
470 void SGVector<uint8_t>::display_vector(const uint8_t* vector, int32_t n, const char* name,
471  const char* prefix)
472 {
473  ASSERT(n>=0)
474  SG_SPRINT("%s%s=[", prefix, name)
475  for (int32_t i=0; i<n; i++)
476  SG_SPRINT("%s%u%s", prefix, vector[i], i==n-1? "" : ",")
477  SG_SPRINT("%s]\n", prefix)
478 }
479 
480 template <>
481 void SGVector<int8_t>::display_vector(const int8_t* vector, int32_t n, const char* name,
482  const char* prefix)
483 {
484  ASSERT(n>=0)
485  SG_SPRINT("%s%s=[", prefix, name)
486  for (int32_t i=0; i<n; i++)
487  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",")
488  SG_SPRINT("%s]\n", prefix)
489 }
490 
491 template <>
492 void SGVector<uint16_t>::display_vector(const uint16_t* vector, int32_t n, const char* name,
493  const char* prefix)
494 {
495  ASSERT(n>=0)
496  SG_SPRINT("%s%s=[", prefix, name)
497  for (int32_t i=0; i<n; i++)
498  SG_SPRINT("%s%u%s", prefix, vector[i], i==n-1? "" : ",")
499  SG_SPRINT("%s]\n", prefix)
500 }
501 
502 template <>
503 void SGVector<int16_t>::display_vector(const int16_t* vector, int32_t n, const char* name,
504  const char* prefix)
505 {
506  ASSERT(n>=0)
507  SG_SPRINT("%s%s=[", prefix, name)
508  for (int32_t i=0; i<n; i++)
509  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",")
510  SG_SPRINT("%s]\n", prefix)
511 }
512 
513 template <>
514 void SGVector<int32_t>::display_vector(const int32_t* vector, int32_t n, const char* name,
515  const char* prefix)
516 {
517  ASSERT(n>=0)
518  SG_SPRINT("%s%s=[", prefix, name)
519  for (int32_t i=0; i<n; i++)
520  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",")
521  SG_SPRINT("%s]\n", prefix)
522 }
523 
524 template <>
525 void SGVector<uint32_t>::display_vector(const uint32_t* vector, int32_t n, const char* name,
526  const char* prefix)
527 {
528  ASSERT(n>=0)
529  SG_SPRINT("%s%s=[", prefix, name)
530  for (int32_t i=0; i<n; i++)
531  SG_SPRINT("%s%u%s", prefix, vector[i], i==n-1? "" : ",")
532  SG_SPRINT("%s]\n", prefix)
533 }
534 
535 
536 template <>
537 void SGVector<int64_t>::display_vector(const int64_t* vector, int32_t n, const char* name,
538  const char* prefix)
539 {
540  ASSERT(n>=0)
541  SG_SPRINT("%s%s=[", prefix, name)
542  for (int32_t i=0; i<n; i++)
543  SG_SPRINT("%s%lld%s", prefix, vector[i], i==n-1? "" : ",")
544  SG_SPRINT("%s]\n", prefix)
545 }
546 
547 template <>
548 void SGVector<uint64_t>::display_vector(const uint64_t* vector, int32_t n, const char* name,
549  const char* prefix)
550 {
551  ASSERT(n>=0)
552  SG_SPRINT("%s%s=[", prefix, name)
553  for (int32_t i=0; i<n; i++)
554  SG_SPRINT("%s%llu%s", prefix, vector[i], i==n-1? "" : ",")
555  SG_SPRINT("%s]\n", prefix)
556 }
557 
558 template <>
559 void SGVector<float32_t>::display_vector(const float32_t* vector, int32_t n, const char* name,
560  const char* prefix)
561 {
562  ASSERT(n>=0)
563  SG_SPRINT("%s%s=[", prefix, name)
564  for (int32_t i=0; i<n; i++)
565  SG_SPRINT("%s%g%s", prefix, vector[i], i==n-1? "" : ",")
566  SG_SPRINT("%s]\n", prefix)
567 }
568 
569 template <>
570 void SGVector<float64_t>::display_vector(const float64_t* vector, int32_t n, const char* name,
571  const char* prefix)
572 {
573  ASSERT(n>=0)
574  SG_SPRINT("%s%s=[", prefix, name)
575  for (int32_t i=0; i<n; i++)
576  SG_SPRINT("%s%.18g%s", prefix, vector[i], i==n-1? "" : ",")
577  SG_SPRINT("%s]\n", prefix)
578 }
579 
580 template <>
581 void SGVector<floatmax_t>::display_vector(const floatmax_t* vector, int32_t n,
582  const char* name, const char* prefix)
583 {
584  ASSERT(n>=0)
585  SG_SPRINT("%s%s=[", prefix, name)
586  for (int32_t i=0; i<n; i++)
587  {
588  SG_SPRINT("%s%.36Lg%s", prefix, (long double) vector[i],
589  i==n-1? "" : ",");
590  }
591  SG_SPRINT("%s]\n", prefix)
592 }
593 
594 template <>
596  const char* name, const char* prefix)
597 {
598  ASSERT(n>=0)
599  SG_SPRINT("%s%s=[", prefix, name)
600  for (int32_t i=0; i<n; i++)
601  {
602  SG_SPRINT("%s(%.36lg+i%.36lg)%s", prefix, vector[i].real(),
603  vector[i].imag(), i==n-1? "" : ",");
604  }
605  SG_SPRINT("%s]\n", prefix)
606 }
607 
608 template <class T>
610  const T scalar, const T* vec2, int32_t n)
611 {
612  for (int32_t i=0; i<n; i++)
613  vec1[i]+=scalar*vec2[i];
614 }
615 
616 template <>
618  float64_t scalar, const float64_t* vec2, int32_t n)
619 {
620 #ifdef HAVE_LAPACK
621  int32_t skip=1;
622  cblas_daxpy(n, scalar, vec2, skip, vec1, skip);
623 #else
624  for (int32_t i=0; i<n; i++)
625  vec1[i]+=scalar*vec2[i];
626 #endif
627 }
628 
629 template <>
631  float32_t scalar, const float32_t* vec2, int32_t n)
632 {
633 #ifdef HAVE_LAPACK
634  int32_t skip=1;
635  cblas_saxpy(n, scalar, vec2, skip, vec1, skip);
636 #else
637  for (int32_t i=0; i<n; i++)
638  vec1[i]+=scalar*vec2[i];
639 #endif
640 }
641 
642 template <class T>
643 float64_t SGVector<T>::dot(const float64_t* v1, const float64_t* v2, int32_t n)
644 {
645  float64_t r=0;
646 #ifdef HAVE_EIGEN3
647  Eigen::Map<const Eigen::VectorXd> ev1(v1,n);
648  Eigen::Map<const Eigen::VectorXd> ev2(v2,n);
649  r = ev1.dot(ev2);
650 #elif HAVE_LAPACK
651  int32_t skip=1;
652  r = cblas_ddot(n, v1, skip, v2, skip);
653 #else
654  for (int32_t i=0; i<n; i++)
655  r+=v1[i]*v2[i];
656 #endif
657  return r;
658 }
659 
660 template <class T>
661 float32_t SGVector<T>::dot(const float32_t* v1, const float32_t* v2, int32_t n)
662 {
663  float32_t r=0;
664 #ifdef HAVE_EIGEN3
665  Eigen::Map<const Eigen::VectorXf> ev1(v1,n);
666  Eigen::Map<const Eigen::VectorXf> ev2(v2,n);
667  r = ev1.dot(ev2);
668 #elif HAVE_LAPACK
669  int32_t skip=1;
670  r = cblas_sdot(n, v1, skip, v2, skip);
671 #else
672  for (int32_t i=0; i<n; i++)
673  r+=v1[i]*v2[i];
674 #endif
675  return r;
676 }
677 
678 template <class T>
679  void SGVector<T>::random_vector(T* vec, int32_t len, T min_value, T max_value)
680  {
681  for (int32_t i=0; i<len; i++)
682  vec[i]=CMath::random(min_value, max_value);
683  }
684 
685 template <>
687  complex128_t min_value, complex128_t max_value)
688 {
690 }
691 
692 template <class T>
694 {
695  return SGVector<T>(randperm(n), n);
696 }
697 
698 template <>
700 {
702  SGVector<complex128_t> perm(n);
703  return perm;
704 }
705 
706 template <class T>
708 {
709  T* perm = SG_MALLOC(T, n);
710  randperm(perm, n);
711 
712  return perm;
713 }
714 
715 template <>
717 {
719  SGVector<complex128_t> perm(n);
720  return perm.vector;
721 }
722 
723 template <class T>
724 void SGVector<T>::randperm(T* perm, int32_t n)
725 {
726  for (int32_t i = 0; i < n; i++)
727  perm[i] = i;
728  permute(perm,n);
729 }
730 
731 template <>
733 {
735 }
736 
738 template <class T>
739 void SGVector<T>::permute(T* vec, int32_t n)
740 {
741  for (int32_t i = 0; i < n; i++)
742  CMath::swap(vec[i], vec[CMath::random(i, n-1)]);
743 }
744 
745 template <class T>
746 void SGVector<T>::permute(T* vec, int32_t n, CRandom * rand)
747 {
748  for (int32_t i = 0; i < n; i++)
749  CMath::swap(vec[i], vec[rand->random(i, n-1)]);
750 }
751 
752 template<class T>
754 {
755  SGVector<T>::permute(vector, vlen);
756 }
757 
758 template<class T>
760 {
761  SGVector<T>::permute(vector, vlen, rand);
762 }
763 
764 template <class T>
766 {
767  for (index_t i=0; i<vec.vlen; ++i)
768  {
769  CMath::swap(vec.vector[i],
770  vec.vector[CMath::random(i, vec.vlen-1)]);
771  }
772 }
773 
774 template <>
775 bool SGVector<bool>::twonorm(const bool* x, int32_t len)
776 {
778  return false;
779 }
780 
781 template <>
782 char SGVector<char>::twonorm(const char* x, int32_t len)
783 {
785  return '\0';
786 }
787 
788 template <>
789 int8_t SGVector<int8_t>::twonorm(const int8_t* x, int32_t len)
790 {
791  float64_t result=0;
792  for (int32_t i=0; i<len; i++)
793  result+=x[i]*x[i];
794 
795  return CMath::sqrt(result);
796 }
797 
798 template <>
799 uint8_t SGVector<uint8_t>::twonorm(const uint8_t* x, int32_t len)
800 {
801  float64_t result=0;
802  for (int32_t i=0; i<len; i++)
803  result+=x[i]*x[i];
804 
805  return CMath::sqrt(result);
806 }
807 
808 template <>
809 int16_t SGVector<int16_t>::twonorm(const int16_t* x, int32_t len)
810 {
811  float64_t result=0;
812  for (int32_t i=0; i<len; i++)
813  result+=x[i]*x[i];
814 
815  return CMath::sqrt(result);
816 }
817 
818 template <>
819 uint16_t SGVector<uint16_t>::twonorm(const uint16_t* x, int32_t len)
820 {
821  float64_t result=0;
822  for (int32_t i=0; i<len; i++)
823  result+=x[i]*x[i];
824 
825  return CMath::sqrt(result);
826 }
827 
828 template <>
829 int32_t SGVector<int32_t>::twonorm(const int32_t* x, int32_t len)
830 {
831  float64_t result=0;
832  for (int32_t i=0; i<len; i++)
833  result+=x[i]*x[i];
834 
835  return CMath::sqrt(result);
836 }
837 
838 template <>
839 uint32_t SGVector<uint32_t>::twonorm(const uint32_t* x, int32_t len)
840 {
841  float64_t result=0;
842  for (int32_t i=0; i<len; i++)
843  result+=x[i]*x[i];
844 
845  return CMath::sqrt(result);
846 }
847 
848 template <>
849 int64_t SGVector<int64_t>::twonorm(const int64_t* x, int32_t len)
850 {
851  float64_t result=0;
852  for (int32_t i=0; i<len; i++)
853  result+=x[i]*x[i];
854 
855  return CMath::sqrt(result);
856 }
857 
858 template <>
859 uint64_t SGVector<uint64_t>::twonorm(const uint64_t* x, int32_t len)
860 {
861  float64_t result=0;
862  for (int32_t i=0; i<len; i++)
863  result+=x[i]*x[i];
864 
865  return CMath::sqrt(result);
866 }
867 
868 template <>
870 {
871  float64_t result=0;
872  for (int32_t i=0; i<len; i++)
873  result+=x[i]*x[i];
874 
875  return CMath::sqrt(result);
876 }
877 
878 template <>
880 {
881  float64_t norm = 0.0;
882 #ifdef HAVE_LAPACK
883  norm = cblas_dnrm2(n, v, 1);
884 #else
885  norm = CMath::sqrt(SGVector::dot(v, v, n));
886 #endif
887  return norm;
888 }
889 
890 template <>
892 {
893  float64_t result=0;
894  for (int32_t i=0; i<len; i++)
895  result+=x[i]*x[i];
896 
897  return CMath::sqrt(result);
898 }
899 
900 template <>
902 {
903  complex128_t result(0.0);
904  for (int32_t i=0; i<len; i++)
905  result+=x[i]*x[i];
906 
907  return CMath::sqrt(result);
908 }
909 
910 template <class T>
911 float64_t SGVector<T>::onenorm(T* x, int32_t len)
912 {
913  float64_t result=0;
914  for (int32_t i=0;i<len; ++i)
915  result+=CMath::abs(x[i]);
916 
917  return result;
918 }
919 
921 template <class T>
922 T SGVector<T>::qsq(T* x, int32_t len, float64_t q)
923 {
924  float64_t result=0;
925  for (int32_t i=0; i<len; i++)
926  result+=CMath::pow(fabs(x[i]), q);
927 
928  return result;
929 }
930 
931 template <>
933 {
935  return complex128_t(0.0);
936 }
937 
939 template <class T>
940 T SGVector<T>::qnorm(T* x, int32_t len, float64_t q)
941 {
942  ASSERT(q!=0)
943  return CMath::pow((float64_t) qsq(x, len, q), 1.0/q);
944 }
945 
946 template <>
948 {
950  return complex128_t(0.0);
951 }
952 
954 template <class T>
955  T SGVector<T>::min(T* vec, int32_t len)
956  {
957  ASSERT(len>0)
958  T minv=vec[0];
959 
960  for (int32_t i=1; i<len; i++)
961  minv=CMath::min(vec[i], minv);
962 
963  return minv;
964  }
965 
966 #ifdef HAVE_LAPACK
967 template <>
969 {
970  ASSERT(len>0)
971  int32_t skip = 1;
972  int32_t idx = cblas_idamax(len, vec, skip);
973 
974  return CMath::abs(vec[idx]);
975 }
976 
977 template <>
979 {
980  ASSERT(len>0)
981  int32_t skip = 1;
982  int32_t idx = cblas_isamax(len, vec, skip);
983 
984  return CMath::abs(vec[idx]);
985 }
986 #endif
987 
989 template <class T>
990 T SGVector<T>::max_abs(T* vec, int32_t len)
991 {
992  ASSERT(len>0)
993  T maxv=CMath::abs(vec[0]);
994 
995  for (int32_t i=1; i<len; i++)
996  maxv=CMath::max(CMath::abs(vec[i]), maxv);
997 
998  return maxv;
999 }
1000 
1001 template <>
1003 {
1005  return complex128_t(0.0);
1006 }
1007 
1009 template <class T>
1010 T SGVector<T>::max(T* vec, int32_t len)
1011 {
1012  ASSERT(len>0)
1013  T maxv=vec[0];
1014 
1015  for (int32_t i=1; i<len; i++)
1016  maxv=CMath::max(vec[i], maxv);
1017 
1018  return maxv;
1019 }
1020 
1021 #ifdef HAVE_LAPACK
1022 template <>
1023 int32_t SGVector<float64_t>::arg_max_abs(float64_t* vec, int32_t inc, int32_t len, float64_t* maxv_ptr)
1024 {
1025  ASSERT(len>0 || inc > 0)
1026  int32_t idx = cblas_idamax(len, vec, inc);
1027 
1028  if (maxv_ptr != NULL)
1029  *maxv_ptr = CMath::abs(vec[idx*inc]);
1030 
1031  return idx;
1032 }
1033 
1034 template <>
1035 int32_t SGVector<float32_t>::arg_max_abs(float32_t* vec, int32_t inc, int32_t len, float32_t* maxv_ptr)
1036 {
1037  ASSERT(len>0 || inc > 0)
1038  int32_t idx = cblas_isamax(len, vec, inc);
1039 
1040  if (maxv_ptr != NULL)
1041  *maxv_ptr = CMath::abs(vec[idx*inc]);
1042 
1043  return idx;
1044 }
1045 #endif
1046 
1047 template <class T>
1048 int32_t SGVector<T>::arg_max_abs(T * vec, int32_t inc, int32_t len, T * maxv_ptr)
1049 {
1050  ASSERT(len > 0 || inc > 0)
1051 
1052  T maxv = CMath::abs(vec[0]);
1053  int32_t maxIdx = 0;
1054 
1055  for (int32_t i = 1, j = inc ; i < len ; i++, j += inc)
1056  {
1057  if (CMath::abs(vec[j]) > maxv)
1058  maxv = CMath::abs(vec[j]), maxIdx = i;
1059  }
1060 
1061  if (maxv_ptr != NULL)
1062  *maxv_ptr = maxv;
1063 
1064  return maxIdx;
1065 }
1066 
1067 template <>
1069  int32_t len, complex128_t * maxv_ptr)
1070 {
1071  int32_t maxIdx = 0;
1072  SG_SERROR("SGVector::arg_max_abs():: Not supported for complex128_t\n");
1073  return maxIdx;
1074 }
1075 
1076 template <class T>
1077 int32_t SGVector<T>::arg_max(T * vec, int32_t inc, int32_t len, T * maxv_ptr)
1078 {
1079  ASSERT(len > 0 || inc > 0)
1080 
1081  T maxv = vec[0];
1082  int32_t maxIdx = 0;
1083 
1084  for (int32_t i = 1, j = inc ; i < len ; i++, j += inc)
1085  {
1086  if (vec[j] > maxv)
1087  maxv = vec[j], maxIdx = i;
1088  }
1089 
1090  if (maxv_ptr != NULL)
1091  *maxv_ptr = maxv;
1092 
1093  return maxIdx;
1094 }
1095 
1096 template <>
1098  int32_t len, complex128_t * maxv_ptr)
1099 {
1100  int32_t maxIdx=0;
1101  SG_SERROR("SGVector::arg_max():: Not supported for complex128_t\n");
1102  return maxIdx;
1103 }
1104 
1105 
1107 template <class T>
1108 int32_t SGVector<T>::arg_min(T * vec, int32_t inc, int32_t len, T * minv_ptr)
1109 {
1110  ASSERT(len > 0 || inc > 0)
1111 
1112  T minv = vec[0];
1113  int32_t minIdx = 0;
1114 
1115  for (int32_t i = 1, j = inc ; i < len ; i++, j += inc)
1116  {
1117  if (vec[j] < minv)
1118  minv = vec[j], minIdx = i;
1119  }
1120 
1121  if (minv_ptr != NULL)
1122  *minv_ptr = minv;
1123 
1124  return minIdx;
1125 }
1126 
1127 template <>
1129  int32_t len, complex128_t * minv_ptr)
1130 {
1131  int32_t minIdx=0;
1132  SG_SERROR("SGVector::arg_min():: Not supported for complex128_t\n");
1133  return minIdx;
1134 }
1135 
1137 template <class T>
1138 T SGVector<T>::sum_abs(T* vec, int32_t len)
1139 {
1140  T result=0;
1141  for (int32_t i=0; i<len; i++)
1142  result+=CMath::abs(vec[i]);
1143 
1144  return result;
1145 }
1146 
1147 #if HAVE_LAPACK
1148 template <>
1150 {
1151  float64_t result=0;
1152  result = cblas_dasum(len, vec, 1);
1153  return result;
1154 }
1155 
1156 template <>
1158 {
1159  float32_t result=0;
1160  result = cblas_sasum(len, vec, 1);
1161  return result;
1162 }
1163 #endif
1164 
1166 template <class T>
1167 bool SGVector<T>::fequal(T x, T y, float64_t precision)
1168 {
1169  return CMath::abs(x-y)<precision;
1170 }
1171 
1172 template <class T>
1173 int32_t SGVector<T>::unique(T* output, int32_t size)
1174 {
1175  CMath::qsort<T>(output, size);
1176  int32_t j=0;
1177 
1178  for (int32_t i=0; i<size; i++)
1179  {
1180  if (i==0 || output[i]!=output[i-1])
1181  output[j++]=output[i];
1182  }
1183  return j;
1184 }
1185 
1186 template <>
1187 int32_t SGVector<complex128_t>::unique(complex128_t* output, int32_t size)
1188 {
1189  int32_t j=0;
1190  SG_SERROR("SGVector::unique():: Not supported for complex128_t\n");
1191  return j;
1192 }
1193 
1194 template <class T>
1196 {
1197  SGVector<index_t> idx(vlen);
1198  index_t k=0;
1199 
1200  for (index_t i=0; i < vlen; ++i)
1201  if (vector[i] == elem)
1202  idx[k++] = i;
1203  idx.vlen = k;
1204  return idx;
1205 }
1206 
1207 template<class T>
1208 void SGVector<T>::scale_vector(T alpha, T* vec, int32_t len)
1209 {
1210  for (int32_t i=0; i<len; i++)
1211  vec[i]*=alpha;
1212 }
1213 
1214 #ifdef HAVE_LAPACK
1215 template<>
1217 {
1218  cblas_dscal(len, alpha, vec, 1);
1219 }
1220 
1221 template<>
1223 {
1224  cblas_sscal(len, alpha, vec, 1);
1225 }
1226 #endif
1227 
1228 template<class T>
1229 void SGVector<T>::scale(T alpha)
1230 {
1231  scale_vector(alpha, vector, vlen);
1232 }
1233 
1234 template<class T> float64_t SGVector<T>::mean() const
1235 {
1236  float64_t cum = 0;
1237 
1238  for ( index_t i = 0 ; i < vlen ; ++i )
1239  cum += vector[i];
1240 
1241  return cum/vlen;
1242 }
1243 
1244 template <>
1246 {
1248  return float64_t(0.0);
1249 }
1250 
1251 template<class T> void SGVector<T>::load(CFile* loader)
1252 {
1253  ASSERT(loader)
1254  unref();
1255 
1257  SGVector<T> vec;
1258  loader->get_vector(vec.vector, vec.vlen);
1259  copy_data(vec);
1260  copy_refcount(vec);
1261  ref();
1263 }
1264 
1265 template<>
1267 {
1268  SG_SERROR("SGVector::load():: Not supported for complex128_t\n");
1269 }
1270 
1271 template<class T> void SGVector<T>::save(CFile* saver)
1272 {
1273  ASSERT(saver)
1274 
1276  saver->set_vector(vector, vlen);
1278 }
1279 
1280 template<>
1282 {
1283  SG_SERROR("SGVector::save():: Not supported for complex128_t\n");
1284 }
1285 
1286 
1287 #define MATHOP(op) \
1288 template <class T> void SGVector<T>::op() \
1289 { \
1290  for (int32_t i=0; i<vlen; i++) \
1291  vector[i]=(T) CMath::op((double) vector[i]); \
1292 }
1293 
1294 MATHOP(abs)
1295 MATHOP(acos)
1296 MATHOP(asin)
1297 MATHOP(atan)
1298 MATHOP(cos)
1299 MATHOP(cosh)
1300 MATHOP(exp)
1301 MATHOP(log)
1302 MATHOP(log10)
1303 MATHOP(sin)
1304 MATHOP(sinh)
1305 MATHOP(sqrt)
1306 MATHOP(tan)
1307 MATHOP(tanh)
1308 #undef MATHOP
1309 
1310 #define COMPLEX128_MATHOP(op) \
1311 template <>\
1312 void SGVector<complex128_t>::op() \
1313 { \
1314  for (int32_t i=0; i<vlen; i++) \
1315  vector[i]=complex128_t(CMath::op(vector[i])); \
1316 }
1317 
1318 COMPLEX128_MATHOP(abs)
1319 COMPLEX128_MATHOP(sin)
1320 COMPLEX128_MATHOP(cos)
1321 COMPLEX128_MATHOP(tan)
1322 COMPLEX128_MATHOP(sinh)
1323 COMPLEX128_MATHOP(cosh)
1324 COMPLEX128_MATHOP(tanh)
1325 COMPLEX128_MATHOP(exp)
1326 COMPLEX128_MATHOP(log)
1327 COMPLEX128_MATHOP(log10)
1328 COMPLEX128_MATHOP(sqrt)
1329 #undef COMPLEX128_MATHOP
1330 
1331 #define COMPLEX128_MATHOP_NOTIMPLEMENTED(op) \
1332 template <>\
1333 void SGVector<complex128_t>::op() \
1334 { \
1335  SG_SERROR("SGVector::%s():: Not supported for complex128_t\n",#op);\
1336 }
1337 
1341 #undef COMPLEX128_MATHOP_NOTIMPLEMENTED
1342 
1343 template <class T> void SGVector<T>::atan2(T x)
1344 {
1345  for (int32_t i=0; i<vlen; i++)
1346  vector[i]=CMath::atan2(vector[i], x);
1347 }
1348 
1349 BOOL_ERROR_ONEARG(atan2)
1351 
1352 template <class T> void SGVector<T>::pow(T q)
1353 {
1354  for (int32_t i=0; i<vlen; i++)
1355  vector[i]=(T) CMath::pow((double) vector[i], (double) q);
1356 }
1357 
1358 template <class T>
1360 {
1361  return SGVector<float64_t>(linspace(start, end, n), n);
1362 }
1363 
1364 template <class T>
1365 float64_t* SGVector<T>::linspace(T start, T end, int32_t n)
1366 {
1367  float64_t* output = SG_MALLOC(float64_t, n);
1368  CMath::linspace(output, start, end, n);
1369 
1370  return output;
1371 }
1372 
1373 template <>
1375 {
1376  float64_t* output = SG_MALLOC(float64_t, n);
1377  SG_SERROR("SGVector::linspace():: Not supported for complex128_t\n");
1378  return output;
1379 }
1380 
1381 template <>
1383 {
1384  for (int32_t i=0; i<vlen; i++)
1385  vector[i]=CMath::pow(vector[i], q);
1386 }
1387 
1389 {
1390  SGVector<float64_t> real(vlen);
1391  for (int32_t i=0; i<vlen; i++)
1392  real[i]=CMath::real(vector[i]);
1393  return real;
1394 }
1395 
1397 {
1398  SGVector<float64_t> imag(vlen);
1399  for (int32_t i=0; i<vlen; i++)
1400  imag[i]=CMath::imag(vector[i]);
1401  return imag;
1402 }
1403 
1404 template <class T>
1406  index_t nrows, index_t ncols, bool fortran_order)
1407 {
1408  if (nrows*ncols>vector.size())
1409  SG_SERROR("SGVector::convert_to_matrix():: Dimensions mismatch\n");
1410 
1411  T* data=NULL;
1412  SGVector<T>::convert_to_matrix(data, nrows, ncols, vector.vector, vector.vlen, fortran_order);
1413 
1414  SGMatrix<T> matrix=SGMatrix<T>(data, nrows, ncols);
1415  return matrix;
1416 }
1417 
1418 template <class T>
1419 void SGVector<T>::convert_to_matrix(T*& matrix, index_t nrows, index_t ncols, const T* vector, int32_t vlen, bool fortran_order)
1420 {
1421  if (nrows*ncols>vlen)
1422  SG_SERROR("SGVector::convert_to_matrix():: Dimensions mismatch\n");
1423 
1424  if (matrix!=NULL)
1425  SG_FREE(matrix);
1426  matrix=SG_MALLOC(T, nrows*ncols);
1427 
1428  if (fortran_order)
1429  {
1430  for (index_t i=0; i<ncols*nrows; i++)
1431  matrix[i]=vector[i];
1432  }
1433  else
1434  {
1435  for (index_t i=0; i<nrows; i++)
1436  {
1437  for (index_t j=0; j<ncols; j++)
1438  matrix[i+j*nrows]=vector[j+i*ncols];
1439  }
1440  }
1441 }
1442 
1443 #define UNDEFINED(function, type) \
1444 template <> \
1445 SGVector<float64_t> SGVector<type>::function() \
1446 { \
1447  SG_SERROR("SGVector::%s():: Not supported for %s\n", \
1448  #function, #type); \
1449  SGVector<float64_t> ret(vlen); \
1450  return ret; \
1451 }
1452 
1453 UNDEFINED(get_real, bool)
1454 UNDEFINED(get_real, char)
1455 UNDEFINED(get_real, int8_t)
1456 UNDEFINED(get_real, uint8_t)
1457 UNDEFINED(get_real, int16_t)
1458 UNDEFINED(get_real, uint16_t)
1459 UNDEFINED(get_real, int32_t)
1460 UNDEFINED(get_real, uint32_t)
1461 UNDEFINED(get_real, int64_t)
1462 UNDEFINED(get_real, uint64_t)
1463 UNDEFINED(get_real, float32_t)
1464 UNDEFINED(get_real, float64_t)
1465 UNDEFINED(get_real, floatmax_t)
1466 UNDEFINED(get_imag, bool)
1467 UNDEFINED(get_imag, char)
1468 UNDEFINED(get_imag, int8_t)
1469 UNDEFINED(get_imag, uint8_t)
1470 UNDEFINED(get_imag, int16_t)
1471 UNDEFINED(get_imag, uint16_t)
1472 UNDEFINED(get_imag, int32_t)
1473 UNDEFINED(get_imag, uint32_t)
1474 UNDEFINED(get_imag, int64_t)
1475 UNDEFINED(get_imag, uint64_t)
1476 UNDEFINED(get_imag, float32_t)
1477 UNDEFINED(get_imag, float64_t)
1478 UNDEFINED(get_imag, floatmax_t)
1479 #undef UNDEFINED
1480 
1481 template class SGVector<bool>;
1482 template class SGVector<char>;
1483 template class SGVector<int8_t>;
1484 template class SGVector<uint8_t>;
1485 template class SGVector<int16_t>;
1486 template class SGVector<uint16_t>;
1487 template class SGVector<int32_t>;
1488 template class SGVector<uint32_t>;
1489 template class SGVector<int64_t>;
1490 template class SGVector<uint64_t>;
1491 template class SGVector<float32_t>;
1492 template class SGVector<float64_t>;
1493 template class SGVector<floatmax_t>;
1494 template class SGVector<complex128_t>;
1495 }
1496 
1497 #undef COMPLEX128_ERROR_NOARG
1498 #undef COMPLEX128_ERROR_ONEARG
1499 #undef COMPLEX128_ERROR_TWOARGS
1500 #undef COMPLEX128_ERROR_THREEARGS

SHOGUN Machine Learning Toolbox - Documentation