SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SGMatrix.cpp
Go to the documentation of this file.
1 #include <shogun/lib/config.h>
2 #include <shogun/io/SGIO.h>
3 #include <shogun/lib/SGMatrix.h>
4 #include <shogun/lib/SGVector.h>
8 
9 namespace shogun {
10 
11 template <class T>
13  T*& matrix, int32_t& num_feat, int32_t& num_vec)
14 {
15  /* this should be done in-place! Heiko */
16  T* transposed=SG_MALLOC(T, num_vec*num_feat);
17  for (int32_t i=0; i<num_vec; i++)
18  {
19  for (int32_t j=0; j<num_feat; j++)
20  transposed[i+j*num_vec]=matrix[i*num_feat+j];
21  }
22 
23  SG_FREE(matrix);
24  matrix=transposed;
25 
26  CMath::swap(num_feat, num_vec);
27 }
28 
29 template <class T>
30 void SGMatrix<T>::center_matrix(T* matrix, int32_t m, int32_t n)
31 {
32  float64_t num_data=n;
33 
34  T* colsums=get_column_sum(matrix, m,n);
35  T* rowsums=get_row_sum(matrix, m,n);
36 
37  for (int32_t i=0; i<m; i++)
38  colsums[i]/=num_data;
39  for (int32_t j=0; j<n; j++)
40  rowsums[j]/=num_data;
41 
42  T s=SGVector<T>::sum(rowsums, n)/num_data;
43 
44  for (int32_t i=0; i<n; i++)
45  {
46  for (int32_t j=0; j<m; j++)
47  matrix[int64_t(i)*m+j]+=s-colsums[j]-rowsums[i];
48  }
49 
50  SG_FREE(rowsums);
51  SG_FREE(colsums);
52 }
53 
54 template <class T>
56 {
57  /* compute "row" sums (which I would call column sums), i.e. sum of all
58  * elements in a fixed column */
59  T* means=get_row_sum(matrix, num_rows, num_cols);
60 
61  /* substract column mean from every corresponding entry */
62  for (index_t i=0; i<num_cols; ++i)
63  {
64  means[i]/=num_rows;
65  for (index_t j=0; j<num_rows; ++j)
66  matrix[i*num_rows+j]-=means[i];
67  }
68 
69  SG_FREE(means);
70 }
71 
72 template<class T> void SGMatrix<T>::display_matrix(const char* name) const
73 {
74  display_matrix(matrix, num_rows, num_cols, name);
75 }
76 
77 template <class T>
79  const SGMatrix<T> matrix, const char* name,
80  const char* prefix)
81 {
82  matrix.display_matrix();
83 }
84 
85 template <>
87  const bool* matrix, int32_t rows, int32_t cols, const char* name,
88  const char* prefix)
89 {
90  ASSERT(rows>=0 && cols>=0);
91  SG_SPRINT("%s%s=[\n", prefix, name);
92  for (int32_t i=0; i<rows; i++)
93  {
94  SG_SPRINT("%s[", prefix);
95  for (int32_t j=0; j<cols; j++)
96  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i] ? 1 : 0,
97  j==cols-1? "" : ",");
98  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
99  }
100  SG_SPRINT("%s]\n", prefix);
101 }
102 
103 template <>
105  const char* matrix, int32_t rows, int32_t cols, const char* name,
106  const char* prefix)
107 {
108  ASSERT(rows>=0 && cols>=0);
109  SG_SPRINT("%s%s=[\n", prefix, name);
110  for (int32_t i=0; i<rows; i++)
111  {
112  SG_SPRINT("%s[", prefix);
113  for (int32_t j=0; j<cols; j++)
114  SG_SPRINT("%s\t%c%s", prefix, matrix[j*rows+i],
115  j==cols-1? "" : ",");
116  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
117  }
118  SG_SPRINT("%s]\n", prefix);
119 }
120 
121 template <>
123  const int8_t* matrix, int32_t rows, int32_t cols, const char* name,
124  const char* prefix)
125 {
126  ASSERT(rows>=0 && cols>=0);
127  SG_SPRINT("%s%s=[\n", prefix, name);
128  for (int32_t i=0; i<rows; i++)
129  {
130  SG_SPRINT("%s[", prefix);
131  for (int32_t j=0; j<cols; j++)
132  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
133  j==cols-1? "" : ",");
134  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
135  }
136  SG_SPRINT("%s]\n", prefix);
137 }
138 
139 template <>
141  const uint8_t* matrix, int32_t rows, int32_t cols, const char* name,
142  const char* prefix)
143 {
144  ASSERT(rows>=0 && cols>=0);
145  SG_SPRINT("%s%s=[\n", prefix, name);
146  for (int32_t i=0; i<rows; i++)
147  {
148  SG_SPRINT("%s[", prefix);
149  for (int32_t j=0; j<cols; j++)
150  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
151  j==cols-1? "" : ",");
152  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
153  }
154  SG_SPRINT("%s]\n", prefix);
155 }
156 
157 template <>
159  const int16_t* matrix, int32_t rows, int32_t cols, const char* name,
160  const char* prefix)
161 {
162  ASSERT(rows>=0 && cols>=0);
163  SG_SPRINT("%s%s=[\n", prefix, name);
164  for (int32_t i=0; i<rows; i++)
165  {
166  SG_SPRINT("%s[", prefix);
167  for (int32_t j=0; j<cols; j++)
168  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
169  j==cols-1? "" : ",");
170  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
171  }
172  SG_SPRINT("%s]\n", prefix);
173 }
174 
175 template <>
177  const uint16_t* matrix, int32_t rows, int32_t cols, const char* name,
178  const char* prefix)
179 {
180  ASSERT(rows>=0 && cols>=0);
181  SG_SPRINT("%s%s=[\n", prefix, name);
182  for (int32_t i=0; i<rows; i++)
183  {
184  SG_SPRINT("%s[", prefix);
185  for (int32_t j=0; j<cols; j++)
186  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
187  j==cols-1? "" : ",");
188  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
189  }
190  SG_SPRINT("%s]\n", prefix);
191 }
192 
193 
194 template <>
196  const int32_t* matrix, int32_t rows, int32_t cols, const char* name,
197  const char* prefix)
198 {
199  ASSERT(rows>=0 && cols>=0);
200  SG_SPRINT("%s%s=[\n", prefix, name);
201  for (int32_t i=0; i<rows; i++)
202  {
203  SG_SPRINT("%s[", prefix);
204  for (int32_t j=0; j<cols; j++)
205  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
206  j==cols-1? "" : ",");
207  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
208  }
209  SG_SPRINT("%s]\n", prefix);
210 }
211 
212 template <>
214  const uint32_t* matrix, int32_t rows, int32_t cols, const char* name,
215  const char* prefix)
216 {
217  ASSERT(rows>=0 && cols>=0);
218  SG_SPRINT("%s%s=[\n", prefix, name);
219  for (int32_t i=0; i<rows; i++)
220  {
221  SG_SPRINT("%s[", prefix);
222  for (int32_t j=0; j<cols; j++)
223  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
224  j==cols-1? "" : ",");
225  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
226  }
227  SG_SPRINT("%s]\n", prefix);
228 }
229 template <>
231  const int64_t* matrix, int32_t rows, int32_t cols, const char* name,
232  const char* prefix)
233 {
234  ASSERT(rows>=0 && cols>=0);
235  SG_SPRINT("%s%s=[\n", prefix, name);
236  for (int32_t i=0; i<rows; i++)
237  {
238  SG_SPRINT("%s[", prefix);
239  for (int32_t j=0; j<cols; j++)
240  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
241  j==cols-1? "" : ",");
242  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
243  }
244  SG_SPRINT("%s]\n", prefix);
245 }
246 
247 template <>
249  const uint64_t* matrix, int32_t rows, int32_t cols, const char* name,
250  const char* prefix)
251 {
252  ASSERT(rows>=0 && cols>=0);
253  SG_SPRINT("%s%s=[\n", prefix, name);
254  for (int32_t i=0; i<rows; i++)
255  {
256  SG_SPRINT("%s[", prefix);
257  for (int32_t j=0; j<cols; j++)
258  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
259  j==cols-1? "" : ",");
260  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
261  }
262  SG_SPRINT("%s]\n", prefix);
263 }
264 
265 template <>
267  const float32_t* matrix, int32_t rows, int32_t cols, const char* name,
268  const char* prefix)
269 {
270  ASSERT(rows>=0 && cols>=0);
271  SG_SPRINT("%s%s=[\n", prefix, name);
272  for (int32_t i=0; i<rows; i++)
273  {
274  SG_SPRINT("%s[", prefix);
275  for (int32_t j=0; j<cols; j++)
276  SG_SPRINT("%s\t%.18g%s", prefix, (float) matrix[j*rows+i],
277  j==cols-1? "" : ",");
278  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
279  }
280  SG_SPRINT("%s]\n", prefix);
281 }
282 
283 template <>
285  const float64_t* matrix, int32_t rows, int32_t cols, const char* name,
286  const char* prefix)
287 {
288  ASSERT(rows>=0 && cols>=0);
289  SG_SPRINT("%s%s=[\n", prefix, name);
290  for (int32_t i=0; i<rows; i++)
291  {
292  SG_SPRINT("%s[", prefix);
293  for (int32_t j=0; j<cols; j++)
294  SG_SPRINT("%s\t%.18g%s", prefix, (double) matrix[j*rows+i],
295  j==cols-1? "" : ",");
296  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
297  }
298  SG_SPRINT("%s]\n", prefix);
299 }
300 
301 template <>
303  const floatmax_t* matrix, int32_t rows, int32_t cols, const char* name,
304  const char* prefix)
305 {
306  ASSERT(rows>=0 && cols>=0);
307  SG_SPRINT("%s%s=[\n", prefix, name);
308  for (int32_t i=0; i<rows; i++)
309  {
310  SG_SPRINT("%s[", prefix);
311  for (int32_t j=0; j<cols; j++)
312  SG_SPRINT("%s\t%.18g%s", prefix, (double) matrix[j*rows+i],
313  j==cols-1? "" : ",");
314  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",");
315  }
316  SG_SPRINT("%s]\n", prefix);
317 }
318 
319 template <>
321 {
323  return SGMatrix<char>();
324 }
325 
326 template <>
328 {
329  SGMatrix<int8_t> I(size, size);
330  for (index_t i=0; i<size; ++i)
331  {
332  for (index_t j=0; j<size; ++j)
333  I(i,j)=i==j ? scale : 0.0;
334  }
335 
336  return I;
337 }
338 
339 template <>
341 {
342  SGMatrix<uint8_t> I(size, size);
343  for (index_t i=0; i<size; ++i)
344  {
345  for (index_t j=0; j<size; ++j)
346  I(i,j)=i==j ? scale : 0.0;
347  }
348 
349  return I;
350 }
351 
352 template <>
354 {
355  SGMatrix<bool> I(size, size);
356  for (index_t i=0; i<size; ++i)
357  {
358  for (index_t j=0; j<size; ++j)
359  I(i,j)=i==j ? scale : (!scale);
360  }
361 
362  return I;
363 }
364 
365 template <>
367 {
368  SGMatrix<int16_t> I(size, size);
369  for (index_t i=0; i<size; ++i)
370  {
371  for (index_t j=0; j<size; ++j)
372  I(i,j)=i==j ? scale : 0.0;
373  }
374 
375  return I;
376 }
377 
378 template <>
380 {
381  SGMatrix<uint16_t> I(size, size);
382  for (index_t i=0; i<size; ++i)
383  {
384  for (index_t j=0; j<size; ++j)
385  I(i,j)=i==j ? scale : 0.0;
386  }
387 
388  return I;
389 }
390 
391 template <>
393 {
394  SGMatrix<int32_t> I(size, size);
395  for (index_t i=0; i<size; ++i)
396  {
397  for (index_t j=0; j<size; ++j)
398  I(i,j)=i==j ? scale : 0.0;
399  }
400 
401  return I;
402 }
403 
404 template <>
406 {
407  SGMatrix<uint32_t> I(size, size);
408  for (index_t i=0; i<size; ++i)
409  {
410  for (index_t j=0; j<size; ++j)
411  I(i,j)=i==j ? scale : 0.0;
412  }
413 
414  return I;
415 }
416 
417 template <>
419 {
420  SGMatrix<int64_t> I(size, size);
421  for (index_t i=0; i<size; ++i)
422  {
423  for (index_t j=0; j<size; ++j)
424  I(i,j)=i==j ? scale : 0.0;
425  }
426 
427  return I;
428 }
429 
430 template <>
432 {
433  SGMatrix<uint64_t> I(size, size);
434  for (index_t i=0; i<size; ++i)
435  {
436  for (index_t j=0; j<size; ++j)
437  I(i,j)=i==j ? scale : 0.0;
438  }
439 
440  return I;
441 }
442 
443 template <>
445 {
446  SGMatrix<float32_t> I(size, size);
447  for (index_t i=0; i<size; ++i)
448  {
449  for (index_t j=0; j<size; ++j)
450  I(i,j)=i==j ? scale : 0.0;
451  }
452 
453  return I;
454 }
455 
456 template <>
458 {
459  SGMatrix<float64_t> I(size, size);
460  for (index_t i=0; i<size; ++i)
461  {
462  for (index_t j=0; j<size; ++j)
463  I(i,j)=i==j ? scale : 0.0;
464  }
465 
466  return I;
467 }
468 
469 template <>
471 {
472  SGMatrix<floatmax_t> I(size, size);
473  for (index_t i=0; i<size; ++i)
474  {
475  for (index_t j=0; j<size; ++j)
476  I(i,j)=i==j ? scale : 0.0;
477  }
478 
479  return I;
480 }
481 
482 
483 template <class T>
485 {
487 
488  float64_t subtract=1.0/size;
489  for (index_t i=0; i<size; ++i)
490  {
491  for (index_t j=0; j<0; ++j)
492  H(i,j)-=subtract;
493  }
494 
495  return H;
496 }
497 
498 //Howto construct the pseudo inverse (from "The Matrix Cookbook")
499 //
500 //Assume A does not have full rank, i.e. A is n \times m and rank(A) = r < min(n;m).
501 //
502 //The matrix A+ known as the pseudo inverse is unique and does always exist.
503 //
504 //The pseudo inverse A+ can be constructed from the singular value
505 //decomposition A = UDV^T , by A^+ = V(D+)U^T.
506 
507 #ifdef HAVE_LAPACK
508 template <class T>
510  float64_t* matrix, int32_t rows, int32_t cols, float64_t* target)
511 {
512  if (!target)
513  target=SG_MALLOC(float64_t, rows*cols);
514 
515  char jobu='A';
516  char jobvt='A';
517  int m=rows; /* for calling external lib */
518  int n=cols; /* for calling external lib */
519  int lda=m; /* for calling external lib */
520  int ldu=m; /* for calling external lib */
521  int ldvt=n; /* for calling external lib */
522  int info=-1; /* for calling external lib */
523  int32_t lsize=CMath::min((int32_t) m, (int32_t) n);
524  double* s=SG_MALLOC(double, lsize);
525  double* u=SG_MALLOC(double, m*m);
526  double* vt=SG_MALLOC(double, n*n);
527 
528  wrap_dgesvd(jobu, jobvt, m, n, matrix, lda, s, u, ldu, vt, ldvt, &info);
529  ASSERT(info==0);
530 
531  for (int32_t i=0; i<n; i++)
532  {
533  for (int32_t j=0; j<lsize; j++)
534  vt[i*n+j]=vt[i*n+j]/s[j];
535  }
536 
537  cblas_dgemm(CblasColMajor, CblasTrans, CblasTrans, m, n, m, 1.0, vt, ldvt, u, ldu, 0, target, m);
538 
539  SG_FREE(u);
540  SG_FREE(vt);
541  SG_FREE(s);
542 
543  return target;
544 }
545 
547 template <class T>
549 {
550  ASSERT(matrix.num_cols==matrix.num_rows);
551  int32_t* ipiv = SG_MALLOC(int32_t, matrix.num_cols);
552  clapack_dgetrf(CblasColMajor,matrix.num_cols,matrix.num_cols,matrix.matrix,matrix.num_cols,ipiv);
553  clapack_dgetri(CblasColMajor,matrix.num_cols,matrix.matrix,matrix.num_cols,ipiv);
554  SG_FREE(ipiv);
555 }
556 
557 template <class T>
559 {
560  if (matrix.num_rows!=matrix.num_rows)
561  {
562  SG_SERROR("SGMatrix::compute_eigenvectors(SGMatrix<float64_t>): matrix"
563  " rows and columns are not equal!\n");
564  }
565 
566  /* use reference counting for SGVector */
567  SGVector<float64_t> result(NULL, 0, true);
568  result.vlen=matrix.num_rows;
569  result.vector=compute_eigenvectors(matrix.matrix, matrix.num_rows,
570  matrix.num_rows);
571  return result;
572 }
573 
574 template <class T>
575 double* SGMatrix<T>::compute_eigenvectors(double* matrix, int n, int m)
576 {
577  ASSERT(n == m);
578 
579  char V='V';
580  char U='U';
581  int info;
582  int ord=n;
583  int lda=n;
584  double* eigenvalues=SG_CALLOC(float64_t, n+1);
585 
586  // lapack sym matrix eigenvalues+vectors
587  wrap_dsyev(V, U, ord, matrix, lda,
588  eigenvalues, &info);
589 
590  if (info!=0)
591  SG_SERROR("DSYEV failed with code %d\n", info);
592 
593  return eigenvalues;
594 }
595 
596 template <class T>
597 void SGMatrix<T>::compute_few_eigenvectors(double* matrix_, double*& eigenvalues, double*& eigenvectors,
598  int n, int il, int iu)
599 {
600  eigenvalues = SG_MALLOC(double, n);
601  eigenvectors = SG_MALLOC(double, (iu-il+1)*n);
602  int status = 0;
603  wrap_dsyevr('V','U',n,matrix_,n,il,iu,eigenvalues,eigenvectors,&status);
604  ASSERT(status==0);
605 }
606 
607 #endif //HAVE_LAPACK
608 
609 template <class T>
612  bool transpose_A, bool transpose_B, float64_t scale)
613 {
614  /* these variables store size of transposed matrices*/
615  index_t cols_A=transpose_A ? A.num_rows : A.num_cols;
616  index_t rows_A=transpose_A ? A.num_cols : A.num_rows;
617  index_t rows_B=transpose_B ? B.num_cols : B.num_rows;
618  index_t cols_B=transpose_B ? B.num_rows : B.num_cols;
619 
620  /* do a dimension check */
621  if (cols_A!=rows_B)
622  {
623  SG_SERROR("SGMatrix::matrix_multiply(): Dimension mismatch: "
624  "A(%dx%d)*B(%dx%D)\n", rows_A, cols_A, rows_B, cols_B);
625  }
626 
627  /* allocate result matrix */
628  SGMatrix<float64_t> C(rows_A, cols_B);
629  C.zero();
630 #ifdef HAVE_LAPACK
631  /* multiply */
632  cblas_dgemm(CblasColMajor,
633  transpose_A ? CblasTrans : CblasNoTrans,
634  transpose_B ? CblasTrans : CblasNoTrans,
635  rows_A, cols_B, cols_A, scale,
636  A.matrix, A.num_rows, B.matrix, B.num_rows,
637  0.0, C.matrix, C.num_rows);
638 #else
639  for (int32_t i=0; i<rows_A; i++)
640  {
641  for (int32_t j=0; j<cols_B; j++)
642  {
643  for (int32_t k=0; k<cols_A; k++)
644  C(i,j) += A(i,k)*B(k,j);
645  }
646  }
647 #endif //HAVE_LAPACK
648 
649  return C;
650 }
651 
652 template<class T>
654  index_t num_cols, SGMatrix<T> pre_allocated)
655 {
656  SGMatrix<T> result;
657 
658  /* evtl use pre-allocated space */
659  if (pre_allocated.matrix)
660  {
661  result=pre_allocated;
662 
663  /* check dimension consistency */
664  if (pre_allocated.num_rows!=num_rows ||
665  pre_allocated.num_cols!=num_cols)
666  {
667  SG_SERROR("SGMatrix<T>::get_allocated_matrix(). Provided target"
668  "matrix dimensions (%dx%d) do not match passed data "
669  "dimensions (%dx%d)!\n", pre_allocated.num_rows,
670  pre_allocated.num_cols, num_rows, num_cols);
671  }
672  }
673  else
674  {
675  /* otherwise, allocate space */
676  result=SGMatrix<T>(num_rows, num_cols);
677  }
678 
679  return result;
680 }
681 
682 template class SGMatrix<bool>;
683 template class SGMatrix<char>;
684 template class SGMatrix<int8_t>;
685 template class SGMatrix<uint8_t>;
686 template class SGMatrix<int16_t>;
687 template class SGMatrix<uint16_t>;
688 template class SGMatrix<int32_t>;
689 template class SGMatrix<uint32_t>;
690 template class SGMatrix<int64_t>;
691 template class SGMatrix<uint64_t>;
692 template class SGMatrix<float32_t>;
693 template class SGMatrix<float64_t>;
694 template class SGMatrix<floatmax_t>;
695 }

SHOGUN Machine Learning Toolbox - Documentation