int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){

    int i, j, k, pass;

    const int n= pca->n;

    double z[n];



    memset(eigenvector, 0, sizeof(double)*n*n);



    for(j=0; j<n; j++){

        pca->mean[j] /= pca->count;

        eigenvector[j + j*n] = 1.0;

        for(i=0; i<=j; i++){

            pca->covariance[j + i*n] /= pca->count;

            pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j];

            pca->covariance[i + j*n] = pca->covariance[j + i*n];

        }

        eigenvalue[j]= pca->covariance[j + j*n];

        z[j]= 0;

    }



    for(pass=0; pass < 50; pass++){

        double sum=0;



        for(i=0; i<n; i++)

            for(j=i+1; j<n; j++)

                sum += fabs(pca->covariance[j + i*n]);



        if(sum == 0){

            for(i=0; i<n; i++){

                double maxvalue= -1;

                for(j=i; j<n; j++){

                    if(eigenvalue[j] > maxvalue){

                        maxvalue= eigenvalue[j];

                        k= j;

                    }

                }

                eigenvalue[k]= eigenvalue[i];

                eigenvalue[i]= maxvalue;

                for(j=0; j<n; j++){

                    double tmp= eigenvector[k + j*n];

                    eigenvector[k + j*n]= eigenvector[i + j*n];

                    eigenvector[i + j*n]= tmp;

                }

            }

            return pass;

        }



        for(i=0; i<n; i++){

            for(j=i+1; j<n; j++){

                double covar= pca->covariance[j + i*n];

                double t,c,s,tau,theta, h;



                if(pass < 3 && fabs(covar) < sum / (5*n*n)) //FIXME why pass < 3

                    continue;

                if(fabs(covar) == 0.0) //FIXME shouldnt be needed

                    continue;

                if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){

                    pca->covariance[j + i*n]=0.0;

                    continue;

                }



                h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]);

                theta=0.5*h/covar;

                t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));

                if(theta < 0.0) t = -t;



                c=1.0/sqrt(1+t*t);

                s=t*c;

                tau=s/(1.0+c);

                z[i] -= t*covar;

                z[j] += t*covar;



#define ROTATE(a,i,j,k,l) {\

    double g=a[j + i*n];\

    double h=a[l + k*n];\

    a[j + i*n]=g-s*(h+g*tau);\

    a[l + k*n]=h+s*(g-h*tau); }

                for(k=0; k<n; k++) {

                    if(k!=i && k!=j){

                        ROTATE(pca->covariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j))

                    }

                    ROTATE(eigenvector,k,i,k,j)

                }

                pca->covariance[j + i*n]=0.0;

            }

        }

        for (i=0; i<n; i++) {

            eigenvalue[i] += z[i];

            z[i]=0.0;

        }

    }



    return -1;

}

int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){

    int i, j, k, pass;

    const int n= pca->n;

    double z[n];



    memset(eigenvector, 0, sizeof(double)*n*n);



    for(j=0; j<n; j++){

        pca->mean[j] /= pca->count;

        eigenvector[j + j*n] = 1.0;

        for(i=0; i<=j; i++){

            pca->covariance[j + i*n] /= pca->count;

            pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j];

            pca->covariance[i + j*n] = pca->covariance[j + i*n];

        }

        eigenvalue[j]= pca->covariance[j + j*n];

        z[j]= 0;

    }



    for(pass=0; pass < 50; pass++){

        double sum=0;



        for(i=0; i<n; i++)

            for(j=i+1; j<n; j++)

                sum += fabs(pca->covariance[j + i*n]);



        if(sum == 0){

            for(i=0; i<n; i++){

                double maxvalue= -1;

                for(j=i; j<n; j++){

                    if(eigenvalue[j] > maxvalue){

                        maxvalue= eigenvalue[j];

                        k= j;

                    }

                }

                eigenvalue[k]= eigenvalue[i];

                eigenvalue[i]= maxvalue;

                for(j=0; j<n; j++){

                    double tmp= eigenvector[k + j*n];

                    eigenvector[k + j*n]= eigenvector[i + j*n];

                    eigenvector[i + j*n]= tmp;

                }

            }

            return pass;

        }



        for(i=0; i<n; i++){

            for(j=i+1; j<n; j++){

                double covar= pca->covariance[j + i*n];

                double t,c,s,tau,theta, h;



                if(pass < 3 && fabs(covar) < sum / (5*n*n)) 

                    continue;

                if(fabs(covar) == 0.0) 

                    continue;

                if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){

                    pca->covariance[j + i*n]=0.0;

                    continue;

                }



                h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]);

                theta=0.5*h/covar;

                t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));

                if(theta < 0.0) t = -t;



                c=1.0/sqrt(1+t*t);

                s=t*c;

                tau=s/(1.0+c);

                z[i] -= t*covar;

                z[j] += t*covar;



