/** * @file tiny_ica.hpp * @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg) * @brief tiny_ica | code | header * @version 1.0 * @date 2025-04-30 * @copyright Copyright (c) 2025 * */#pragma once/* DEPENDENCIES */// tiny_dsp configuration file#include"tiny_dsp_config.h"// tiny_math for matrix operations#include"tiny_matrix.hpp"#ifdef __cplusplus#include<cstdint>#include<cmath>namespacetiny{/** * @brief Nonlinearity function types for FastICA */enumclassICANonlinearity{TANH=0,///< tanh function (default, good for super-Gaussian sources)CUBE,///< x^3 function (good for sub-Gaussian sources)GAUSS,///< Gaussian function (good for symmetric sources)SKEW///< Skew function (good for skewed sources)};/** * @brief Structure to hold ICA decomposition results * @note X = A * S, where X is mixed signals, A is mixing matrix, S is source signals * After ICA: S = W * X, where W is unmixing matrix */structICADecomposition{Matunmixing_matrix;///< Unmixing matrix W (sources x sensors)Matmixing_matrix;///< Estimated mixing matrix A = W^(-1) (sensors x sources)Matsources;///< Estimated source signals (sources x samples)Matwhitening_matrix;///< Whitening matrix used in preprocessingMatmean;///< Mean vector of input signals (for centering)intiterations;///< Number of iterations performedtiny_error_tstatus;///< Computation statusICADecomposition();};/** * @brief ICA class for Independent Component Analysis * @note Implements FastICA algorithm for blind source separation */classICA{public:/** * @brief Default constructor * @param nonlinearity Nonlinearity function for FastICA (default: TANH) * @param max_iter Maximum number of iterations (default: 1000) * @param tolerance Convergence tolerance (default: 1e-6) * @param alpha Step size for FastICA (default: 1.0) */ICA(ICANonlinearitynonlinearity=ICANonlinearity::TANH,intmax_iter=1000,floattolerance=1e-6f,floatalpha=1.0f);/** * @brief Destructor */~ICA();/** * @brief Perform ICA decomposition on mixed signals * @param mixed_signals Input matrix (sensors x samples) * @param num_sources Number of sources to extract (0 = auto-detect, default: 0) * @return ICADecomposition structure containing results * @note Input matrix: each row is a sensor signal, each column is a time sample * If num_sources is 0, it will be set to the number of sensors (rows) */ICADecompositiondecompose(constMat&mixed_signals,intnum_sources=0);/** * @brief Reconstruct mixed signals from sources using mixing matrix * @param sources Source signals matrix (sources x samples) * @param mixing_matrix Mixing matrix (sensors x sources) * @return Reconstructed mixed signals (sensors x samples) */staticMatreconstruct(constMat&sources,constMat&mixing_matrix);/** * @brief Apply learned unmixing matrix to new data * @param decomposition ICA decomposition result from previous decompose() call * @param new_mixed_signals New mixed signals (sensors x samples) * @return Separated sources (sources x samples) */staticMatapply(constICADecomposition&decomposition,constMat&new_mixed_signals);/** * @brief Set algorithm parameters */voidset_max_iterations(intmax_iter);voidset_tolerance(floattolerance);voidset_alpha(floatalpha);voidset_nonlinearity(ICANonlinearitynonlinearity);private:ICANonlinearitynonlinearity_;intmax_iter_;floattolerance_;floatalpha_;/** * @brief Center the data (remove mean) */staticMatcenter_data(constMat&data,Mat&mean);/** * @brief Whiten the data (decorrelate and normalize variance) */staticMatwhiten_data(constMat&data,Mat&whitening_matrix);/** * @brief FastICA algorithm implementation */ICADecompositionfastica(constMat&mixed_signals,intnum_sources);/** * @brief Apply nonlinearity function */floatapply_nonlinearity(floatx)const;Matapply_nonlinearity(constMat&x)const;/** * @brief Compute derivative of nonlinearity function */floatapply_nonlinearity_derivative(floatx)const;Matapply_nonlinearity_derivative(constMat&x)const;/** * @brief Orthogonalize vector against previous vectors (Gram-Schmidt) */staticvoidorthogonalize(Mat&w,constMat&W_prev);/** * @brief Normalize vector to unit length */staticvoidnormalize(Mat&w);};}// namespace tiny#endif // __cplusplus
/** * @file tiny_ica.hpp * @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg) * @brief tiny_ica | code | header * @version 1.0 * @date 2025-04-30 * @copyright Copyright (c) 2025 * */#pragma once/* DEPENDENCIES */// tiny_dsp configuration file#include"tiny_dsp_config.h"// tiny_math for matrix operations#include"tiny_matrix.hpp"#ifdef __cplusplus#include<cstdint>#include<cmath>namespacetiny{/** * @brief Nonlinearity function types for FastICA */enumclassICANonlinearity{TANH=0,///< tanh function (default, good for super-Gaussian sources)CUBE,///< x^3 function (good for sub-Gaussian sources)GAUSS,///< Gaussian function (good for symmetric sources)SKEW///< Skew function (good for skewed sources)};/** * @brief Structure to hold ICA decomposition results * @note X = A * S, where X is mixed signals, A is mixing matrix, S is source signals * After ICA: S = W * X, where W is unmixing matrix */structICADecomposition{Matunmixing_matrix;///< Unmixing matrix W (sources x sensors)Matmixing_matrix;///< Estimated mixing matrix A = W^(-1) (sensors x sources)Matsources;///< Estimated source signals (sources x samples)Matwhitening_matrix;///< Whitening matrix used in preprocessingMatmean;///< Mean vector of input signals (for centering)intiterations;///< Number of iterations performedtiny_error_tstatus;///< Computation statusICADecomposition();};/** * @brief ICA class for Independent Component Analysis * @note Implements FastICA algorithm for blind source separation */classICA{public:/** * @brief Default constructor * @param nonlinearity Nonlinearity function for FastICA (default: TANH) * @param max_iter Maximum number of iterations (default: 1000) * @param tolerance Convergence tolerance (default: 1e-6) * @param alpha Step size for FastICA (default: 1.0) */ICA(ICANonlinearitynonlinearity=ICANonlinearity::TANH,intmax_iter=1000,floattolerance=1e-6f,floatalpha=1.0f);/** * @brief Destructor */~ICA();/** * @brief Perform ICA decomposition on mixed signals * @param mixed_signals Input matrix (sensors x samples) * @param num_sources Number of sources to extract (0 = auto-detect, default: 0) * @return ICADecomposition structure containing results * @note Input matrix: each row is a sensor signal, each column is a time sample * If num_sources is 0, it will be set to the number of sensors (rows) */ICADecompositiondecompose(constMat&mixed_signals,intnum_sources=0);/** * @brief Reconstruct mixed signals from sources using mixing matrix * @param sources Source signals matrix (sources x samples) * @param mixing_matrix Mixing matrix (sensors x sources) * @return Reconstructed mixed signals (sensors x samples) */staticMatreconstruct(constMat&sources,constMat&mixing_matrix);/** * @brief Apply learned unmixing matrix to new data * @param decomposition ICA decomposition result from previous decompose() call * @param new_mixed_signals New mixed signals (sensors x samples) * @return Separated sources (sources x samples) */staticMatapply(constICADecomposition&decomposition,constMat&new_mixed_signals);/** * @brief Set algorithm parameters */voidset_max_iterations(intmax_iter);voidset_tolerance(floattolerance);voidset_alpha(floatalpha);voidset_nonlinearity(ICANonlinearitynonlinearity);private:ICANonlinearitynonlinearity_;intmax_iter_;floattolerance_;floatalpha_;/** * @brief Center the data (remove mean) */staticMatcenter_data(constMat&data,Mat&mean);/** * @brief Whiten the data (decorrelate and normalize variance) */staticMatwhiten_data(constMat&data,Mat&whitening_matrix);/** * @brief FastICA algorithm implementation */ICADecompositionfastica(constMat&mixed_signals,intnum_sources);/** * @brief Apply nonlinearity function */floatapply_nonlinearity(floatx)const;Matapply_nonlinearity(constMat&x)const;/** * @brief Compute derivative of nonlinearity function */floatapply_nonlinearity_derivative(floatx)const;Matapply_nonlinearity_derivative(constMat&x)const;/** * @brief Orthogonalize vector against previous vectors (Gram-Schmidt) */staticvoidorthogonalize(Mat&w,constMat&W_prev);/** * @brief Normalize vector to unit length */staticvoidnormalize(Mat&w);};}// namespace tiny#endif // __cplusplus