SHOGUN  v3.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 /*
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) 2011-2013 Heiko Strathmann
8  * Written (W) 2012 Fernando Jose Iglesias Garcia
9  * Written (W) 2010,2012 Soeren Sonnenburg
10  * Copyright (C) 2010 Berlin Institute of Technology
11  * Copyright (C) 2012 Soeren Sonnenburg
12  */
13 
14 #include <shogun/lib/config.h>
15 #include <shogun/io/SGIO.h>
16 #include <shogun/io/File.h>
17 #include <shogun/lib/SGMatrix.h>
18 #include <shogun/lib/SGVector.h>
22 
23 namespace shogun {
24 
25 template <class T>
27 {
28  init_data();
29 }
30 
31 template <class T>
32 SGMatrix<T>::SGMatrix(bool ref_counting) : SGReferencedData(ref_counting)
33 {
34  init_data();
35 }
36 
37 template <class T>
38 SGMatrix<T>::SGMatrix(T* m, index_t nrows, index_t ncols, bool ref_counting)
39  : SGReferencedData(ref_counting), matrix(m),
40  num_rows(nrows), num_cols(ncols) { }
41 
42 template <class T>
43 SGMatrix<T>::SGMatrix(index_t nrows, index_t ncols, bool ref_counting)
44  : SGReferencedData(ref_counting), num_rows(nrows), num_cols(ncols)
45 {
46  matrix=SG_MALLOC(T, ((int64_t) nrows)*ncols);
47 }
48 
49 template <class T>
51 {
52  copy_data(orig);
53 }
54 
55 template <class T>
57 {
58  unref();
59 }
60 
61 template <class T>
63 {
64  if (num_rows!=other.num_rows || num_cols!=other.num_cols)
65  return false;
66 
67  if (matrix!=other.matrix)
68  return false;
69 
70  return true;
71 }
72 
73 template <class T>
75 {
76  if (num_rows!=other.num_rows || num_cols!=other.num_cols)
77  return false;
78 
79  for (index_t i=0; i<num_rows*num_cols; ++i)
80  {
81  if (matrix[i]!=other.matrix[i])
82  return false;
83  }
84 
85  return true;
86 }
87 
88 template <class T>
89 void SGMatrix<T>::set_const(T const_elem)
90 {
91  for (index_t i=0; i<num_rows*num_cols; i++)
92  matrix[i]=const_elem ;
93 }
94 
95 template <class T>
97 {
98  if (matrix && (num_rows*num_cols))
99  set_const(0);
100 }
101 
102 template <>
104 {
105  if (matrix && (num_rows*num_cols))
106  set_const(complex128_t(0.0));
107 }
108 
109 template <class T>
111 {
112  T max=matrix[0];
113  for (index_t i=1; i<num_rows*num_cols; ++i)
114  {
115  if (matrix[i]>max)
116  max=matrix[i];
117  }
118 
119  return max;
120 }
121 
122 template <>
124 {
125  SG_SERROR("SGMatrix::max_single():: Not supported for complex128_t\n");
126  return complex128_t(0.0);
127 }
128 
129 template <class T>
131 {
132  return SGMatrix<T>(clone_matrix(matrix, num_rows, num_cols),
133  num_rows, num_cols);
134 }
135 
136 template <class T>
137 T* SGMatrix<T>::clone_matrix(const T* matrix, int32_t nrows, int32_t ncols)
138 {
139  T* result = SG_MALLOC(T, int64_t(nrows)*ncols);
140  for (int64_t i=0; i<int64_t(nrows)*ncols; i++)
141  result[i]=matrix[i];
142 
143  return result;
144 }
145 
146 template <class T>
148  T*& matrix, int32_t& num_feat, int32_t& num_vec)
149 {
150  /* this should be done in-place! Heiko */
151  T* transposed=SG_MALLOC(T, num_vec*num_feat);
152  for (int32_t i=0; i<num_vec; i++)
153  {
154  for (int32_t j=0; j<num_feat; j++)
155  transposed[i+j*num_vec]=matrix[i*num_feat+j];
156  }
157 
158  SG_FREE(matrix);
159  matrix=transposed;
160 
161  CMath::swap(num_feat, num_vec);
162 }
163 
164 template <class T>
165 void SGMatrix<T>::create_diagonal_matrix(T* matrix, T* v,int32_t size)
166 {
167  for(int32_t i=0;i<size;i++)
168  {
169  for(int32_t j=0;j<size;j++)
170  {
171  if(i==j)
172  matrix[j*size+i]=v[i];
173  else
174  matrix[j*size+i]=0;
175  }
176  }
177 }
178 
179 template <class T>
181  float64_t* mat, int32_t cols, int32_t rows)
182 {
183  float64_t trace=0;
184  for (int32_t i=0; i<rows; i++)
185  trace+=mat[i*cols+i];
186  return trace;
187 }
188 
189 template <class T>
190 T* SGMatrix<T>::get_row_sum(T* matrix, int32_t m, int32_t n)
191 {
192  T* rowsums=SG_CALLOC(T, n);
193 
194  for (int32_t i=0; i<n; i++)
195  {
196  for (int32_t j=0; j<m; j++)
197  rowsums[i]+=matrix[j+int64_t(i)*m];
198  }
199  return rowsums;
200 }
201 
202 template <class T>
203 T* SGMatrix<T>::get_column_sum(T* matrix, int32_t m, int32_t n)
204 {
205  T* colsums=SG_CALLOC(T, m);
206 
207  for (int32_t i=0; i<n; i++)
208  {
209  for (int32_t j=0; j<m; j++)
210  colsums[j]+=matrix[j+int64_t(i)*m];
211  }
212  return colsums;
213 }
214 
215 template <class T>
217 {
218  center_matrix(matrix, num_rows, num_cols);
219 }
220 
221 template <class T>
222 void SGMatrix<T>::center_matrix(T* matrix, int32_t m, int32_t n)
223 {
224  float64_t num_data=n;
225 
226  T* colsums=get_column_sum(matrix, m,n);
227  T* rowsums=get_row_sum(matrix, m,n);
228 
229  for (int32_t i=0; i<m; i++)
230  colsums[i]/=num_data;
231  for (int32_t j=0; j<n; j++)
232  rowsums[j]/=num_data;
233 
234  T s=SGVector<T>::sum(rowsums, n)/num_data;
235 
236  for (int32_t i=0; i<n; i++)
237  {
238  for (int32_t j=0; j<m; j++)
239  matrix[int64_t(i)*m+j]+=s-colsums[j]-rowsums[i];
240  }
241 
242  SG_FREE(rowsums);
243  SG_FREE(colsums);
244 }
245 
246 template <class T>
248 {
249  /* compute "row" sums (which I would call column sums), i.e. sum of all
250  * elements in a fixed column */
251  T* means=get_row_sum(matrix, num_rows, num_cols);
252 
253  /* substract column mean from every corresponding entry */
254  for (index_t i=0; i<num_cols; ++i)
255  {
256  means[i]/=num_rows;
257  for (index_t j=0; j<num_rows; ++j)
258  matrix[i*num_rows+j]-=means[i];
259  }
260 
261  SG_FREE(means);
262 }
263 
264 template<class T> void SGMatrix<T>::display_matrix(const char* name) const
265 {
266  display_matrix(matrix, num_rows, num_cols, name);
267 }
268 
269 template <class T>
271  const SGMatrix<T> matrix, const char* name,
272  const char* prefix)
273 {
274  matrix.display_matrix();
275 }
276 
277 template <>
279  const bool* matrix, int32_t rows, int32_t cols, const char* name,
280  const char* prefix)
281 {
282  ASSERT(rows>=0 && cols>=0)
283  SG_SPRINT("%s%s=[\n", prefix, name)
284  for (int32_t i=0; i<rows; i++)
285  {
286  SG_SPRINT("%s[", prefix)
287  for (int32_t j=0; j<cols; j++)
288  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i] ? 1 : 0,
289  j==cols-1? "" : ",");
290  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
291  }
292  SG_SPRINT("%s]\n", prefix)
293 }
294 
295 template <>
297  const char* matrix, int32_t rows, int32_t cols, const char* name,
298  const char* prefix)
299 {
300  ASSERT(rows>=0 && cols>=0)
301  SG_SPRINT("%s%s=[\n", prefix, name)
302  for (int32_t i=0; i<rows; i++)
303  {
304  SG_SPRINT("%s[", prefix)
305  for (int32_t j=0; j<cols; j++)
306  SG_SPRINT("%s\t%c%s", prefix, matrix[j*rows+i],
307  j==cols-1? "" : ",");
308  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
309  }
310  SG_SPRINT("%s]\n", prefix)
311 }
312 
313 template <>
315  const int8_t* matrix, int32_t rows, int32_t cols, const char* name,
316  const char* prefix)
317 {
318  ASSERT(rows>=0 && cols>=0)
319  SG_SPRINT("%s%s=[\n", prefix, name)
320  for (int32_t i=0; i<rows; i++)
321  {
322  SG_SPRINT("%s[", prefix)
323  for (int32_t j=0; j<cols; j++)
324  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
325  j==cols-1? "" : ",");
326  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
327  }
328  SG_SPRINT("%s]\n", prefix)
329 }
330 
331 template <>
333  const uint8_t* matrix, int32_t rows, int32_t cols, const char* name,
334  const char* prefix)
335 {
336  ASSERT(rows>=0 && cols>=0)
337  SG_SPRINT("%s%s=[\n", prefix, name)
338  for (int32_t i=0; i<rows; i++)
339  {
340  SG_SPRINT("%s[", prefix)
341  for (int32_t j=0; j<cols; j++)
342  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
343  j==cols-1? "" : ",");
344  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
345  }
346  SG_SPRINT("%s]\n", prefix)
347 }
348 
349 template <>
351  const int16_t* matrix, int32_t rows, int32_t cols, const char* name,
352  const char* prefix)
353 {
354  ASSERT(rows>=0 && cols>=0)
355  SG_SPRINT("%s%s=[\n", prefix, name)
356  for (int32_t i=0; i<rows; i++)
357  {
358  SG_SPRINT("%s[", prefix)
359  for (int32_t j=0; j<cols; j++)
360  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
361  j==cols-1? "" : ",");
362  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
363  }
364  SG_SPRINT("%s]\n", prefix)
365 }
366 
367 template <>
369  const uint16_t* matrix, int32_t rows, int32_t cols, const char* name,
370  const char* prefix)
371 {
372  ASSERT(rows>=0 && cols>=0)
373  SG_SPRINT("%s%s=[\n", prefix, name)
374  for (int32_t i=0; i<rows; i++)
375  {
376  SG_SPRINT("%s[", prefix)
377  for (int32_t j=0; j<cols; j++)
378  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
379  j==cols-1? "" : ",");
380  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
381  }
382  SG_SPRINT("%s]\n", prefix)
383 }
384 
385 
386 template <>
388  const int32_t* matrix, int32_t rows, int32_t cols, const char* name,
389  const char* prefix)
390 {
391  ASSERT(rows>=0 && cols>=0)
392  SG_SPRINT("%s%s=[\n", prefix, name)
393  for (int32_t i=0; i<rows; i++)
394  {
395  SG_SPRINT("%s[", prefix)
396  for (int32_t j=0; j<cols; j++)
397  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
398  j==cols-1? "" : ",");
399  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
400  }
401  SG_SPRINT("%s]\n", prefix)
402 }
403 
404 template <>
406  const uint32_t* matrix, int32_t rows, int32_t cols, const char* name,
407  const char* prefix)
408 {
409  ASSERT(rows>=0 && cols>=0)
410  SG_SPRINT("%s%s=[\n", prefix, name)
411  for (int32_t i=0; i<rows; i++)
412  {
413  SG_SPRINT("%s[", prefix)
414  for (int32_t j=0; j<cols; j++)
415  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
416  j==cols-1? "" : ",");
417  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
418  }
419  SG_SPRINT("%s]\n", prefix)
420 }
421 template <>
423  const int64_t* matrix, int32_t rows, int32_t cols, const char* name,
424  const char* prefix)
425 {
426  ASSERT(rows>=0 && cols>=0)
427  SG_SPRINT("%s%s=[\n", prefix, name)
428  for (int32_t i=0; i<rows; i++)
429  {
430  SG_SPRINT("%s[", prefix)
431  for (int32_t j=0; j<cols; j++)
432  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
433  j==cols-1? "" : ",");
434  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
435  }
436  SG_SPRINT("%s]\n", prefix)
437 }
438 
439 template <>
441  const uint64_t* matrix, int32_t rows, int32_t cols, const char* name,
442  const char* prefix)
443 {
444  ASSERT(rows>=0 && cols>=0)
445  SG_SPRINT("%s%s=[\n", prefix, name)
446  for (int32_t i=0; i<rows; i++)
447  {
448  SG_SPRINT("%s[", prefix)
449  for (int32_t j=0; j<cols; j++)
450  SG_SPRINT("%s\t%d%s", prefix, matrix[j*rows+i],
451  j==cols-1? "" : ",");
452  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
453  }
454  SG_SPRINT("%s]\n", prefix)
455 }
456 
457 template <>
459  const float32_t* matrix, int32_t rows, int32_t cols, const char* name,
460  const char* prefix)
461 {
462  ASSERT(rows>=0 && cols>=0)
463  SG_SPRINT("%s%s=[\n", prefix, name)
464  for (int32_t i=0; i<rows; i++)
465  {
466  SG_SPRINT("%s[", prefix)
467  for (int32_t j=0; j<cols; j++)
468  SG_SPRINT("%s\t%.18g%s", prefix, (float) matrix[j*rows+i],
469  j==cols-1? "" : ",");
470  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
471  }
472  SG_SPRINT("%s]\n", prefix)
473 }
474 
475 template <>
477  const float64_t* matrix, int32_t rows, int32_t cols, const char* name,
478  const char* prefix)
479 {
480  ASSERT(rows>=0 && cols>=0)
481  SG_SPRINT("%s%s=[\n", prefix, name)
482  for (int32_t i=0; i<rows; i++)
483  {
484  SG_SPRINT("%s[", prefix)
485  for (int32_t j=0; j<cols; j++)
486  SG_SPRINT("%s\t%.18g%s", prefix, (double) matrix[j*rows+i],
487  j==cols-1? "" : ",");
488  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
489  }
490  SG_SPRINT("%s]\n", prefix)
491 }
492 
493 template <>
495  const floatmax_t* matrix, int32_t rows, int32_t cols, const char* name,
496  const char* prefix)
497 {
498  ASSERT(rows>=0 && cols>=0)
499  SG_SPRINT("%s%s=[\n", prefix, name)
500  for (int32_t i=0; i<rows; i++)
501  {
502  SG_SPRINT("%s[", prefix)
503  for (int32_t j=0; j<cols; j++)
504  SG_SPRINT("%s\t%.18g%s", prefix, (double) matrix[j*rows+i],
505  j==cols-1? "" : ",");
506  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
507  }
508  SG_SPRINT("%s]\n", prefix)
509 }
510 
511 template <>
513  const complex128_t* matrix, int32_t rows, int32_t cols, const char* name,
514  const char* prefix)
515 {
516  ASSERT(rows>=0 && cols>=0)
517  SG_SPRINT("%s%s=[\n", prefix, name)
518  for (int32_t i=0; i<rows; i++)
519  {
520  SG_SPRINT("%s[", prefix)
521  for (int32_t j=0; j<cols; j++)
522  SG_SPRINT("%s\t(%.18g+i%.18g)%s", prefix, matrix[j*rows+i].real(),
523  matrix[j*rows+i].imag(), j==cols-1? "" : ",");
524  SG_SPRINT("%s]%s\n", prefix, i==rows-1? "" : ",")
525  }
526  SG_SPRINT("%s]\n", prefix)
527 }
528 
529 template <>
531 {
533  return SGMatrix<char>();
534 }
535 
536 template <>
538 {
539  SGMatrix<int8_t> I(size, size);
540  for (index_t i=0; i<size; ++i)
541  {
542  for (index_t j=0; j<size; ++j)
543  I(i,j)=i==j ? scale : 0.0;
544  }
545 
546  return I;
547 }
548 
549 template <>
551 {
552  SGMatrix<uint8_t> I(size, size);
553  for (index_t i=0; i<size; ++i)
554  {
555  for (index_t j=0; j<size; ++j)
556  I(i,j)=i==j ? scale : 0.0;
557  }
558 
559  return I;
560 }
561 
562 template <>
564 {
565  SGMatrix<bool> I(size, size);
566  for (index_t i=0; i<size; ++i)
567  {
568  for (index_t j=0; j<size; ++j)
569  I(i,j)=i==j ? scale : (!scale);
570  }
571 
572  return I;
573 }
574 
575 template <>
577 {
578  SGMatrix<int16_t> I(size, size);
579  for (index_t i=0; i<size; ++i)
580  {
581  for (index_t j=0; j<size; ++j)
582  I(i,j)=i==j ? scale : 0.0;
583  }
584 
585  return I;
586 }
587 
588 template <>
590 {
591  SGMatrix<uint16_t> I(size, size);
592  for (index_t i=0; i<size; ++i)
593  {
594  for (index_t j=0; j<size; ++j)
595  I(i,j)=i==j ? scale : 0.0;
596  }
597 
598  return I;
599 }
600 
601 template <>
603 {
604  SGMatrix<int32_t> I(size, size);
605  for (index_t i=0; i<size; ++i)
606  {
607  for (index_t j=0; j<size; ++j)
608  I(i,j)=i==j ? scale : 0.0;
609  }
610 
611  return I;
612 }
613 
614 template <>
616 {
617  SGMatrix<uint32_t> I(size, size);
618  for (index_t i=0; i<size; ++i)
619  {
620  for (index_t j=0; j<size; ++j)
621  I(i,j)=i==j ? scale : 0.0;
622  }
623 
624  return I;
625 }
626 
627 template <>
629 {
630  SGMatrix<int64_t> I(size, size);
631  for (index_t i=0; i<size; ++i)
632  {
633  for (index_t j=0; j<size; ++j)
634  I(i,j)=i==j ? scale : 0.0;
635  }
636 
637  return I;
638 }
639 
640 template <>
642 {
643  SGMatrix<uint64_t> I(size, size);
644  for (index_t i=0; i<size; ++i)
645  {
646  for (index_t j=0; j<size; ++j)
647  I(i,j)=i==j ? scale : 0.0;
648  }
649 
650  return I;
651 }
652 
653 template <>
655 {
656  SGMatrix<float32_t> I(size, size);
657  for (index_t i=0; i<size; ++i)
658  {
659  for (index_t j=0; j<size; ++j)
660  I(i,j)=i==j ? scale : 0.0;
661  }
662 
663  return I;
664 }
665 
666 template <>
668 {
669  SGMatrix<float64_t> I(size, size);
670  for (index_t i=0; i<size; ++i)
671  {
672  for (index_t j=0; j<size; ++j)
673  I(i,j)=i==j ? scale : 0.0;
674  }
675 
676  return I;
677 }
678 
679 template <>
681 {
682  SGMatrix<floatmax_t> I(size, size);
683  for (index_t i=0; i<size; ++i)
684  {
685  for (index_t j=0; j<size; ++j)
686  I(i,j)=i==j ? scale : 0.0;
687  }
688 
689  return I;
690 }
691 
692 template <>
694 {
695  SGMatrix<complex128_t> I(size, size);
696  for (index_t i=0; i<size; ++i)
697  {
698  for (index_t j=0; j<size; ++j)
699  I(i,j)=i==j ? scale : complex128_t(0.0);
700  }
701 
702  return I;
703 }
704 
705 
706 template <class T>
708 {
710 
711  float64_t subtract=1.0/size;
712  for (index_t i=0; i<size; ++i)
713  {
714  for (index_t j=0; j<0; ++j)
715  H(i,j)-=subtract;
716  }
717 
718  return H;
719 }
720 
721 //Howto construct the pseudo inverse (from "The Matrix Cookbook")
722 //
723 //Assume A does not have full rank, i.e. A is n \times m and rank(A) = r < min(n;m).
724 //
725 //The matrix A+ known as the pseudo inverse is unique and does always exist.
726 //
727 //The pseudo inverse A+ can be constructed from the singular value
728 //decomposition A = UDV^T , by A^+ = V(D+)U^T.
729 
730 #ifdef HAVE_LAPACK
731 template <class T>
733  float64_t* matrix, int32_t rows, int32_t cols, float64_t* target)
734 {
735  if (!target)
736  target=SG_MALLOC(float64_t, rows*cols);
737 
738  char jobu='A';
739  char jobvt='A';
740  int m=rows; /* for calling external lib */
741  int n=cols; /* for calling external lib */
742  int lda=m; /* for calling external lib */
743  int ldu=m; /* for calling external lib */
744  int ldvt=n; /* for calling external lib */
745  int info=-1; /* for calling external lib */
746  int32_t lsize=CMath::min((int32_t) m, (int32_t) n);
747  double* s=SG_MALLOC(double, lsize);
748  double* u=SG_MALLOC(double, m*m);
749  double* vt=SG_MALLOC(double, n*n);
750 
751  wrap_dgesvd(jobu, jobvt, m, n, matrix, lda, s, u, ldu, vt, ldvt, &info);
752  ASSERT(info==0)
753 
754  for (int32_t i=0; i<n; i++)
755  {
756  for (int32_t j=0; j<lsize; j++)
757  vt[i*n+j]=vt[i*n+j]/s[j];
758  }
759 
760  cblas_dgemm(CblasColMajor, CblasTrans, CblasTrans, m, n, m, 1.0, vt, ldvt, u, ldu, 0, target, m);
761 
762  SG_FREE(u);
763  SG_FREE(vt);
764  SG_FREE(s);
765 
766  return target;
767 }
768 
770 template <class T>
772 {
773  ASSERT(matrix.num_cols==matrix.num_rows)
774  int32_t* ipiv = SG_MALLOC(int32_t, matrix.num_cols);
775  clapack_dgetrf(CblasColMajor,matrix.num_cols,matrix.num_cols,matrix.matrix,matrix.num_cols,ipiv);
776  clapack_dgetri(CblasColMajor,matrix.num_cols,matrix.matrix,matrix.num_cols,ipiv);
777  SG_FREE(ipiv);
778 }
779 
780 template <class T>
782 {
783  if (matrix.num_rows!=matrix.num_rows)
784  {
785  SG_SERROR("SGMatrix::compute_eigenvectors(SGMatrix<float64_t>): matrix"
786  " rows and columns are not equal!\n");
787  }
788 
789  /* use reference counting for SGVector */
790  SGVector<float64_t> result(NULL, 0, true);
791  result.vlen=matrix.num_rows;
792  result.vector=compute_eigenvectors(matrix.matrix, matrix.num_rows,
793  matrix.num_rows);
794  return result;
795 }
796 
797 template <class T>
798 double* SGMatrix<T>::compute_eigenvectors(double* matrix, int n, int m)
799 {
800  ASSERT(n == m)
801 
802  char V='V';
803  char U='U';
804  int info;
805  int ord=n;
806  int lda=n;
807  double* eigenvalues=SG_CALLOC(float64_t, n+1);
808 
809  // lapack sym matrix eigenvalues+vectors
810  wrap_dsyev(V, U, ord, matrix, lda,
811  eigenvalues, &info);
812 
813  if (info!=0)
814  SG_SERROR("DSYEV failed with code %d\n", info)
815 
816  return eigenvalues;
817 }
818 
819 template <class T>
820 void SGMatrix<T>::compute_few_eigenvectors(double* matrix_, double*& eigenvalues, double*& eigenvectors,
821  int n, int il, int iu)
822 {
823  eigenvalues = SG_MALLOC(double, n);
824  eigenvectors = SG_MALLOC(double, (iu-il+1)*n);
825  int status = 0;
826  wrap_dsyevr('V','U',n,matrix_,n,il,iu,eigenvalues,eigenvectors,&status);
827  ASSERT(status==0)
828 }
829 
830 #endif //HAVE_LAPACK
831 
832 template <class T>
835  bool transpose_A, bool transpose_B, float64_t scale)
836 {
837  /* these variables store size of transposed matrices*/
838  index_t cols_A=transpose_A ? A.num_rows : A.num_cols;
839  index_t rows_A=transpose_A ? A.num_cols : A.num_rows;
840  index_t rows_B=transpose_B ? B.num_cols : B.num_rows;
841  index_t cols_B=transpose_B ? B.num_rows : B.num_cols;
842 
843  /* do a dimension check */
844  if (cols_A!=rows_B)
845  {
846  SG_SERROR("SGMatrix::matrix_multiply(): Dimension mismatch: "
847  "A(%dx%d)*B(%dx%D)\n", rows_A, cols_A, rows_B, cols_B);
848  }
849 
850  /* allocate result matrix */
851  SGMatrix<float64_t> C(rows_A, cols_B);
852  C.zero();
853 #ifdef HAVE_LAPACK
854  /* multiply */
855  cblas_dgemm(CblasColMajor,
856  transpose_A ? CblasTrans : CblasNoTrans,
857  transpose_B ? CblasTrans : CblasNoTrans,
858  rows_A, cols_B, cols_A, scale,
859  A.matrix, A.num_rows, B.matrix, B.num_rows,
860  0.0, C.matrix, C.num_rows);
861 #else
862  for (int32_t i=0; i<rows_A; i++)
863  {
864  for (int32_t j=0; j<cols_B; j++)
865  {
866  for (int32_t k=0; k<cols_A; k++)
867  C(i,j) += A(i,k)*B(k,j);
868  }
869  }
870 #endif //HAVE_LAPACK
871 
872  return C;
873 }
874 
875 template<class T>
877  index_t num_cols, SGMatrix<T> pre_allocated)
878 {
879  SGMatrix<T> result;
880 
881  /* evtl use pre-allocated space */
882  if (pre_allocated.matrix)
883  {
884  result=pre_allocated;
885 
886  /* check dimension consistency */
887  if (pre_allocated.num_rows!=num_rows ||
888  pre_allocated.num_cols!=num_cols)
889  {
890  SG_SERROR("SGMatrix<T>::get_allocated_matrix(). Provided target"
891  "matrix dimensions (%dx%d) do not match passed data "
892  "dimensions (%dx%d)!\n", pre_allocated.num_rows,
893  pre_allocated.num_cols, num_rows, num_cols);
894  }
895  }
896  else
897  {
898  /* otherwise, allocate space */
899  result=SGMatrix<T>(num_rows, num_cols);
900  }
901 
902  return result;
903 }
904 
905 template<class T>
907 {
908  matrix=((SGMatrix*)(&orig))->matrix;
909  num_rows=((SGMatrix*)(&orig))->num_rows;
910  num_cols=((SGMatrix*)(&orig))->num_cols;
911 }
912 
913 template<class T>
915 {
916  matrix=NULL;
917  num_rows=0;
918  num_cols=0;
919 }
920 
921 template<class T>
923 {
924  SG_FREE(matrix);
925  matrix=NULL;
926  num_rows=0;
927  num_cols=0;
928 }
929 
930 template<class T>
932 {
933  ASSERT(loader)
934  unref();
935 
937  SGMatrix<T> mat;
938  loader->get_matrix(mat.matrix, mat.num_rows, mat.num_cols);
939  copy_data(mat);
940  copy_refcount(mat);
941  ref();
943 }
944 
945 template<>
947 {
948  SG_SERROR("SGMatrix::load():: Not supported for complex128_t\n");
949 }
950 
951 template<class T>
953 {
954  ASSERT(writer)
956  writer->set_matrix(matrix, num_rows, num_cols);
958 }
959 
960 template<>
962 {
963  SG_SERROR("SGMatrix::save():: Not supported for complex128_t\n");
964 }
965 
966 template<class T>
968 {
969  SGVector<T> rowv(num_cols);
970  for (index_t i = 0; i < num_cols; i++)
971  {
972  rowv[i] = matrix[i*num_rows+row];
973  }
974  return rowv;
975 }
976 
977 template<class T>
979 {
980  index_t diag_vlen=CMath::min(num_cols, num_rows);
981  SGVector<T> diag(diag_vlen);
982 
983  for (index_t i=0; i<diag_vlen; i++)
984  {
985  diag[i]=matrix[i*num_rows+i];
986  }
987 
988  return diag;
989 }
990 
991 template class SGMatrix<bool>;
992 template class SGMatrix<char>;
993 template class SGMatrix<int8_t>;
994 template class SGMatrix<uint8_t>;
995 template class SGMatrix<int16_t>;
996 template class SGMatrix<uint16_t>;
997 template class SGMatrix<int32_t>;
998 template class SGMatrix<uint32_t>;
999 template class SGMatrix<int64_t>;
1000 template class SGMatrix<uint64_t>;
1001 template class SGMatrix<float32_t>;
1002 template class SGMatrix<float64_t>;
1003 template class SGMatrix<floatmax_t>;
1004 template class SGMatrix<complex128_t>;
1005 }

SHOGUN Machine Learning Toolbox - Documentation