#define ROTATE(a,i,j,k,l) {\

    double g=a[j + i*n];\

    double h=a[l + k*n];\

    a[j + i*n]=g-s*(h+g*tau);\

    a[l + k*n]=h+s*(g-h*tau); }

                for(k=0; k<n; k++) {

                    if(k!=i && k!=j){

                        ROTATE(pca->covariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j))

                    }

                    ROTATE(eigenvector,k,i,k,j)

                }

                pca->covariance[j + i*n]=0.0;

            }

        }

        for (i=0; i<n; i++) {

            eigenvalue[i] += z[i];

            z[i]=0.0;

        }

    }



    return -1;

}

    int i, j, k, pass;
int FUNC_0(PCA *VAR_0, double *VAR_1, double *VAR_2){

    int VAR_3, VAR_4, VAR_5, VAR_6;

    const int VAR_7= VAR_0->VAR_7;

    double VAR_8[VAR_7];



    memset(VAR_1, 0, sizeof(double)*VAR_7*VAR_7);



    for(VAR_4=0; VAR_4<VAR_7; VAR_4++){

        VAR_0->mean[VAR_4] /= VAR_0->count;

        VAR_1[VAR_4 + VAR_4*VAR_7] = 1.0;

        for(VAR_3=0; VAR_3<=VAR_4; VAR_3++){

            VAR_0->covariance[VAR_4 + VAR_3*VAR_7] /= VAR_0->count;

            VAR_0->covariance[VAR_4 + VAR_3*VAR_7] -= VAR_0->mean[VAR_3] * VAR_0->mean[VAR_4];

            VAR_0->covariance[VAR_3 + VAR_4*VAR_7] = VAR_0->covariance[VAR_4 + VAR_3*VAR_7];

        }

        VAR_2[VAR_4]= VAR_0->covariance[VAR_4 + VAR_4*VAR_7];

        VAR_8[VAR_4]= 0;

    }



    for(VAR_6=0; VAR_6 < 50; VAR_6++){

        double VAR_9=0;



        for(VAR_3=0; VAR_3<VAR_7; VAR_3++)

            for(VAR_4=VAR_3+1; VAR_4<VAR_7; VAR_4++)

                VAR_9 += fabs(VAR_0->covariance[VAR_4 + VAR_3*VAR_7]);



        if(VAR_9 == 0){

            for(VAR_3=0; VAR_3<VAR_7; VAR_3++){

                double VAR_10= -1;

                for(VAR_4=VAR_3; VAR_4<VAR_7; VAR_4++){

                    if(VAR_2[VAR_4] > VAR_10){

                        VAR_10= VAR_2[VAR_4];

                        VAR_5= VAR_4;

                    }

                }

                VAR_2[VAR_5]= VAR_2[VAR_3];

                VAR_2[VAR_3]= VAR_10;

                for(VAR_4=0; VAR_4<VAR_7; VAR_4++){

                    double VAR_11= VAR_1[VAR_5 + VAR_4*VAR_7];

                    VAR_1[VAR_5 + VAR_4*VAR_7]= VAR_1[VAR_3 + VAR_4*VAR_7];

                    VAR_1[VAR_3 + VAR_4*VAR_7]= VAR_11;

                }

            }

            return VAR_6;

        }



        for(VAR_3=0; VAR_3<VAR_7; VAR_3++){

            for(VAR_4=VAR_3+1; VAR_4<VAR_7; VAR_4++){

                double VAR_12= VAR_0->covariance[VAR_4 + VAR_3*VAR_7];

                double VAR_13,VAR_14,VAR_15,VAR_16,VAR_17, VAR_20;



                if(VAR_6 < 3 && fabs(VAR_12) < VAR_9 / (5*VAR_7*VAR_7)) 

                    continue;

                if(fabs(VAR_12) == 0.0) 

                    continue;

                if(VAR_6 >=3 && fabs((VAR_2[VAR_4]+VAR_8[VAR_4])/VAR_12) > (1LL<<32) && fabs((VAR_2[VAR_3]+VAR_8[VAR_3])/VAR_12) > (1LL<<32)){

                    VAR_0->covariance[VAR_4 + VAR_3*VAR_7]=0.0;

                    continue;

                }



                VAR_20= (VAR_2[VAR_4]+VAR_8[VAR_4]) - (VAR_2[VAR_3]+VAR_8[VAR_3]);

                VAR_17=0.5*VAR_20/VAR_12;

                VAR_13=1.0/(fabs(VAR_17)+sqrt(1.0+VAR_17*VAR_17));

                if(VAR_17 < 0.0) VAR_13 = -VAR_13;



                VAR_14=1.0/sqrt(1+VAR_13*VAR_13);

                VAR_15=VAR_13*VAR_14;

                VAR_16=VAR_15/(1.0+VAR_14);

                VAR_8[VAR_3] -= VAR_13*VAR_12;

                VAR_8[VAR_4] += VAR_13*VAR_12;



#define ROTATE(a,VAR_3,VAR_4,VAR_5,l) {\

    double VAR_19=a[VAR_4 + VAR_3*VAR_7];\

    double VAR_20=a[l + VAR_5*VAR_7];\

    a[VAR_4 + VAR_3*VAR_7]=VAR_19-VAR_15*(VAR_20+VAR_19*VAR_16);\

    a[l + VAR_5*VAR_7]=VAR_20+VAR_15*(VAR_19-VAR_20*VAR_16); }

                for(VAR_5=0; VAR_5<VAR_7; VAR_5++) {

                    if(VAR_5!=VAR_3 && VAR_5!=VAR_4){

                        ROTATE(VAR_0->covariance,FFMIN(VAR_5,VAR_3),FFMAX(VAR_5,VAR_3),FFMIN(VAR_5,VAR_4),FFMAX(VAR_5,VAR_4))

                    }

                    ROTATE(VAR_1,VAR_5,VAR_3,VAR_5,VAR_4)

                }

                VAR_0->covariance[VAR_4 + VAR_3*VAR_7]=0.0;

            }

        }

        for (VAR_3=0; VAR_3<VAR_7; VAR_3++) {

            VAR_2[VAR_3] += VAR_8[VAR_3];

            VAR_8[VAR_3]=0.0;

        }

    }



    return -1;

}

