Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-2.4.4/include/armadillo_bits/op_princomp_meat.hpp @ 0:8b6102e2a9b0
Armadillo Library
author | maxzanoni76 <max.zanoni@eecs.qmul.ac.uk> |
---|---|
date | Wed, 11 Apr 2012 09:27:06 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:8b6102e2a9b0 |
---|---|
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 | |
16 //! \addtogroup op_princomp | |
17 //! @{ | |
18 | |
19 | |
20 | |
21 //! \brief | |
22 //! principal component analysis -- 4 arguments version | |
23 //! computation is done via singular value decomposition | |
24 //! coeff_out -> principal component coefficients | |
25 //! score_out -> projected samples | |
26 //! latent_out -> eigenvalues of principal vectors | |
27 //! tsquared_out -> Hotelling's T^2 statistic | |
28 template<typename eT> | |
29 inline | |
30 bool | |
31 op_princomp::direct_princomp | |
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 { | |
40 arma_extra_debug_sigprint(); | |
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 | |
116 //! \brief | |
117 //! principal component analysis -- 3 arguments version | |
118 //! computation is done via singular value decomposition | |
119 //! coeff_out -> principal component coefficients | |
120 //! score_out -> projected samples | |
121 //! latent_out -> eigenvalues of principal vectors | |
122 template<typename eT> | |
123 inline | |
124 bool | |
125 op_princomp::direct_princomp | |
126 ( | |
127 Mat<eT>& coeff_out, | |
128 Mat<eT>& score_out, | |
129 Col<eT>& latent_out, | |
130 const Mat<eT>& in | |
131 ) | |
132 { | |
133 arma_extra_debug_sigprint(); | |
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 | |
192 //! \brief | |
193 //! principal component analysis -- 2 arguments version | |
194 //! computation is done via singular value decomposition | |
195 //! coeff_out -> principal component coefficients | |
196 //! score_out -> projected samples | |
197 template<typename eT> | |
198 inline | |
199 bool | |
200 op_princomp::direct_princomp | |
201 ( | |
202 Mat<eT>& coeff_out, | |
203 Mat<eT>& score_out, | |
204 const Mat<eT>& in | |
205 ) | |
206 { | |
207 arma_extra_debug_sigprint(); | |
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 | |
257 //! \brief | |
258 //! principal component analysis -- 1 argument version | |
259 //! computation is done via singular value decomposition | |
260 //! coeff_out -> principal component coefficients | |
261 template<typename eT> | |
262 inline | |
263 bool | |
264 op_princomp::direct_princomp | |
265 ( | |
266 Mat<eT>& coeff_out, | |
267 const Mat<eT>& in | |
268 ) | |
269 { | |
270 arma_extra_debug_sigprint(); | |
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 | |
297 //! \brief | |
298 //! principal component analysis -- 4 arguments complex version | |
299 //! computation is done via singular value decomposition | |
300 //! coeff_out -> principal component coefficients | |
301 //! score_out -> projected samples | |
302 //! latent_out -> eigenvalues of principal vectors | |
303 //! tsquared_out -> Hotelling's T^2 statistic | |
304 template<typename T> | |
305 inline | |
306 bool | |
307 op_princomp::direct_princomp | |
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 { | |
316 arma_extra_debug_sigprint(); | |
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 | |
391 //! \brief | |
392 //! principal component analysis -- 3 arguments complex version | |
393 //! computation is done via singular value decomposition | |
394 //! coeff_out -> principal component coefficients | |
395 //! score_out -> projected samples | |
396 //! latent_out -> eigenvalues of principal vectors | |
397 template<typename T> | |
398 inline | |
399 bool | |
400 op_princomp::direct_princomp | |
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 { | |
408 arma_extra_debug_sigprint(); | |
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 | |
469 //! \brief | |
470 //! principal component analysis -- 2 arguments complex version | |
471 //! computation is done via singular value decomposition | |
472 //! coeff_out -> principal component coefficients | |
473 //! score_out -> projected samples | |
474 template<typename T> | |
475 inline | |
476 bool | |
477 op_princomp::direct_princomp | |
478 ( | |
479 Mat< std::complex<T> >& coeff_out, | |
480 Mat< std::complex<T> >& score_out, | |
481 const Mat< std::complex<T> >& in | |
482 ) | |
483 { | |
484 arma_extra_debug_sigprint(); | |
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 | |
534 //! \brief | |
535 //! principal component analysis -- 1 argument complex version | |
536 //! computation is done via singular value decomposition | |
537 //! coeff_out -> principal component coefficients | |
538 template<typename T> | |
539 inline | |
540 bool | |
541 op_princomp::direct_princomp | |
542 ( | |
543 Mat< std::complex<T> >& coeff_out, | |
544 const Mat< std::complex<T> >& in | |
545 ) | |
546 { | |
547 arma_extra_debug_sigprint(); | |
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 | |
579 op_princomp::apply | |
580 ( | |
581 Mat<typename T1::elem_type>& out, | |
582 const Op<T1,op_princomp>& in | |
583 ) | |
584 { | |
585 arma_extra_debug_sigprint(); | |
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 | |
604 //! @} |