/*---------------------------------------------------------------------------*
 *                                   IT++			             *
 *---------------------------------------------------------------------------*
 * Copyright (c) 1995-2004 by Tony Ottosson, Thomas Eriksson, Pål Frenger,   *
 * Tobias Ringström, and Jonas Samuelsson.                                   *
 *                                                                           *
 * Permission to use, copy, modify, and distribute this software and its     *
 * documentation under the terms of the GNU General Public License is hereby *
 * granted. No representations are made about the suitability of this        *
 * software for any purpose. It is provided "as is" without expressed or     *
 * implied warranty. See the GNU General Public License for more details.    *
 *---------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------------------*
 * FastICA for IT++                                                                       *
 *----------------------------------------------------------------------------------------*
 * This code is Copyright (C) 2004 by François CAYRE and Teddy FURON                      *
 *                                    TEMICS Project                                      *
 *                                    INRIA/Rennes (IRISA)                                *
 *                                    Campus Universitaire de Beaulieu                    *
 *                                    35042 RENNES cedex FRANCE                           *
 *                                                                                        *
 * Email : firstname.lastname@irisa.fr                                                    *
 *                                                                                        *
 * This is the IT++ implementation of the original Matlab package FastICA.                * 
 *                                                                                        *
 * Matlab package is Copyright (C) 1998 by Jarmo HURRI, Hugo GÄVERT, Jaakko SÄRELÄ and    *
 *                                         Aapo HYVÄRINEN                                 *
 *                                         Laboratory of Information and Computer Science *
 *                                         Helsinki University of Technology              *
 *                                                                                        *
 * URL : http://www.cis.hut.fi/projects/ica/fastica/about.shtml                           *
 *                                                                                        *
 * If you use results given by this FastICA software in an article for a scientific       *
 * journal, conference proceedings or similar, please include the following original      *
 * reference in the bibliography :                                                        *
 *                                                                                        *
 *     A. Hyvärinen. Fast and Robust Fixed-Point Algorithms for Independent Component     *
 *     Analysis. IEEE Transactions on Neural Networks 10(3):626-634, 1999.                *
 *----------------------------------------------------------------------------------------*
 *                                           DISCLAIMER                                   *
 *                                                                                        *
 * This software package is free software ; you can redistribute it and/or modify it      *
 * under the terms of the GNU General Public License as published by the Free Software    * 
 * Foundation ; either version 2 of the License, or any later version.                    *
 *                                                                                        *
 * The software package is distributed in the hope that it will be useful, but WITHOUT    *
 * ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR     * 
 * A PARTICULAR PURPOSE.                                                                  *
 * See the GNU General Public License for more details.                                   *
 *                                                                                        *
 *----------------------------------------------------------------------------------------* 
 * Differences with the original Matlab implementation :                                  * 
 * - no GUI                                                                               *
 * - return something even in the case of a convergence problem                           * 
 * - optimization of SVD decomposition (performed 2 times in Matlab, only 1 time in IT++) *
 * - default approach is SYMM wit non-linearity POW3                                      *
 *----------------------------------------------------------------------------------------*/

/*! 
  \file 
  \brief FastICA for IT++ (Independent Component Analysis)
  \author François Cayre and Teddy Furon

  1.3

  2004/08/19 12:27:13
*/

#ifndef _fastica_h
#define _fastica_h

#include "base/matfunc.h"
#include "base/mat.h"
#include "base/vec.h"


#ifndef NO_LAPACK


//! Use deflation approach : compute IC one-by-one in a Gram-Schmidt-like fashion
#define FICA_APPROACH_DEFL 2 
//! Use symmetric approach : compute all ICs at a time
#define FICA_APPROACH_SYMM 1 

//! Use x^3 non-linearity
#define FICA_NONLIN_POW3 10 
//! Use tanh(x) non-linearity
#define FICA_NONLIN_TANH 20 
//! Use Gaussian non-linearity
#define FICA_NONLIN_GAUSS 30 
//! Use skew non-linearity
#define FICA_NONLIN_SKEW 40 

//! Set random start for FastICA
#define FICA_INIT_RAND  0 
//! Set predefined start for FastICA
#define FICA_INIT_GUESS 1 

//! Eigenvalues of the covariance matrix lower than TOL are discarded for analysis
#define FICA_TOL 1e-9

namespace itpp {

  /*!
    \defgroup fastica Fast Independent Component Analysis
  */

  //---------------------- FastICA --------------------------------------

  /*! 
    \ingroup fastica
    \brief Class for performing independent component analysis (blind source separation)
  
    The software is based upon original FastICA for Matlab from 
    A. Hyvärinen. Fast and Robust Fixed-Point Algorithms for Independent Component Analysis. 
    IEEE Transactions on Neural Networks, 10(3), pp. 626-634, 1999.

    Example: 
    \code
    FastICA fastica(sources);
    fastica.set_nrIC(sources.rows());
    fastica.set_non_linearity(  FICA_NONLIN_TANH );
    fastica.set_approach( FICA_APPROACH_DEFL );
    fastica.separate();
    mat ICs = fastica.get_IC();
    \endcode 
  */