int FUNC_0(PCA *VAR_0, double *VAR_1, double *VAR_2){ int VAR_3, VAR_4, VAR_5, VAR_6; const int VAR_7= VAR_0->VAR_7; double VAR_8[VAR_7]; memset(VAR_1, 0, sizeof(double)*VAR_7*VAR_7); for(VAR_4=0; VAR_4<VAR_7; VAR_4++){ VAR_0->mean[VAR_4] /= VAR_0->count; VAR_1[VAR_4 + VAR_4*VAR_7] = 1.0; for(VAR_3=0; VAR_3<=VAR_4; VAR_3++){ VAR_0->covariance[VAR_4 + VAR_3*VAR_7] /= VAR_0->count; VAR_0->covariance[VAR_4 + VAR_3*VAR_7] -= VAR_0->mean[VAR_3] * VAR_0->mean[VAR_4]; VAR_0->covariance[VAR_3 + VAR_4*VAR_7] = VAR_0->covariance[VAR_4 + VAR_3*VAR_7]; } VAR_2[VAR_4]= VAR_0->covariance[VAR_4 + VAR_4*VAR_7]; VAR_8[VAR_4]= 0; } for(VAR_6=0; VAR_6 < 50; VAR_6++){ double VAR_9=0; for(VAR_3=0; VAR_3<VAR_7; VAR_3++) for(VAR_4=VAR_3+1; VAR_4<VAR_7; VAR_4++) VAR_9 += fabs(VAR_0->covariance[VAR_4 + VAR_3*VAR_7]); if(VAR_9 == 0){ for(VAR_3=0; VAR_3<VAR_7; VAR_3++){ double VAR_10= -1; for(VAR_4=VAR_3; VAR_4<VAR_7; VAR_4++){ if(VAR_2[VAR_4] > VAR_10){ VAR_10= VAR_2[VAR_4]; VAR_5= VAR_4; } } VAR_2[VAR_5]= VAR_2[VAR_3]; VAR_2[VAR_3]= VAR_10; for(VAR_4=0; VAR_4<VAR_7; VAR_4++){ double VAR_11= VAR_1[VAR_5 + VAR_4*VAR_7]; VAR_1[VAR_5 + VAR_4*VAR_7]= VAR_1[VAR_3 + VAR_4*VAR_7]; VAR_1[VAR_3 + VAR_4*VAR_7]= VAR_11; } } return VAR_6; } for(VAR_3=0; VAR_3<VAR_7; VAR_3++){ for(VAR_4=VAR_3+1; VAR_4<VAR_7; VAR_4++){ double VAR_12= VAR_0->covariance[VAR_4 + VAR_3*VAR_7]; double VAR_13,VAR_14,VAR_15,VAR_16,VAR_17, VAR_20; if(VAR_6 < 3 && fabs(VAR_12) < VAR_9 / (5*VAR_7*VAR_7))
continue; if(fabs(VAR_12) == 0.0)
continue; if(VAR_6 >=3 && fabs((VAR_2[VAR_4]+VAR_8[VAR_4])/VAR_12) > (1LL<<32) && fabs((VAR_2[VAR_3]+VAR_8[VAR_3])/VAR_12) > (1LL<<32)){ VAR_0->covariance[VAR_4 + VAR_3*VAR_7]=0.0; continue; } VAR_20= (VAR_2[VAR_4]+VAR_8[VAR_4]) - (VAR_2[VAR_3]+VAR_8[VAR_3]); VAR_17=0.5*VAR_20/VAR_12; VAR_13=1.0/(fabs(VAR_17)+sqrt(1.0+VAR_17*VAR_17)); if(VAR_17 < 0.0) VAR_13 = -VAR_13; VAR_14=1.0/sqrt(1+VAR_13*VAR_13); VAR_15=VAR_13*VAR_14; VAR_16=VAR_15/(1.0+VAR_14); VAR_8[VAR_3] -= VAR_13*VAR_12; VAR_8[VAR_4] += VAR_13*VAR_12; #define ROTATE(a,VAR_3,VAR_4,VAR_5,l) {\ double VAR_19=a[VAR_4 + VAR_3*VAR_7];\ double VAR_20=a[l + VAR_5*VAR_7];\ a[VAR_4 + VAR_3*VAR_7]=VAR_19-VAR_15*(VAR_20+VAR_19*VAR_16);\ a[l + VAR_5*VAR_7]=VAR_20+VAR_15*(VAR_19-VAR_20*VAR_16); } for(VAR_5=0; VAR_5<VAR_7; VAR_5++) { if(VAR_5!=VAR_3 && VAR_5!=VAR_4){ ROTATE(VAR_0->covariance,FFMIN(VAR_5,VAR_3),FFMAX(VAR_5,VAR_3),FFMIN(VAR_5,VAR_4),FFMAX(VAR_5,VAR_4))
} ROTATE(VAR_1,VAR_5,VAR_3,VAR_5,VAR_4)
} VAR_0->covariance[VAR_4 + VAR_3*VAR_7]=0.0; } } for (VAR_3=0; VAR_3<VAR_7; VAR_3++) { VAR_2[VAR_3] += VAR_8[VAR_3]; VAR_8[VAR_3]=0.0; } } return -1; }