FastICA.h
Go to the documentation of this file.00001 #ifndef FASTICA_H_
00002 #define FASTICA_H_
00003 #include "VecMat.h"
00004 #include <complex>
00005 #include <iostream>
00006 #include <cmath>
00007 #include "PCA.h"
00008
00009 namespace ublas = boost::numeric::ublas;
00010
00011 namespace gplib
00012 {
00013
00014
00015
00016 void FastICA(rmat &input, rmat &source_estimate, rmat &mixing_matrix)
00017 {
00018 mixing_matrix = ublas::identity_matrix<double>(input.size1());
00019 rmat old_mix(mixing_matrix);
00020 rmat new_mix(mixing_matrix);
00021 rmat white_mat(mixing_matrix);
00022 cmat evec(input.size1(), input.size1());
00023 cvec eval(input.size1());
00024 PCA(input, evec, eval);
00025 white_mat = real(WhiteMat(evec, eval));
00026 std::cout << "white_mat: " << white_mat << std::endl;
00027 input = prod(white_mat, input);
00028 const int maxiterations = 1000;
00029 const double min_improv = 0.01;
00030 double improvement = 10.0;
00031 int niter = 0;
00032 while (niter < maxiterations)
00033 {
00034
00035 ublas::noalias(source_estimate) = ublas::prod(mixing_matrix, input);
00036 rmat pow3mat = prod(trans(input), mixing_matrix);
00037
00038 for (size_t i = 0; i < pow3mat.size1(); ++i)
00039 {
00040 for (size_t j = 0; j < pow3mat.size2(); ++j)
00041 pow3mat(i, j) = std::pow(pow3mat(i, j), 3);
00042 }
00043 new_mix = prod(input, pow3mat);
00044 new_mix /= input.size2();
00045 new_mix -= 3.0 * mixing_matrix;
00046 mixing_matrix = new_mix;
00047
00048 rmat wwt = prod(mixing_matrix, trans(mixing_matrix));
00049 mixing_matrix /= sqrt(norm_inf(wwt));
00050 for (int i = 0; i < maxiterations; ++i)
00051 {
00052 rmat neww(mixing_matrix);
00053 wwt = prod(mixing_matrix, trans(mixing_matrix));
00054 neww *= 1.5;
00055 mixing_matrix = prod(wwt, mixing_matrix);
00056 mixing_matrix *= 0.5;
00057 neww -= mixing_matrix;
00058 mixing_matrix = neww;
00059
00060 }
00061
00062 ++niter;
00063 }
00064
00065 noalias(source_estimate) = prod(trans(mixing_matrix), input);
00066 mixing_matrix = prod(trans(mixing_matrix), white_mat);
00067 }
00068
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #endif