  class FastICA {

  public: 

    //! \brief Initialize an ICA object with a given data matrix
    //! \param ma_mixed_sig Mixed IC observations to separate
    FastICA( mat ma_mixed_sig );

    //! \brief Explicit launch of main FastICA function
    void separate( void );

    //! \brief Set approach : FICA_APPROACH_DEFL or FICA_APPROACH_SYMM (default) 
    //! \param in_approach FICA_APPROACH_DEFL or FICA_APPROACH_SYMM (default)
    void set_approach( int in_approach ) { approach = in_approach; if ( approach == FICA_APPROACH_DEFL ) finetune = true; }; 

    //! \brief Set number of independent components to separate
    //! \param in_nrIC Set number of Indenpendent Components to separate 
    void set_nrIC( int in_nrIC ) { numOfIC = in_nrIC; };

    //! \brief Set non-linearity to use : FICA_NONLIN_POW3 (default),  FICA_NONLIN_TANH, FICA_NONLIN_GAUSS, FICA_NONLIN_SKEW
    //! \param in_g FICA_NONLIN_POW3 (default),  FICA_NONLIN_TANH, FICA_NONLIN_GAUSS, FICA_NONLIN_SKEW
    void set_non_linearity( int in_g ) { g = in_g; };

    //! \brief Set fine tuning true or false
    //! \param in_finetune true or false (default)
    void set_fine_tune( bool in_finetune ) { finetune = in_finetune; };

    //! \brief Set a_1 parameter
    void set_a1( double fl_a1 ) { a1 = fl_a1; };

    //! \brief Set a_2 parameter
    void set_a2( double fl_a2 ) { a2 = fl_a2; };

    //! \brief Set mu parameter
    void set_mu( double fl_mu ) { mu = fl_mu; };

    //! \brief Set convergence parameter epsilon
    void set_epsilon( double fl_epsilon ) { epsilon = fl_epsilon; };

    //! \brief Set sample size
    void set_sample_size( double fl_sampleSize ) { sampleSize = fl_sampleSize; };

    //! \brief Set stabilization mode true or off
    //! \param in_stabilization true or false (default)
    void set_stabilization( bool in_stabilization ) { stabilization = in_stabilization; };

    //! \brief Set maximum number of iterations
    void set_max_num_iterations( int in_maxNumIterations ) { maxNumIterations = in_maxNumIterations; };

    //! \brief Set maximum number of iterations for fine tuning
    void set_max_fine_tune( int in_maxFineTune ) { maxFineTune = in_maxFineTune; };

    //! \brief Set first eigenvalue index to take into account
    void set_first_eig( int in_firstEig ) { firstEig = in_firstEig; };

    //! \brief Set last eigenvalue index to take into account
    void set_last_eig( int in_lastEig ) { lastEig = in_lastEig; };

    //! \brief If true, only perform Principal Component Analysis (default = false)
    void set_PCA_only( bool in_PCAonly ) { PCAonly = in_PCAonly; };

    //! \brief Set initial guess matrix instead of random (default)
    void set_init_guess( mat ma_initGuess ) { initGuess = ma_initGuess; };


    //! \brief Get mixing matrix
    mat get_mixing_matrix() { if ( PCAonly ) { it_warning ( "No ICA performed." ); return (zeros(1,1));} else return A; };

    //! \brief Get separating matrix
    mat get_separating_matrix() { if ( PCAonly ) { it_warning ( "No ICA performed." ); return(zeros(1,1)); } else return W; };

    //! \brief Get separated signals
    mat get_IC() { if ( PCAonly ) { it_warning ( "No ICA performed." ); return(zeros(1,1)); } else return icasig; };

    //! \brief Get number of independent components
    int get_nrIC() { return numOfIC; };

    //! \brief Get nrIC first columns of the de-whitening matrix
    mat get_principal_eigenvectors() { return VecPr; };

    //! \brief Get the whitening matrix
    mat get_whitening_matrix() { return whiteningMatrix; };

    //! \brief Get the de-whitening matrix
    mat get_dewhitening_matrix() { return dewhiteningMatrix; };

    //! \brief Get whitened signals
    mat get_white_sig() { return whitesig; };

  private:

    int approach, numOfIC, g, initState; 
    bool finetune, stabilization, PCAonly;
    double a1, a2, mu, epsilon, sampleSize; 
    int maxNumIterations, maxFineTune; 

    int firstEig, lastEig; 

    mat initGuess; 

    mat mixedSig, A, W, icasig; 

    mat whiteningMatrix;
    mat dewhiteningMatrix; 
    mat whitesig;

    mat E, VecPr; 
    vec D; 

  }; // class FastICA



} // namespace itpp

#endif // NO_LAPACK

#endif // _fastica_h


syntax highlighted by Code2HTML, v. 0.9.1