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

SHOGUN Machine Learning Toolbox - Documentation