op_princomp_meat.hpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2010-2011 Conrad Sanderson
3 // Copyright (C) 2010 Dimitrios Bouzas
4 // Copyright (C) 2011 Stanislav Funiak
5 //
6 // This file is part of the Armadillo C++ library.
7 // It is provided without any warranty of fitness
8 // for any purpose. You can redistribute this file
9 // and/or modify it under the terms of the GNU
10 // Lesser General Public License (LGPL) as published
11 // by the Free Software Foundation, either version 3
12 // of the License or (at your option) any later version.
13 // (see http://www.opensource.org/licenses for more info)
14 
15 
18 
19 
20 
28 template<typename eT>
29 inline
30 bool
32  (
33  Mat<eT>& coeff_out,
34  Mat<eT>& score_out,
35  Col<eT>& latent_out,
36  Col<eT>& tsquared_out,
37  const Mat<eT>& in
38  )
39  {
41 
42  const uword n_rows = in.n_rows;
43  const uword n_cols = in.n_cols;
44 
45  if(n_rows > 1) // more than one sample
46  {
47  // subtract the mean - use score_out as temporary matrix
48  score_out = in - repmat(mean(in), n_rows, 1);
49 
50  // singular value decomposition
51  Mat<eT> U;
52  Col<eT> s;
53 
54  const bool svd_ok = svd(U,s,coeff_out,score_out);
55 
56  if(svd_ok == false)
57  {
58  return false;
59  }
60 
61 
62  //U.reset(); // TODO: do we need this ? U will get automatically deleted anyway
63 
64  // normalize the eigenvalues
65  s /= std::sqrt( double(n_rows - 1) );
66 
67  // project the samples to the principals
68  score_out *= coeff_out;
69 
70  if(n_rows <= n_cols) // number of samples is less than their dimensionality
71  {
72  score_out.cols(n_rows-1,n_cols-1).zeros();
73 
74  //Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
75  Col<eT> s_tmp(n_cols);
76  s_tmp.zeros();
77 
78  s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
79  s = s_tmp;
80 
81  // compute the Hotelling's T-squared
82  s_tmp.rows(0,n_rows-2) = eT(1) / s_tmp.rows(0,n_rows-2);
83 
84  const Mat<eT> S = score_out * diagmat(Col<eT>(s_tmp));
85  tsquared_out = sum(S%S,1);
86  }
87  else
88  {
89  // compute the Hotelling's T-squared
90  const Mat<eT> S = score_out * diagmat(Col<eT>( eT(1) / s));
91  tsquared_out = sum(S%S,1);
92  }
93 
94  // compute the eigenvalues of the principal vectors
95  latent_out = s%s;
96  }
97  else // 0 or 1 samples
98  {
99  coeff_out.eye(n_cols, n_cols);
100 
101  score_out.copy_size(in);
102  score_out.zeros();
103 
104  latent_out.set_size(n_cols);
105  latent_out.zeros();
106 
107  tsquared_out.set_size(n_rows);
108  tsquared_out.zeros();
109  }
110 
111  return true;
112  }
113 
114 
115 
122 template<typename eT>
123 inline
124 bool
126  (
127  Mat<eT>& coeff_out,
128  Mat<eT>& score_out,
129  Col<eT>& latent_out,
130  const Mat<eT>& in
131  )
132  {
134 
135  const uword n_rows = in.n_rows;
136  const uword n_cols = in.n_cols;
137 
138  if(n_rows > 1) // more than one sample
139  {
140  // subtract the mean - use score_out as temporary matrix
141  score_out = in - repmat(mean(in), n_rows, 1);
142 
143  // singular value decomposition
144  Mat<eT> U;
145  Col<eT> s;
146 
147  const bool svd_ok = svd(U,s,coeff_out,score_out);
148 
149  if(svd_ok == false)
150  {
151  return false;
152  }
153 
154 
155  // U.reset();
156 
157  // normalize the eigenvalues
158  s /= std::sqrt( double(n_rows - 1) );
159 
160  // project the samples to the principals
161  score_out *= coeff_out;
162 
163  if(n_rows <= n_cols) // number of samples is less than their dimensionality
164  {
165  score_out.cols(n_rows-1,n_cols-1).zeros();
166 
167  Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
168  s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
169  s = s_tmp;
170  }
171 
172  // compute the eigenvalues of the principal vectors
173  latent_out = s%s;
174 
175  }
176  else // 0 or 1 samples
177  {
178  coeff_out.eye(n_cols, n_cols);
179 
180  score_out.copy_size(in);
181  score_out.zeros();
182 
183  latent_out.set_size(n_cols);
184  latent_out.zeros();
185  }
186 
187  return true;
188  }
189 
190 
191 
197 template<typename eT>
198 inline
199 bool
201  (
202  Mat<eT>& coeff_out,
203  Mat<eT>& score_out,
204  const Mat<eT>& in
205  )
206  {
208 
209  const uword n_rows = in.n_rows;
210  const uword n_cols = in.n_cols;
211 
212  if(n_rows > 1) // more than one sample
213  {
214  // subtract the mean - use score_out as temporary matrix
215  score_out = in - repmat(mean(in), n_rows, 1);
216 
217  // singular value decomposition
218  Mat<eT> U;
219  Col<eT> s;
220 
221  const bool svd_ok = svd(U,s,coeff_out,score_out);
222 
223  if(svd_ok == false)
224  {
225  return false;
226  }
227 
228  // U.reset();
229 
230  // normalize the eigenvalues
231  s /= std::sqrt( double(n_rows - 1) );
232 
233  // project the samples to the principals
234  score_out *= coeff_out;
235 
236  if(n_rows <= n_cols) // number of samples is less than their dimensionality
237  {
238  score_out.cols(n_rows-1,n_cols-1).zeros();
239 
240  Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
241  s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
242  s = s_tmp;
243  }
244  }
245  else // 0 or 1 samples
246  {
247  coeff_out.eye(n_cols, n_cols);
248  score_out.copy_size(in);
249  score_out.zeros();
250  }
251 
252  return true;
253  }
254 
255 
256 
261 template<typename eT>
262 inline
263 bool
265  (
266  Mat<eT>& coeff_out,
267  const Mat<eT>& in
268  )
269  {
271 
272  if(in.n_elem != 0)
273  {
274  // singular value decomposition
275  Mat<eT> U;
276  Col<eT> s;
277 
278  const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
279 
280  const bool svd_ok = svd(U,s,coeff_out, tmp);
281 
282  if(svd_ok == false)
283  {
284  return false;
285  }
286  }
287  else
288  {
289  coeff_out.eye(in.n_cols, in.n_cols);
290  }
291 
292  return true;
293  }
294 
295 
296 
304 template<typename T>
305 inline
306 bool
308  (
309  Mat< std::complex<T> >& coeff_out,
310  Mat< std::complex<T> >& score_out,
311  Col<T>& latent_out,
312  Col< std::complex<T> >& tsquared_out,
313  const Mat< std::complex<T> >& in
314  )
315  {
317 
318  typedef std::complex<T> eT;
319 
320  const uword n_rows = in.n_rows;
321  const uword n_cols = in.n_cols;
322 
323  if(n_rows > 1) // more than one sample
324  {
325  // subtract the mean - use score_out as temporary matrix
326  score_out = in - repmat(mean(in), n_rows, 1);
327 
328  // singular value decomposition
329  Mat<eT> U;
330  Col<T> s;
331 
332  const bool svd_ok = svd(U,s,coeff_out,score_out);
333 
334  if(svd_ok == false)
335  {
336  return false;
337  }
338 
339 
340  //U.reset();
341 
342  // normalize the eigenvalues
343  s /= std::sqrt( double(n_rows - 1) );
344 
345  // project the samples to the principals
346  score_out *= coeff_out;
347 
348  if(n_rows <= n_cols) // number of samples is less than their dimensionality
349  {
350  score_out.cols(n_rows-1,n_cols-1).zeros();
351 
352  Col<T> s_tmp = zeros< Col<T> >(n_cols);
353  s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
354  s = s_tmp;
355 
356  // compute the Hotelling's T-squared
357  s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
358  const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));
359  tsquared_out = sum(S%S,1);
360  }
361  else
362  {
363  // compute the Hotelling's T-squared
364  const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));
365  tsquared_out = sum(S%S,1);
366  }
367 
368  // compute the eigenvalues of the principal vectors
369  latent_out = s%s;
370 
371  }
372  else // 0 or 1 samples
373  {
374  coeff_out.eye(n_cols, n_cols);
375 
376  score_out.copy_size(in);
377  score_out.zeros();
378 
379  latent_out.set_size(n_cols);
380  latent_out.zeros();
381 
382  tsquared_out.set_size(n_rows);
383  tsquared_out.zeros();
384  }
385 
386  return true;
387  }
388 
389 
390 
397 template<typename T>
398 inline
399 bool
401  (
402  Mat< std::complex<T> >& coeff_out,
403  Mat< std::complex<T> >& score_out,
404  Col<T>& latent_out,
405  const Mat< std::complex<T> >& in
406  )
407  {
409 
410  typedef std::complex<T> eT;
411 
412  const uword n_rows = in.n_rows;
413  const uword n_cols = in.n_cols;
414 
415  if(n_rows > 1) // more than one sample
416  {
417  // subtract the mean - use score_out as temporary matrix
418  score_out = in - repmat(mean(in), n_rows, 1);
419 
420  // singular value decomposition
421  Mat<eT> U;
422  Col< T> s;
423 
424  const bool svd_ok = svd(U,s,coeff_out,score_out);
425 
426  if(svd_ok == false)
427  {
428  return false;
429  }
430 
431 
432  // U.reset();
433 
434  // normalize the eigenvalues
435  s /= std::sqrt( double(n_rows - 1) );
436 
437  // project the samples to the principals
438  score_out *= coeff_out;
439 
440  if(n_rows <= n_cols) // number of samples is less than their dimensionality
441  {
442  score_out.cols(n_rows-1,n_cols-1).zeros();
443 
444  Col<T> s_tmp = zeros< Col<T> >(n_cols);
445  s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
446  s = s_tmp;
447  }
448 
449  // compute the eigenvalues of the principal vectors
450  latent_out = s%s;
451 
452  }
453  else // 0 or 1 samples
454  {
455  coeff_out.eye(n_cols, n_cols);
456 
457  score_out.copy_size(in);
458  score_out.zeros();
459 
460  latent_out.set_size(n_cols);
461  latent_out.zeros();
462  }
463 
464  return true;
465  }
466 
467 
468 
474 template<typename T>
475 inline
476 bool
478  (
479  Mat< std::complex<T> >& coeff_out,
480  Mat< std::complex<T> >& score_out,
481  const Mat< std::complex<T> >& in
482  )
483  {
485 
486  typedef std::complex<T> eT;
487 
488  const uword n_rows = in.n_rows;
489  const uword n_cols = in.n_cols;
490 
491  if(n_rows > 1) // more than one sample
492  {
493  // subtract the mean - use score_out as temporary matrix
494  score_out = in - repmat(mean(in), n_rows, 1);
495 
496  // singular value decomposition
497  Mat<eT> U;
498  Col< T> s;
499 
500  const bool svd_ok = svd(U,s,coeff_out,score_out);
501 
502  if(svd_ok == false)
503  {
504  return false;
505  }
506 
507  // U.reset();
508 
509  // normalize the eigenvalues
510  s /= std::sqrt( double(n_rows - 1) );
511 
512  // project the samples to the principals
513  score_out *= coeff_out;
514 
515  if(n_rows <= n_cols) // number of samples is less than their dimensionality
516  {
517  score_out.cols(n_rows-1,n_cols-1).zeros();
518  }
519 
520  }
521  else // 0 or 1 samples
522  {
523  coeff_out.eye(n_cols, n_cols);
524 
525  score_out.copy_size(in);
526  score_out.zeros();
527  }
528 
529  return true;
530  }
531 
532 
533 
538 template<typename T>
539 inline
540 bool
542  (
543  Mat< std::complex<T> >& coeff_out,
544  const Mat< std::complex<T> >& in
545  )
546  {
548 
549  typedef typename std::complex<T> eT;
550 
551  if(in.n_elem != 0)
552  {
553  // singular value decomposition
554  Mat<eT> U;
555  Col< T> s;
556 
557  const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
558 
559  const bool svd_ok = svd(U,s,coeff_out, tmp);
560 
561  if(svd_ok == false)
562  {
563  return false;
564  }
565  }
566  else
567  {
568  coeff_out.eye(in.n_cols, in.n_cols);
569  }
570 
571  return true;
572  }
573 
574 
575 
576 template<typename T1>
577 inline
578 void
580  (
582  const Op<T1,op_princomp>& in
583  )
584  {
586 
587  typedef typename T1::elem_type eT;
588 
589  const unwrap_check<T1> tmp(in.m, out);
590  const Mat<eT>& A = tmp.M;
591 
592  const bool status = op_princomp::direct_princomp(out, A);
593 
594  if(status == false)
595  {
596  out.reset();
597 
598  arma_bad("princomp(): failed to converge");
599  }
600  }
601 
602 
603 
arma_inline const Op< T1, op_sum > sum(const Base< typename T1::elem_type, T1 > &X, const uword dim=0)
Delayed sum of elements of a matrix along a specified dimension (either rows or columns). The result is stored in a dense matrix that has either one column or one row. For dim = 0, find the sum of each column. For dim = 1, find the sum of each row. The default is dim = 0. NOTE: this function works differently than in Matlab/Octave.
Definition: fn_sum.hpp:29
void set_size(const uword in_elem)
change the matrix to have user specified dimensions (data is not preserved)
Definition: Mat_meat.hpp:4211
const Mat & eye()
Definition: Mat_meat.hpp:4518
arma_inline const eOp< T1, eop_sqrt > sqrt(const Base< typename T1::elem_type, T1 > &A)
Definition: fn_elem.hpp:403
static bool direct_princomp(Mat< eT > &coeff_out, const Mat< eT > &in)
principal component analysis – 1 argument version computation is done via singular value decompositi...
const uword n_cols
number of columns in the matrix (read-only)
Definition: Mat_bones.hpp:30
const uword n_elem
number of elements in the matrix (read-only)
Definition: Mat_bones.hpp:31
const uword n_rows
number of rows in the matrix (read-only)
Definition: Mat_bones.hpp:29
arma_inline const Op< T1, op_mean > mean(const Base< typename T1::elem_type, T1 > &X, const uword dim=0)
Definition: fn_mean.hpp:22
arma_aligned const T1 & m
storage of reference to the operand (eg. a matrix)
Definition: Op_bones.hpp:45
u32 uword
Definition: typedef.hpp:85
arma_inline subview_col< eT > rows(const uword in_row1, const uword in_row2)
Definition: Col_meat.hpp:370
Class for column vectors (matrices with only one column)
Definition: Col_bones.hpp:20
void reset()
Definition: Mat_meat.hpp:4553
void copy_size(const Mat< eT2 > &m)
change the matrix (without preserving data) to have the same dimensions as the given matrix ...
Definition: Mat_meat.hpp:4303
#define arma_extra_debug_sigprint
Definition: debug.hpp:1116
void arma_cold arma_bad(const T1 &x, const bool hurl=true)
print a message to get_stream_err2() and/or throw a run-time error exception
Definition: debug.hpp:150
arma_inline const Op< T1, op_diagmat > diagmat(const Base< typename T1::elem_type, T1 > &X)
interpret a matrix or a vector as a diagonal matrix (i.e. off-diagonal entries are zero) ...
Definition: fn_diagmat.hpp:22
bool svd(Col< typename T1::pod_type > &S, const Base< typename T1::elem_type, T1 > &X, const typename arma_blas_type_only< typename T1::elem_type >::result *junk=0)
Definition: fn_svd.hpp:23
Dense matrix class.
arma_inline const Op< T1, op_repmat > repmat(const Base< typename T1::elem_type, T1 > &A, const uword r, const uword c)
delayed &#39;repeat matrix&#39; construction of a matrix
Definition: fn_repmat.hpp:25
const Mat & zeros()
Definition: Mat_meat.hpp:4331
arma_inline subview< eT > cols(const uword in_col1, const uword in_col2)
creation of subview (submatrix comprised of specified column vectors)
Definition: Mat_meat.hpp:2050
static void apply(Mat< typename T1::elem_type > &out, const Op< T1, op_princomp > &in)
const Mat< eT > M
Definition: unwrap.hpp:142


armadillo_matrix
Author(s):
autogenerated on Fri Apr 16 2021 02:31:58