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

SHOGUN Machine Learning Toolbox - Documentation