public static double[][] fastICA(double[][] input,int maxIterations,double epsilon,int noComponents){
  whitening(input);
  int m=Matrix.getNumOfRows(whitenedVectors);
  int n=Matrix.getNumOfColumns(whitenedVectors);
  if (m > noComponents) {
    noComponents=m;
  }
  B=Matrix.random(noComponents,m);
  B=Matrix.mult(powerSymmMatrix(Matrix.square(B),-0.5),B);
  for (int k=1; k < maxIterations; k++) {
    double[][] oldB=Matrix.clone(B);
    for (int c=0; c < noComponents; c++) {
      double[] prevW=Matrix.getVecOfRow(oldB,c);
      double[] firstPart=new double[m];
      for (int j=0; j < n; j++) {
        double one=Vector.dot(prevW,Matrix.getVecOfCol(whitenedVectors,j));
        one=Math.pow(one,3);
        double[] two=Vector.scale(one,Matrix.getVecOfCol(whitenedVectors,j));
        firstPart=Vector.add(firstPart,two);
      }
      firstPart=Vector.scale((1.0 / (double)n),firstPart);
      double[] secondPart=Vector.scale(-3,prevW);
      double[] w=Vector.add(firstPart,secondPart);
      for (int j=0; j < m; ++j) {
        B[c][j]=w[j];
      }
    }
    B=Matrix.mult(powerSymmMatrix(Matrix.square(B),-0.5),B);
    double matrixDelta=deltaMatrices(B,oldB);
    if (matrixDelta < epsilon) {
      break;
    }
  }
  double[][] sepMatrix=Matrix.mult(B,whiteningMatrix);
  return Matrix.mult(sepMatrix,input);
}

public static double [ ] [ ] fastICA ( double [ ] [ ] input , int maxIterations , double epsilon , int noComponents ) { whitening ( input ) ; int m = Matrix . getNumOfRows ( whitenedVectors ) ; int n = Matrix . getNumOfColumns ( whitenedVectors ) ; if ( m > noComponents ) { noComponents = m ; } B = Matrix . random ( noComponents , m ) ; B = Matrix . mult ( powerSymmMatrix ( Matrix . square ( B ) , - 0.5 ) , B ) ; for ( int k = 1 ; k < maxIterations ; k ++ ) { double [ ] [ ] oldB = Matrix . clone ( B ) ; for ( int c = 0 ; c < noComponents ; c ++ ) { double [ ] prevW = Matrix . getVecOfRow ( oldB , c ) ; double [ ] firstPart = new double [ m ] ; for ( int j = 0 ; j < n ; j ++ ) { double one = Vector . dot ( prevW , Matrix . getVecOfCol ( whitenedVectors , j ) ) ; one = Math . pow ( one , 3 ) ; double [ ] two = Vector . scale ( one , Matrix . getVecOfCol ( whitenedVectors , j ) ) ; firstPart = Vector . add ( firstPart , two ) ; } firstPart = Vector . scale ( ( 1.0 / ( double ) n ) , firstPart ) ; double [ ] secondPart = Vector . scale ( - 3 , prevW ) ; double [ ] w = Vector . add ( firstPart , secondPart ) ; for ( int j = 0 ; j < m ; ++ j ) { B [ c ] [ j ] = w [ j ] ; } } B = Matrix . mult ( powerSymmMatrix ( Matrix . square ( B ) , - 0.5 ) , B ) ; double matrixDelta = deltaMatrices ( B , oldB ) ; if ( matrixDelta < epsilon ) { break ; } } double [ ] [ ] sepMatrix = Matrix . mult ( B , whiteningMatrix ) ; return Matrix . mult ( sepMatrix , input ) ; }
finds a certain number of independent components of the input signal using fastica
