ComplexICA.h

Go to the documentation of this file.
00001 #ifndef COMPLEXICA_H_
00002 #define COMPLEXICA_H_
00003 #include <boost/numeric/ublas/matrix.hpp>
00004 #include <boost/numeric/ublas/matrix_proxy.hpp>
00005 #include <boost/numeric/ublas/vector.hpp>
00006 #include <boost/numeric/ublas/lu.hpp>
00007 #include <boost/numeric/ublas/io.hpp>
00008 #include <complex>
00009 #include <iostream>
00010 #include "PCA.h"
00011 #include "VecMat.h"
00012 
00013 namespace gplib
00014   {
00015     namespace ublas = boost::numeric::ublas;
00016     std::complex<double> sign(const std::complex<double> &z)
00017       {
00018         if (abs(z) == 0)
00019           return std::complex<double>(0.0, 0.0);
00020         else
00021           return z / abs(z);
00022       }
00023 
00024     double non_lin(const double x)
00025       {
00026         return (1.0 - exp(-x)) / (1.0 + exp(x));
00027       }
00028 
00029     void ComplexICA(cmat &input, cmat &source_estimate, cmat &mixing_matrix)
00030       {
00031         mixing_matrix = ublas::identity_matrix<double>(input.size1());
00032         cmat mix_grad(input.size1(), input.size1());
00033         const int maxiterations = 100;
00034         const double min_improv = 0.01;
00035         double improvement = 10.0;
00036         int niter = 0;
00037 
00038         cmat white_mat(mixing_matrix);
00039         cmat evec(input.size1(), input.size1());
00040         cvec eval(input.size1());
00041         PCA(input, evec, eval);
00042         white_mat = WhiteMat(evec, eval);
00043         std::cout << "white_mat: " << white_mat << std::endl;
00044         input = prod(white_mat, input);
00045 
00046         while (improvement > min_improv && niter < maxiterations)
00047           {
00048             std::cout << std::endl << std::endl << "Iter: " << niter
00049                 << std::endl;
00050             ublas::noalias(source_estimate) = ublas::prod(mixing_matrix, input);
00051             cmat outer_expect(input.size1(), input.size1());
00052             cmat v(input.size1(), input.size2());
00053             for (size_t i = 0; i < v.size1(); ++i)
00054               {
00055                 for (size_t j = 0; j < v.size2(); ++j)
00056                   v(i, j) = sign(source_estimate(i, j)) * non_lin(abs(
00057                       source_estimate(i, j)));
00058               }
00059             for (size_t i = 0; i < input.size2(); ++i)
00060               {
00061                 outer_expect += ublas::outer_prod(ublas::column(v, i),
00062                     ublas::herm(ublas::column(source_estimate, i)));
00063               }
00064             outer_expect /= input.size2();
00065             mix_grad = mixing_matrix;
00066             ublas::axpy_prod(-outer_expect, mixing_matrix, mix_grad);
00067             mixing_matrix += real(mix_grad);
00068             //std::cout << "source: " << source_estimate << std::endl;
00069             std::cout << "mixing: " << mixing_matrix << std::endl;
00070             std::cout << "mix_grad: " << mix_grad << std::endl;
00071             std::cout << "Norm(mix_grad): " << ublas::norm_inf(mix_grad)
00072                 << std::endl;
00073             std::cout << "outer_expect: " << outer_expect << std::endl;
00074             improvement = ublas::norm_inf(mix_grad) / ublas::norm_inf(
00075                 mixing_matrix);
00076             std::cout << "improvement: " << improvement << std::endl;
00077             ++niter;
00078           }
00079       }
00080   }
00081 #endif /*COMPLEXICA_H_*/

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8