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

SHOGUN Machine Learning Toolbox - Documentation