00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00018
00019
00020
00028 template<typename eT>
00029 inline
00030 bool
00031 op_princomp::direct_princomp
00032 (
00033 Mat<eT>& coeff_out,
00034 Mat<eT>& score_out,
00035 Col<eT>& latent_out,
00036 Col<eT>& tsquared_out,
00037 const Mat<eT>& in
00038 )
00039 {
00040 arma_extra_debug_sigprint();
00041
00042 const uword n_rows = in.n_rows;
00043 const uword n_cols = in.n_cols;
00044
00045 if(n_rows > 1)
00046 {
00047
00048 score_out = in - repmat(mean(in), n_rows, 1);
00049
00050
00051 Mat<eT> U;
00052 Col<eT> s;
00053
00054 const bool svd_ok = svd(U,s,coeff_out,score_out);
00055
00056 if(svd_ok == false)
00057 {
00058 return false;
00059 }
00060
00061
00062
00063
00064
00065 s /= std::sqrt( double(n_rows - 1) );
00066
00067
00068 score_out *= coeff_out;
00069
00070 if(n_rows <= n_cols)
00071 {
00072 score_out.cols(n_rows-1,n_cols-1).zeros();
00073
00074
00075 Col<eT> s_tmp(n_cols);
00076 s_tmp.zeros();
00077
00078 s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
00079 s = s_tmp;
00080
00081
00082 s_tmp.rows(0,n_rows-2) = eT(1) / s_tmp.rows(0,n_rows-2);
00083
00084 const Mat<eT> S = score_out * diagmat(Col<eT>(s_tmp));
00085 tsquared_out = sum(S%S,1);
00086 }
00087 else
00088 {
00089
00090 const Mat<eT> S = score_out * diagmat(Col<eT>( eT(1) / s));
00091 tsquared_out = sum(S%S,1);
00092 }
00093
00094
00095 latent_out = s%s;
00096 }
00097 else
00098 {
00099 coeff_out.eye(n_cols, n_cols);
00100
00101 score_out.copy_size(in);
00102 score_out.zeros();
00103
00104 latent_out.set_size(n_cols);
00105 latent_out.zeros();
00106
00107 tsquared_out.set_size(n_rows);
00108 tsquared_out.zeros();
00109 }
00110
00111 return true;
00112 }
00113
00114
00115
00122 template<typename eT>
00123 inline
00124 bool
00125 op_princomp::direct_princomp
00126 (
00127 Mat<eT>& coeff_out,
00128 Mat<eT>& score_out,
00129 Col<eT>& latent_out,
00130 const Mat<eT>& in
00131 )
00132 {
00133 arma_extra_debug_sigprint();
00134
00135 const uword n_rows = in.n_rows;
00136 const uword n_cols = in.n_cols;
00137
00138 if(n_rows > 1)
00139 {
00140
00141 score_out = in - repmat(mean(in), n_rows, 1);
00142
00143
00144 Mat<eT> U;
00145 Col<eT> s;
00146
00147 const bool svd_ok = svd(U,s,coeff_out,score_out);
00148
00149 if(svd_ok == false)
00150 {
00151 return false;
00152 }
00153
00154
00155
00156
00157
00158 s /= std::sqrt( double(n_rows - 1) );
00159
00160
00161 score_out *= coeff_out;
00162
00163 if(n_rows <= n_cols)
00164 {
00165 score_out.cols(n_rows-1,n_cols-1).zeros();
00166
00167 Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
00168 s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
00169 s = s_tmp;
00170 }
00171
00172
00173 latent_out = s%s;
00174
00175 }
00176 else
00177 {
00178 coeff_out.eye(n_cols, n_cols);
00179
00180 score_out.copy_size(in);
00181 score_out.zeros();
00182
00183 latent_out.set_size(n_cols);
00184 latent_out.zeros();
00185 }
00186
00187 return true;
00188 }
00189
00190
00191
00197 template<typename eT>
00198 inline
00199 bool
00200 op_princomp::direct_princomp
00201 (
00202 Mat<eT>& coeff_out,
00203 Mat<eT>& score_out,
00204 const Mat<eT>& in
00205 )
00206 {
00207 arma_extra_debug_sigprint();
00208
00209 const uword n_rows = in.n_rows;
00210 const uword n_cols = in.n_cols;
00211
00212 if(n_rows > 1)
00213 {
00214
00215 score_out = in - repmat(mean(in), n_rows, 1);
00216
00217
00218 Mat<eT> U;
00219 Col<eT> s;
00220
00221 const bool svd_ok = svd(U,s,coeff_out,score_out);
00222
00223 if(svd_ok == false)
00224 {
00225 return false;
00226 }
00227
00228
00229
00230
00231 s /= std::sqrt( double(n_rows - 1) );
00232
00233
00234 score_out *= coeff_out;
00235
00236 if(n_rows <= n_cols)
00237 {
00238 score_out.cols(n_rows-1,n_cols-1).zeros();
00239
00240 Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
00241 s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
00242 s = s_tmp;
00243 }
00244 }
00245 else
00246 {
00247 coeff_out.eye(n_cols, n_cols);
00248 score_out.copy_size(in);
00249 score_out.zeros();
00250 }
00251
00252 return true;
00253 }
00254
00255
00256
00261 template<typename eT>
00262 inline
00263 bool
00264 op_princomp::direct_princomp
00265 (
00266 Mat<eT>& coeff_out,
00267 const Mat<eT>& in
00268 )
00269 {
00270 arma_extra_debug_sigprint();
00271
00272 if(in.n_elem != 0)
00273 {
00274
00275 Mat<eT> U;
00276 Col<eT> s;
00277
00278 const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
00279
00280 const bool svd_ok = svd(U,s,coeff_out, tmp);
00281
00282 if(svd_ok == false)
00283 {
00284 return false;
00285 }
00286 }
00287 else
00288 {
00289 coeff_out.eye(in.n_cols, in.n_cols);
00290 }
00291
00292 return true;
00293 }
00294
00295
00296
00304 template<typename T>
00305 inline
00306 bool
00307 op_princomp::direct_princomp
00308 (
00309 Mat< std::complex<T> >& coeff_out,
00310 Mat< std::complex<T> >& score_out,
00311 Col<T>& latent_out,
00312 Col< std::complex<T> >& tsquared_out,
00313 const Mat< std::complex<T> >& in
00314 )
00315 {
00316 arma_extra_debug_sigprint();
00317
00318 typedef std::complex<T> eT;
00319
00320 const uword n_rows = in.n_rows;
00321 const uword n_cols = in.n_cols;
00322
00323 if(n_rows > 1)
00324 {
00325
00326 score_out = in - repmat(mean(in), n_rows, 1);
00327
00328
00329 Mat<eT> U;
00330 Col<T> s;
00331
00332 const bool svd_ok = svd(U,s,coeff_out,score_out);
00333
00334 if(svd_ok == false)
00335 {
00336 return false;
00337 }
00338
00339
00340
00341
00342
00343 s /= std::sqrt( double(n_rows - 1) );
00344
00345
00346 score_out *= coeff_out;
00347
00348 if(n_rows <= n_cols)
00349 {
00350 score_out.cols(n_rows-1,n_cols-1).zeros();
00351
00352 Col<T> s_tmp = zeros< Col<T> >(n_cols);
00353 s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
00354 s = s_tmp;
00355
00356
00357 s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
00358 const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));
00359 tsquared_out = sum(S%S,1);
00360 }
00361 else
00362 {
00363
00364 const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));
00365 tsquared_out = sum(S%S,1);
00366 }
00367
00368
00369 latent_out = s%s;
00370
00371 }
00372 else
00373 {
00374 coeff_out.eye(n_cols, n_cols);
00375
00376 score_out.copy_size(in);
00377 score_out.zeros();
00378
00379 latent_out.set_size(n_cols);
00380 latent_out.zeros();
00381
00382 tsquared_out.set_size(n_rows);
00383 tsquared_out.zeros();
00384 }
00385
00386 return true;
00387 }
00388
00389
00390
00397 template<typename T>
00398 inline
00399 bool
00400 op_princomp::direct_princomp
00401 (
00402 Mat< std::complex<T> >& coeff_out,
00403 Mat< std::complex<T> >& score_out,
00404 Col<T>& latent_out,
00405 const Mat< std::complex<T> >& in
00406 )
00407 {
00408 arma_extra_debug_sigprint();
00409
00410 typedef std::complex<T> eT;
00411
00412 const uword n_rows = in.n_rows;
00413 const uword n_cols = in.n_cols;
00414
00415 if(n_rows > 1)
00416 {
00417
00418 score_out = in - repmat(mean(in), n_rows, 1);
00419
00420
00421 Mat<eT> U;
00422 Col< T> s;
00423
00424 const bool svd_ok = svd(U,s,coeff_out,score_out);
00425
00426 if(svd_ok == false)
00427 {
00428 return false;
00429 }
00430
00431
00432
00433
00434
00435 s /= std::sqrt( double(n_rows - 1) );
00436
00437
00438 score_out *= coeff_out;
00439
00440 if(n_rows <= n_cols)
00441 {
00442 score_out.cols(n_rows-1,n_cols-1).zeros();
00443
00444 Col<T> s_tmp = zeros< Col<T> >(n_cols);
00445 s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
00446 s = s_tmp;
00447 }
00448
00449
00450 latent_out = s%s;
00451
00452 }
00453 else
00454 {
00455 coeff_out.eye(n_cols, n_cols);
00456
00457 score_out.copy_size(in);
00458 score_out.zeros();
00459
00460 latent_out.set_size(n_cols);
00461 latent_out.zeros();
00462 }
00463
00464 return true;
00465 }
00466
00467
00468
00474 template<typename T>
00475 inline
00476 bool
00477 op_princomp::direct_princomp
00478 (
00479 Mat< std::complex<T> >& coeff_out,
00480 Mat< std::complex<T> >& score_out,
00481 const Mat< std::complex<T> >& in
00482 )
00483 {
00484 arma_extra_debug_sigprint();
00485
00486 typedef std::complex<T> eT;
00487
00488 const uword n_rows = in.n_rows;
00489 const uword n_cols = in.n_cols;
00490
00491 if(n_rows > 1)
00492 {
00493
00494 score_out = in - repmat(mean(in), n_rows, 1);
00495
00496
00497 Mat<eT> U;
00498 Col< T> s;
00499
00500 const bool svd_ok = svd(U,s,coeff_out,score_out);
00501
00502 if(svd_ok == false)
00503 {
00504 return false;
00505 }
00506
00507
00508
00509
00510 s /= std::sqrt( double(n_rows - 1) );
00511
00512
00513 score_out *= coeff_out;
00514
00515 if(n_rows <= n_cols)
00516 {
00517 score_out.cols(n_rows-1,n_cols-1).zeros();
00518 }
00519
00520 }
00521 else
00522 {
00523 coeff_out.eye(n_cols, n_cols);
00524
00525 score_out.copy_size(in);
00526 score_out.zeros();
00527 }
00528
00529 return true;
00530 }
00531
00532
00533
00538 template<typename T>
00539 inline
00540 bool
00541 op_princomp::direct_princomp
00542 (
00543 Mat< std::complex<T> >& coeff_out,
00544 const Mat< std::complex<T> >& in
00545 )
00546 {
00547 arma_extra_debug_sigprint();
00548
00549 typedef typename std::complex<T> eT;
00550
00551 if(in.n_elem != 0)
00552 {
00553
00554 Mat<eT> U;
00555 Col< T> s;
00556
00557 const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
00558
00559 const bool svd_ok = svd(U,s,coeff_out, tmp);
00560
00561 if(svd_ok == false)
00562 {
00563 return false;
00564 }
00565 }
00566 else
00567 {
00568 coeff_out.eye(in.n_cols, in.n_cols);
00569 }
00570
00571 return true;
00572 }
00573
00574
00575
00576 template<typename T1>
00577 inline
00578 void
00579 op_princomp::apply
00580 (
00581 Mat<typename T1::elem_type>& out,
00582 const Op<T1,op_princomp>& in
00583 )
00584 {
00585 arma_extra_debug_sigprint();
00586
00587 typedef typename T1::elem_type eT;
00588
00589 const unwrap_check<T1> tmp(in.m, out);
00590 const Mat<eT>& A = tmp.M;
00591
00592 const bool status = op_princomp::direct_princomp(out, A);
00593
00594 if(status == false)
00595 {
00596 out.reset();
00597
00598 arma_bad("princomp(): failed to converge");
00599 }
00600 }
00601
00602
00603