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
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