GPLIB++
ComplexICA.h
Go to the documentation of this file.
1 #ifndef COMPLEXICA_H_
2 #define COMPLEXICA_H_
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>
8 #include <complex>
9 #include <iostream>
10 #include "PCA.h"
11 #include "VecMat.h"
12 
13 namespace gplib
14  {
15  namespace ublas = boost::numeric::ublas;
16  std::complex<double> sign(const std::complex<double> &z)
17  {
18  if (abs(z) == 0)
19  return std::complex<double>(0.0, 0.0);
20  else
21  return z / abs(z);
22  }
23 
24  double non_lin(const double x)
25  {
26  return (1.0 - exp(-x)) / (1.0 + exp(x));
27  }
28 
29  void ComplexICA(cmat &input, cmat &source_estimate, cmat &mixing_matrix)
30  {
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;
36  int niter = 0;
37 
38  cmat white_mat(mixing_matrix);
39  cmat evec(input.size1(), input.size1());
40  cvec eval(input.size1());
41  PCA(input, evec, eval);
42  white_mat = WhiteMat(evec, eval);
43  std::cout << "white_mat: " << white_mat << std::endl;
44  input = prod(white_mat, input);
45 
46  while (improvement > min_improv && niter < maxiterations)
47  {
48  std::cout << std::endl << std::endl << "Iter: " << niter
49  << std::endl;
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)
54  {
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)));
58  }
59  for (size_t i = 0; i < input.size2(); ++i)
60  {
61  outer_expect += ublas::outer_prod(ublas::column(v, i),
62  ublas::herm(ublas::column(source_estimate, i)));
63  }
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);
68  //std::cout << "source: " << source_estimate << std::endl;
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)
72  << std::endl;
73  std::cout << "outer_expect: " << outer_expect << std::endl;
74  improvement = ublas::norm_inf(mix_grad) / ublas::norm_inf(
75  mixing_matrix);
76  std::cout << "improvement: " << improvement << std::endl;
77  ++niter;
78  }
79  }
80  }
81 #endif /*COMPLEXICA_H_*/
gplib::cmat WhiteMat(gplib::cmat &evectors, gplib::cvec &evalues)
Calculate the Whitening Matrix.
Definition: PCA.h:46
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...
Definition: PCA.h:25
std::complex< double > sign(const std::complex< double > &z)
Definition: ComplexICA.h:16
double non_lin(const double x)
Definition: ComplexICA.h:24
void ComplexICA(cmat &input, cmat &source_estimate, cmat &mixing_matrix)
Definition: ComplexICA.h:29