3 #include <boost/numeric/ublas/matrix.hpp>
4 #include <boost/numeric/ublas/matrix_proxy.hpp>
5 #include <boost/numeric/ublas/vector.hpp>
6 #include <boost/numeric/ublas/lu.hpp>
7 #include <boost/numeric/ublas/io.hpp>
15 namespace ublas = boost::numeric::ublas;
16 std::complex<double>
sign(
const std::complex<double> &z)
19 return std::complex<double>(0.0, 0.0);
26 return (1.0 - exp(-x)) / (1.0 + exp(x));
29 void ComplexICA(cmat &input, cmat &source_estimate, cmat &mixing_matrix)
31 mixing_matrix = ublas::identity_matrix<double>(input.size1());
32 cmat mix_grad(input.size1(), input.size1());
33 const int maxiterations = 100;
34 const double min_improv = 0.01;
35 double improvement = 10.0;
38 cmat white_mat(mixing_matrix);
39 cmat evec(input.size1(), input.size1());
40 cvec eval(input.size1());
41 PCA(input, evec, eval);
43 std::cout <<
"white_mat: " << white_mat << std::endl;
44 input = prod(white_mat, input);
46 while (improvement > min_improv && niter < maxiterations)
48 std::cout << std::endl << std::endl <<
"Iter: " << niter
50 ublas::noalias(source_estimate) = ublas::prod(mixing_matrix, input);
51 cmat outer_expect(input.size1(), input.size1());
52 cmat v(input.size1(), input.size2());
53 for (
size_t i = 0; i < v.size1(); ++i)
55 for (
size_t j = 0; j < v.size2(); ++j)
56 v(i, j) =
sign(source_estimate(i, j)) *
non_lin(abs(
57 source_estimate(i, j)));
59 for (
size_t i = 0; i < input.size2(); ++i)
61 outer_expect += ublas::outer_prod(ublas::column(v, i),
62 ublas::herm(ublas::column(source_estimate, i)));
64 outer_expect /= input.size2();
65 mix_grad = mixing_matrix;
66 ublas::axpy_prod(-outer_expect, mixing_matrix, mix_grad);
67 mixing_matrix += real(mix_grad);
69 std::cout <<
"mixing: " << mixing_matrix << std::endl;
70 std::cout <<
"mix_grad: " << mix_grad << std::endl;
71 std::cout <<
"Norm(mix_grad): " << ublas::norm_inf(mix_grad)
73 std::cout <<
"outer_expect: " << outer_expect << std::endl;
74 improvement = ublas::norm_inf(mix_grad) / ublas::norm_inf(
76 std::cout <<
"improvement: " << improvement << std::endl;
gplib::cmat WhiteMat(gplib::cmat &evectors, gplib::cvec &evalues)
Calculate the Whitening Matrix.
void PCA(const UblasMatrix &observations, gplib::cmat &evectors, gplib::cvec &evalues)
This template function calculates the principal component rotation matrix from a matrix of observatio...
std::complex< double > sign(const std::complex< double > &z)
double non_lin(const double x)
void ComplexICA(cmat &input, cmat &source_estimate, cmat &mixing_matrix)