SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SGVector.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2012 Fernando José Iglesias García
8  * Written (W) 2010,2012 Soeren Sonnenburg
9  * Copyright (C) 2010 Berlin Institute of Technology
10  * Copyright (C) 2012 Soeren Sonnenburg
11  */
12 #include <shogun/lib/config.h>
14 #include <shogun/lib/SGVector.h>
17 
18 #ifdef HAVE_EIGEN3
20 #endif
21 
22 namespace shogun {
23 
24 template<class T> SGVector<T>::SGVector() : SGReferencedData()
25 {
26  init_data();
27 }
28 
29 template<class T> SGVector<T>::SGVector(T* v, index_t len, bool ref_counting)
30 : SGReferencedData(ref_counting), vector(v), vlen(len)
31 {
32 }
33 
34 template<class T> SGVector<T>::SGVector(index_t len, bool ref_counting)
35 : SGReferencedData(ref_counting), vlen(len)
36 {
37  vector=SG_MALLOC(T, len);
38 }
39 
40 template<class T> SGVector<T>::SGVector(const SGVector &orig) : SGReferencedData(orig)
41 {
42  copy_data(orig);
43 }
44 
45 template<class T> SGVector<T>::~SGVector()
46 {
47  unref();
48 }
49 
50 template<class T> void SGVector<T>::zero()
51 {
52  if (vector && vlen)
53  set_const(0);
54 }
55 
56 template<class T> void SGVector<T>::set_const(T const_elem)
57 {
58  for (index_t i=0; i<vlen; i++)
59  vector[i]=const_elem ;
60 }
61 
62 template<class T> void SGVector<T>::range_fill(T start)
63 {
64  range_fill_vector(vector, vlen, start);
65 }
66 
67 template<class T> void SGVector<T>::random(T min_value, T max_value)
68 {
69  random_vector(vector, vlen, min_value, max_value);
70 }
71 
72 template<class T> void SGVector<T>::randperm()
73 {
74  randperm(vector, vlen);
75 }
76 
77 template<class T> SGVector<T> SGVector<T>::clone() const
78 {
79  return SGVector<T>(clone_vector(vector, vlen), vlen);
80 }
81 
82 template<class T> const T& SGVector<T>::get_element(index_t index)
83 {
84  ASSERT(vector && (index>=0) && (index<vlen));
85  return vector[index];
86 }
87 
88 template<class T> void SGVector<T>::set_element(const T& p_element, index_t index)
89 {
90  ASSERT(vector && (index>=0) && (index<vlen));
91  vector[index]=p_element;
92 }
93 
94 template<class T> void SGVector<T>::resize_vector(int32_t n)
95 {
96  vector=SG_REALLOC(T, vector, n);
97 
98  if (n > vlen)
99  memset(&vector[vlen], 0, (n-vlen)*sizeof(T));
100  vlen=n;
101 }
102 
103 template<class T> void SGVector<T>::add(const SGVector<T> x)
104 {
105  ASSERT(x.vector && vector);
106  ASSERT(x.vlen == vlen);
107 
108  for (int32_t i=0; i<vlen; i++)
109  vector[i]+=x.vector[i];
110 }
111 
112 template<class T> void SGVector<T>::add(const T x)
113 {
114  ASSERT(vector);
115 
116  for (int32_t i=0; i<vlen; i++)
117  vector[i]+=x;
118 }
119 
120 template<class T> void SGVector<T>::display_size() const
121 {
122  SG_SPRINT("SGVector '%p' of size: %d\n", vector, vlen);
123 }
124 
125 template<class T> void SGVector<T>::copy_data(const SGReferencedData &orig)
126 {
127  vector=((SGVector*)(&orig))->vector;
128  vlen=((SGVector*)(&orig))->vlen;
129 }
130 
131 template<class T> void SGVector<T>::init_data()
132 {
133  vector=NULL;
134  vlen=0;
135 }
136 
137 template<class T> void SGVector<T>::free_data()
138 {
139  SG_FREE(vector);
140  vector=NULL;
141  vlen=0;
142 }
143 
144 template<class T> void SGVector<T>::display_vector(const char* name,
145  const char* prefix) const
146 {
147  display_vector(vector, vlen, name, prefix);
148 }
149 
150 template <class T>
151 void SGVector<T>::display_vector(const SGVector<T> vector, const char* name,
152  const char* prefix)
153 {
154  vector.display_vector(prefix);
155 }
156 
157 template <>
158 void SGVector<bool>::display_vector(const bool* vector, int32_t n, const char* name,
159  const char* prefix)
160 {
161  ASSERT(n>=0);
162  SG_SPRINT("%s%s=[", prefix, name);
163  for (int32_t i=0; i<n; i++)
164  SG_SPRINT("%s%d%s", prefix, vector[i] ? 1 : 0, i==n-1? "" : ",");
165  SG_SPRINT("%s]\n", prefix);
166 }
167 
168 template <>
169 void SGVector<char>::display_vector(const char* vector, int32_t n, const char* name,
170  const char* prefix)
171 {
172  ASSERT(n>=0);
173  SG_SPRINT("%s%s=[", prefix, name);
174  for (int32_t i=0; i<n; i++)
175  SG_SPRINT("%s%c%s", prefix, vector[i], i==n-1? "" : ",");
176  SG_SPRINT("%s]\n", prefix);
177 }
178 
179 template <>
180 void SGVector<uint8_t>::display_vector(const uint8_t* vector, int32_t n, const char* name,
181  const char* prefix)
182 {
183  ASSERT(n>=0);
184  SG_SPRINT("%s%s=[", prefix, name);
185  for (int32_t i=0; i<n; i++)
186  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
187  SG_SPRINT("%s]\n", prefix);
188 }
189 
190 template <>
191 void SGVector<int8_t>::display_vector(const int8_t* vector, int32_t n, const char* name,
192  const char* prefix)
193 {
194  ASSERT(n>=0);
195  SG_SPRINT("%s%s=[", prefix, name);
196  for (int32_t i=0; i<n; i++)
197  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
198  SG_SPRINT("%s]\n", prefix);
199 }
200 
201 template <>
202 void SGVector<uint16_t>::display_vector(const uint16_t* vector, int32_t n, const char* name,
203  const char* prefix)
204 {
205  ASSERT(n>=0);
206  SG_SPRINT("%s%s=[", prefix, name);
207  for (int32_t i=0; i<n; i++)
208  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
209  SG_SPRINT("%s]\n", prefix);
210 }
211 
212 template <>
213 void SGVector<int16_t>::display_vector(const int16_t* vector, int32_t n, const char* name,
214  const char* prefix)
215 {
216  ASSERT(n>=0);
217  SG_SPRINT("%s%s=[", prefix, name);
218  for (int32_t i=0; i<n; i++)
219  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
220  SG_SPRINT("%s]\n", prefix);
221 }
222 
223 template <>
224 void SGVector<int32_t>::display_vector(const int32_t* vector, int32_t n, const char* name,
225  const char* prefix)
226 {
227  ASSERT(n>=0);
228  SG_SPRINT("%s%s=[", prefix, name);
229  for (int32_t i=0; i<n; i++)
230  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
231  SG_SPRINT("%s]\n", prefix);
232 }
233 
234 template <>
235 void SGVector<uint32_t>::display_vector(const uint32_t* vector, int32_t n, const char* name,
236  const char* prefix)
237 {
238  ASSERT(n>=0);
239  SG_SPRINT("%s%s=[", prefix, name);
240  for (int32_t i=0; i<n; i++)
241  SG_SPRINT("%s%d%s", prefix, vector[i], i==n-1? "" : ",");
242  SG_SPRINT("%s]\n", prefix);
243 }
244 
245 
246 template <>
247 void SGVector<int64_t>::display_vector(const int64_t* vector, int32_t n, const char* name,
248  const char* prefix)
249 {
250  ASSERT(n>=0);
251  SG_SPRINT("%s%s=[", prefix, name);
252  for (int32_t i=0; i<n; i++)
253  SG_SPRINT("%s%lld%s", prefix, vector[i], i==n-1? "" : ",");
254  SG_SPRINT("%s]\n", prefix);
255 }
256 
257 template <>
258 void SGVector<uint64_t>::display_vector(const uint64_t* vector, int32_t n, const char* name,
259  const char* prefix)
260 {
261  ASSERT(n>=0);
262  SG_SPRINT("%s%s=[", prefix, name);
263  for (int32_t i=0; i<n; i++)
264  SG_SPRINT("%s%llu%s", prefix, vector[i], i==n-1? "" : ",");
265  SG_SPRINT("%s]\n", prefix);
266 }
267 
268 template <>
269 void SGVector<float32_t>::display_vector(const float32_t* vector, int32_t n, const char* name,
270  const char* prefix)
271 {
272  ASSERT(n>=0);
273  SG_SPRINT("%s%s=[", prefix, name);
274  for (int32_t i=0; i<n; i++)
275  SG_SPRINT("%s%g%s", prefix, vector[i], i==n-1? "" : ",");
276  SG_SPRINT("%s]\n", prefix);
277 }
278 
279 template <>
280 void SGVector<float64_t>::display_vector(const float64_t* vector, int32_t n, const char* name,
281  const char* prefix)
282 {
283  ASSERT(n>=0);
284  SG_SPRINT("%s%s=[", prefix, name);
285  for (int32_t i=0; i<n; i++)
286  SG_SPRINT("%s%.18g%s", prefix, vector[i], i==n-1? "" : ",");
287  SG_SPRINT("%s]\n", prefix);
288 }
289 
290 template <>
291 void SGVector<floatmax_t>::display_vector(const floatmax_t* vector, int32_t n,
292  const char* name, const char* prefix)
293 {
294  ASSERT(n>=0);
295  SG_SPRINT("%s%s=[", prefix, name);
296  for (int32_t i=0; i<n; i++)
297  {
298  SG_SPRINT("%s%.36Lg%s", prefix, (long double) vector[i],
299  i==n-1? "" : ",");
300  }
301  SG_SPRINT("%s]\n", prefix);
302 }
303 
304 template <class T>
306  const float64_t scalar, const float64_t* vec2, int32_t n)
307 {
308 #ifdef HAVE_LAPACK
309  int32_t skip=1;
310  cblas_daxpy(n, scalar, vec2, skip, vec1, skip);
311 #else
312  for (int32_t i=0; i<n; i++)
313  vec1[i]+=scalar*vec2[i];
314 #endif
315 }
316 
317 template <class T>
319  const float32_t scalar, const float32_t* vec2, int32_t n)
320 {
321 #ifdef HAVE_LAPACK
322  int32_t skip=1;
323  cblas_saxpy(n, scalar, vec2, skip, vec1, skip);
324 #else
325  for (int32_t i=0; i<n; i++)
326  vec1[i]+=scalar*vec2[i];
327 #endif
328 }
329 
330 template <class T>
331 float64_t SGVector<T>::dot(const float64_t* v1, const float64_t* v2, int32_t n)
332 {
333  float64_t r=0;
334 #ifdef HAVE_EIGEN3
335  Eigen::Map<const Eigen::VectorXd> ev1(v1,n);
336  Eigen::Map<const Eigen::VectorXd> ev2(v2,n);
337  r = ev1.dot(ev2);
338 #else
339 #ifdef HAVE_LAPACK
340  int32_t skip=1;
341  r = cblas_ddot(n, v1, skip, v2, skip);
342 #else
343  for (int32_t i=0; i<n; i++)
344  r+=v1[i]*v2[i];
345 #endif /* HAVE_LAPACK */
346 #endif /* HAVE_EIGEN3 */
347  return r;
348 }
349 
350 template <class T>
351 float32_t SGVector<T>::dot(const float32_t* v1, const float32_t* v2, int32_t n)
352 {
353  float32_t r=0;
354 #ifdef HAVE_EIGEN3
355  Eigen::Map<const Eigen::VectorXf> ev1(v1,n);
356  Eigen::Map<const Eigen::VectorXf> ev2(v2,n);
357  r = ev1.dot(ev2);
358 #else
359 #ifdef HAVE_LAPACK
360  int32_t skip=1;
361  r = cblas_sdot(n, v1, skip, v2, skip);
362 #else
363  for (int32_t i=0; i<n; i++)
364  r+=v1[i]*v2[i];
365 #endif /* HAVE_LAPACK */
366 #endif /* HAVE_EIGEN3 */
367  return r;
368 }
369 
371 template <class T>
372  void SGVector<T>::random_vector(T* vec, int32_t len, T min_value, T max_value)
373  {
374  for (int32_t i=0; i<len; i++)
375  vec[i]=CMath::random(min_value, max_value);
376  }
377 
379 template <class T>
380 void SGVector<T>::randperm(T* perm, int32_t n)
381 {
382  for (int32_t i = 0; i < n; i++)
383  perm[i] = i;
384  permute(perm,n);
385 }
386 
388 template <class T>
389 void SGVector<T>::permute(T* vec, int32_t n)
390 {
391  for (int32_t i = 0; i < n; i++)
392  CMath::swap(vec[i], vec[CMath::random(i, n-1)]);
393 }
394 
395 template<class T> void SGVector<T>::permute()
396 {
397  SGVector<T>::permute(vector, vlen);
398 }
399 
400 template <class T>
402 {
403  for (index_t i=0; i<vec.vlen; ++i)
404  {
405  CMath::swap(vec.vector[i],
406  vec.vector[CMath::random(i, vec.vlen-1)]);
407  }
408 }
409 
410 template <>
411 bool SGVector<bool>::twonorm(const bool* x, int32_t len)
412 {
414  return false;
415 }
416 
417 template <>
418 char SGVector<char>::twonorm(const char* x, int32_t len)
419 {
421  return '\0';
422 }
423 
424 template <>
425 int8_t SGVector<int8_t>::twonorm(const int8_t* x, int32_t len)
426 {
427  float64_t result=0;
428  for (int32_t i=0; i<len; i++)
429  result+=x[i]*x[i];
430 
431  return CMath::sqrt(result);
432 }
433 
434 template <>
435 uint8_t SGVector<uint8_t>::twonorm(const uint8_t* x, int32_t len)
436 {
437  float64_t result=0;
438  for (int32_t i=0; i<len; i++)
439  result+=x[i]*x[i];
440 
441  return CMath::sqrt(result);
442 }
443 
444 template <>
445 int16_t SGVector<int16_t>::twonorm(const int16_t* x, int32_t len)
446 {
447  float64_t result=0;
448  for (int32_t i=0; i<len; i++)
449  result+=x[i]*x[i];
450 
451  return CMath::sqrt(result);
452 }
453 
454 template <>
455 uint16_t SGVector<uint16_t>::twonorm(const uint16_t* x, int32_t len)
456 {
457  float64_t result=0;
458  for (int32_t i=0; i<len; i++)
459  result+=x[i]*x[i];
460 
461  return CMath::sqrt(result);
462 }
463 
464 template <>
465 int32_t SGVector<int32_t>::twonorm(const int32_t* x, int32_t len)
466 {
467  float64_t result=0;
468  for (int32_t i=0; i<len; i++)
469  result+=x[i]*x[i];
470 
471  return CMath::sqrt(result);
472 }
473 
474 template <>
475 uint32_t SGVector<uint32_t>::twonorm(const uint32_t* x, int32_t len)
476 {
477  float64_t result=0;
478  for (int32_t i=0; i<len; i++)
479  result+=x[i]*x[i];
480 
481  return CMath::sqrt(result);
482 }
483 
484 template <>
485 int64_t SGVector<int64_t>::twonorm(const int64_t* x, int32_t len)
486 {
487  float64_t result=0;
488  for (int32_t i=0; i<len; i++)
489  result+=x[i]*x[i];
490 
491  return CMath::sqrt(result);
492 }
493 
494 template <>
495 uint64_t SGVector<uint64_t>::twonorm(const uint64_t* x, int32_t len)
496 {
497  float64_t result=0;
498  for (int32_t i=0; i<len; i++)
499  result+=x[i]*x[i];
500 
501  return CMath::sqrt(result);
502 }
503 
504 template <>
506 {
507  float64_t result=0;
508  for (int32_t i=0; i<len; i++)
509  result+=x[i]*x[i];
510 
511  return CMath::sqrt(result);
512 }
513 
514 template <>
516 {
517  float64_t norm = 0.0;
518 #ifdef HAVE_LAPACK
519  norm = cblas_dnrm2(n, v, 1);
520 #else
521  norm = CMath::sqrt(SGVector::dot(v, v, n));
522 #endif
523  return norm;
524 }
525 
526 template <>
528 {
529  float64_t result=0;
530  for (int32_t i=0; i<len; i++)
531  result+=x[i]*x[i];
532 
533  return CMath::sqrt(result);
534 }
535 
536 
537 template <class T>
538 float64_t SGVector<T>::onenorm(T* x, int32_t len)
539 {
540  float64_t result=0;
541  for (int32_t i=0;i<len; ++i)
542  result+=CMath::abs(x[i]);
543 
544  return result;
545 }
546 
548 template <class T>
549 T SGVector<T>::qsq(T* x, int32_t len, float64_t q)
550 {
551  float64_t result=0;
552  for (int32_t i=0; i<len; i++)
553  result+=CMath::pow(fabs(x[i]), q);
554 
555  return result;
556 }
557 
559 template <class T>
560 T SGVector<T>::qnorm(T* x, int32_t len, float64_t q)
561 {
562  ASSERT(q!=0);
563  return CMath::pow((float64_t) qsq(x, len, q), 1.0/q);
564 }
565 
567 template <class T>
568  T SGVector<T>::min(T* vec, int32_t len)
569  {
570  ASSERT(len>0);
571  T minv=vec[0];
572 
573  for (int32_t i=1; i<len; i++)
574  minv=CMath::min(vec[i], minv);
575 
576  return minv;
577  }
578 
580 template <class T>
581  T SGVector<T>::max(T* vec, int32_t len)
582  {
583  ASSERT(len>0);
584  T maxv=vec[0];
585 
586  for (int32_t i=1; i<len; i++)
587  maxv=CMath::max(vec[i], maxv);
588 
589  return maxv;
590  }
591 
593 template <class T>
594 T SGVector<T>::sum_abs(T* vec, int32_t len)
595 {
596  T result=0;
597  for (int32_t i=0; i<len; i++)
598  result+=CMath::abs(vec[i]);
599 
600  return result;
601 }
602 
604 template <class T>
605 bool SGVector<T>::fequal(T x, T y, float64_t precision)
606 {
607  return CMath::abs(x-y)<precision;
608 }
609 
610 template <class T>
611 int32_t SGVector<T>::unique(T* output, int32_t size)
612 {
613  CMath::qsort(output, size);
614  int32_t j=0;
615 
616  for (int32_t i=0; i<size; i++)
617  {
618  if (i==0 || output[i]!=output[i-1])
619  output[j++]=output[i];
620  }
621  return j;
622 }
623 
624 template <class T>
626 {
627  SGVector<index_t> idx(vlen);
628  index_t k=0;
629 
630  for (index_t i=0; i < vlen; ++i)
631  if (vector[i] == elem)
632  idx[k++] = i;
633  idx.vlen = k;
634  return idx;
635 }
636 
637 template<class T> void SGVector<T>::scale(T alpha)
638 {
639  scale_vector(alpha, vector, vlen);
640 }
641 
642 template<class T> float64_t SGVector<T>::mean() const
643 {
644  float64_t cum = 0;
645 
646  for ( index_t i = 0 ; i < vlen ; ++i )
647  cum += vector[i];
648 
649  return cum/vlen;
650 }
651 
652 template class SGVector<bool>;
653 template class SGVector<char>;
654 template class SGVector<int8_t>;
655 template class SGVector<uint8_t>;
656 template class SGVector<int16_t>;
657 template class SGVector<uint16_t>;
658 template class SGVector<int32_t>;
659 template class SGVector<uint32_t>;
660 template class SGVector<int64_t>;
661 template class SGVector<uint64_t>;
662 template class SGVector<float32_t>;
663 template class SGVector<float64_t>;
664 template class SGVector<floatmax_t>;
665 }

SHOGUN Machine Learning Toolbox - Documentation