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

SHOGUN Machine Learning Toolbox - Documentation