int main(int argc, char *argv[])
{
  Arguments args;
  Subspace subspace;
  char fname [255], label [255];

  MESSAGE (OPENING);
  MESSAGE (VERSION);
  
  process_command(argc, argv, &args);

  MESSAGE1ARG ("Reading subspace %s", args.trainingFile);
  readSubspace (&subspace, args.trainingFile, quiet);

  /* Save out the mean */

  strcpy (label, args.trainingFile);
  strcat (label, "_mean");
  strcpy (fname, label);
  strcat (fname, ".txt");
  MESSAGE1ARG ("Saving mean to %s", fname);
  saveMatrixAscii (fname, label, subspace.mean, args.mode);

  /* Save out the values */

  strcpy (label, args.trainingFile);
  strcat (label, "_values");
  strcpy (fname, label);
  strcat (fname, ".txt");
  MESSAGE1ARG ("Saving values to %s", fname);
  saveMatrixAscii (fname, label, subspace.values, args.mode);

  /* Save out the basis */

  strcpy (label, args.trainingFile);
  strcat (label, "_basis");
  strcpy (fname, label);
  strcat (fname, ".txt");
  MESSAGE1ARG ("Saving basis to %s", fname);
  saveMatrixAscii (fname, label, subspace.basis, args.mode);

  return 0;
}
Пример #2
0
/*
  main()
*/
int
main(int argc, char *argv[])
{
  Arguments args;
  int numImages, numSubjects;
  ImageList *srt;
  Matrix images;
  Subspace subspace;
    
  process_command(argc, argv, &args);

  MESSAGE(OPENING);
  MESSAGE(VERSION);

  /* The Matrix images is contains what is commonly calld the data matrix. It
     consists of n images, one image per column. Hence, each images data is 
     contiguous in memory. This choice facilities easy integration with the 
     Eigensolver used below */

  MESSAGE1ARG("Reading images from files in directory %s.", args.imageDirectory);

  images = readImages(args.imageList, args.imageDirectory, &args.vecLength,
		      &numImages, &numSubjects, &srt);
  
  subspaceTrain (&subspace, images, srt, numSubjects, args.dropNVectors, args.cutOffMode, args.cutOff, args.uselda, args.writeTextInterm);

  /* Write out text files for basis and values */
  if (args.writeTextBasis)
    {
      SAVE_MATRIX (subspace.basis);
      SAVE_MATRIX (subspace.mean);
      
      SAVE_MATRIX (subspace.values);
    }

  writeSubspace (&subspace, args.training_filename, args.imageList, args.argc, args.argv);
  
  MESSAGE("Finished Training.");
  
  return 0;
}
void convertImages(Arguments* args){
    FILE* list;
    JetMasks masks;
    int x, y,i,j;
    char imagename[MAX_FILENAME_LENGTH];
    char filename[MAX_FILENAME_LENGTH];
    
    MESSAGE("Creating gabor masks.");
    masks = readMasksFile(args->maskFile);

    if(args->saveMasks){
        for(y = 0; y < masks->size; y++){
            char outname[MAX_FILENAME_LENGTH];
            sprintf(outname, "mask%03d.pgm",y);
            writePGMImage(masks->masks[y],outname,0);
        }
    }

       
    list = fopen(args->imageList,"r");
    if(!list){
        printf("Error opening file: %s\n", args->imageList);
        exit(1);
    }

    while(fscanf(list, "%s", imagename) == 1){
        Image im;
        Image grid;
        
        sprintf(filename, "%s/%s", args->inputDir, imagename);
        im = readRawImage(filename);
        MESSAGE1ARG("Processing file: %s",filename);

        /* Find the number of points in the grid */
        
        i = 0;
        for( x = args->gridStartX; x < im->width; x += args->gridSpaceX){
            for( y = args->gridStartY; y < im->height; y+= args->gridSpaceY){
                i++;
            }
        }
        
        grid = makeImage(i,masks->size,1);

        /* Compute convolutions */
        i = 0;
        for( x = args->gridStartX; x < im->width; x += args->gridSpaceX){
            for( y = args->gridStartY; y < im->height; y+= args->gridSpaceY){
                for(j = 0; j < masks->size; j++){
                    if( i < grid->width )
                        IE(grid,i,j,0) = convolvePoint(x, y, 0, im, masks->masks[j]);
                }
                i++;
            }
            
        }

        sprintf(filename, "%s/%s", args->sfiDir, imagename);
        writeRawImage(grid,filename);

        freeImage(grid);
        freeImage(im);

    }

    
    fclose(list);
   
}
Пример #4
0
GraphDiscription buildBunchGraph(GraphDiscription modelJets, JetSimilarityMeasure jetSim, int bunchsize){
    int vert;

    assert(bunchsize > 1);
    for(vert = 0; vert < modelJets->numVert; vert++){
        Matrix dist;
        int size, i, j;
        FTYPE maxsim, minsim, smallest;
        int minjet;
        JetBunch finalBunch = makeJetBunch();

        MESSAGE1ARG("Selecting jets for point: %s",modelJets->vertLabels[vert]);

        size = modelJets->bunch[vert]->size;
        assert(bunchsize <= size);
        assert(size > 0);

        dist = makeZeroMatrix(size, size);

        smallest = maxsim = jetSim(modelJets->bunch[vert]->jets[0],modelJets->bunch[vert]->jets[0]);
        for(i = 0; i < size; i++){
            for(j = 0; j < size; j++){
                ME(dist,i,j) = jetSim(modelJets->bunch[vert]->jets[i],modelJets->bunch[vert]->jets[j]);
                maxsim = MAX( maxsim, ME(dist,i,j) );
                smallest = MIN(smallest, ME(dist,i,j));
            }
        }

        /* find the minimum similarity */
        minsim = 0.0;
        minjet = -1;
        for(i = 0; i < size; i++){
            for(j = 0; j < size; j++){
                if(minjet < 0 || minsim > ME(dist,i,j) ){
                    minsim = ME(dist,i,j);
                    minjet = i;
                }
            }
        }

        while(1){
            /* MESSAGE2ARG("    Adding jet %03d to final bunch. sim=%+f",minjet,minsim); */
            /* add that jet to the final bunch */
            addJetToBunch(finalBunch, modelJets->bunch[vert]->jets[minjet]);
            /* eleminate the newly added jet from the old bunch and the distance matrix */
            modelJets->bunch[vert]->jets[minjet] = NULL;
            for( i = 0; i < size; i++){
                /* Make sure new value is greater that the maximum similarity */
                ME(dist,i,minjet) = 2*ABS(maxsim);
            }

            if(finalBunch->size >= bunchsize) break;

            minsim = 0.0;
            minjet = -1;
            for(j = 0; j < size; j++){
                FTYPE locmax = smallest;
                for(i = 0; i < size; i++){
                    /* compute the best similarity to the jets in the data set */
                    if(modelJets->bunch[vert]->jets[i] == NULL){
                        locmax = MAX(locmax,ME(dist,i,j));
                    }
                }
                if(minjet < 0 || minsim > locmax ){
                    minsim = locmax;
                    minjet = j;
                }
            }
        }

        freeJetBunch(modelJets->bunch[vert]);
        modelJets->bunch[vert] = finalBunch;
        freeMatrix(dist);
    }
    return modelJets;
}
Пример #5
0
void convertImages(Arguments* args){
    char** mask = NULL;
    TwoPoints source, dest;
    FILE* eyeList;
    char line[ FILE_LINE_LENGTH ];
    char filename[MAX_FILENAME_LENGTH];
    char imagename[MAX_FILENAME_LENGTH];
    char suffix[MAX_FILENAME_LENGTH];
    int i;

    scaleArgs(args, args->scale);

    dest.x1 = args->eyeLx;
    dest.y1 = args->eyeLy;
    dest.x2 = args->eyeRx;
    dest.y2 = args->eyeRy;

    /* Prepare file suffix encoding preprocessing settings, blank if not requested */
    if (args->configSuffix) {
        sprintf(suffix,"_%s", imageSuffix(args)); }
    else {
        suffix[0] = '\0'; }	

    if(args->maskType == CL_YES){
        MESSAGE("Creating Mask.");
        mask = generateMask(args->sizeWidth, args->sizeHeight, args->ellipseX, args->ellipseY, args->ellipseA, args->ellipseB);
    }

    eyeList = fopen(args->eyeFile,"r");
    DEBUG_CHECK(eyeList,"Error opening eye coordinates file");

    for(i = 1;;i++){
        Image pgm;
        Image geo;
        Matrix transform;

        fgets(line, FILE_LINE_LENGTH, eyeList);
        if(feof(eyeList)) break;

        if(sscanf(line,"%s %lf %lf %lf %lf",filename, &(source.x1), &(source.y1), &(source.x2), &(source.y2)) != 5){
            printf("Error parsing line %d of eye coordinate file. Exiting...",i);
            exit(1);
        }

        /* shift the eye coordinates if neccessary */
        source.x1 += args->shiftX;
        source.y1 += args->shiftY;
        source.x2 += args->shiftX;
        source.y2 += args->shiftY;

        sprintf(imagename,"%s\\%s.pgm",args->inputDir,filename);

        MESSAGE1ARG("Processing image: %s",filename);

        pgm = readPGMImage(imagename);

        if(args->histType == HIST_PRE){
            DEBUG(1,"   Performing Pre Histogram Equalization.");
            histEqual(pgm,256);
        }

        if(args->preNormType == CL_YES){
            DEBUG(1,"   Performing Pre Pixel Normalization.");
            ZeroMeanOneStdDev(pgm);
        }

        if(args->preEdge){
            smoothImageEdge(pgm, args->preEdge);
        }

        if(args->geoType == CL_YES){
            DEBUG(1,"   Performing Geometric Normalization.");
            transform = generateTransform(&source,&dest,args->reflect);
            geo = transformImage(pgm,args->sizeWidth,args->sizeHeight,transform);
        }
        else{
            transform = makeIdentityMatrix(3);
            geo = transformImage(pgm,args->sizeWidth,args->sizeHeight,transform);
        }

        if(args->noise != 0.0){
            DEBUG(1,"   Adding Gausian Noise.");
            gaussianNoise(geo,args->noise);
        }


        if(args->histType == HIST_POST){
            DEBUG(1,"   Performing Post Histogram Equalization.");
            histEqualMask(geo,256, (const char**) mask);
        }

        if(args->nrmType == CL_YES){
            DEBUG(1,"   Performing final value normalization and Applying Mask.");
            ZeroMeanOneStdDevMasked(geo, (const char **) mask);
        }
        else{
            DEBUG(1,"   No Value Normalization. Just Applying Mask.");
            applyMask(geo, (const char **) mask);
        }

        if(args->postEdge){
            smoothImageEdge(geo, args->postEdge);
        }

        if(args->nrmDir){
            sprintf(imagename,"%s\\%s%s.nrm", args->nrmDir, filename, suffix);
            DEBUG_STRING(1,"   Saving nrm: %s",imagename);
            writeFeretImage(geo,imagename);
        }
        if(args->pgmDir){
            sprintf(imagename,"%s\\%s%s.pgm", args->pgmDir, filename, suffix);
            DEBUG_STRING(1,"   Saving pgm: %s",imagename);
            writePGMImage(geo,imagename,0);
        }
        if(args->sfiDir){
            sprintf(imagename,"%s\\%s%s.sfi", args->sfiDir, filename, suffix);
            DEBUG_STRING(1,"   Saving sfi: %s",imagename);
            writeRawImage(geo,imagename);
        }

        freeImage(geo);
        freeImage(pgm);
        freeMatrix(transform);
    }

    fclose(eyeList);

}
int main(int argc, char** argv) {
    ImageList *imagenames, *subject, *replicate;
    int imageCount;
    Matrix distance;
    FaceGraph* graphs;
    char** names;
    int i, j;
    Arguments args;
    DistDirNode* distrec;

    processCommand(argc, argv, &args);

    MESSAGE("Reading in image names");
    imagenames = getImageNames(args.imageNamesFile, &imageCount);

    MESSAGE1ARG("Reading in graph files %d",imageCount);

    /* Allocate space for imagenames, face graphs and distance matrix */
    names = ALLOCATE(char*,imageCount);
    graphs = ALLOCATE(FaceGraph, imageCount);
    distance = makeZeroMatrix(imageCount,imageCount);


    MESSAGE("Reading in graph files");
    i = 0;
    for(subject = imagenames; subject != NULL; subject = subject->next_subject) {
        for( replicate = subject; replicate != NULL; replicate = replicate->next_replicate) {
            printf("Reading in graph: %s\n", replicate->filename);
            fflush(stdout);
            names[i] = strdup(replicate->filename);
            graphs[i] = loadFaceGraph(makePath(args.faceGraphDir,replicate->filename));
            i++;
        }
    }

    for(distrec = args.distList; distrec != NULL; distrec = distrec->next) {
        /* Create distance matrix */
        completed = 0;
        total = imageCount*imageCount;

        MESSAGE("Computing Distance Matrix");
        start_time = time(NULL);

        computeDistanceMatrix(distance, graphs, 0, imageCount, 0, imageCount, distrec->distMeasure);

        /* Print out distance files to the distance directory */
        for(i = 0; i < imageCount; i++) {
            FILE* distfile = fopen(makePath(distrec->distDirectory,names[i]), "w");

            if(!distfile) {
                printf("Error opening distance file: %s\n",makePath(distrec->distDirectory,names[i]));
                exit(1);
            }

            printf("Saving distances for image: %s\n",names[i]);
            fflush(stdout);

            for(j = 0; j < imageCount; j++) {
                fprintf(distfile,"%s\t%16e\n",names[j], ME(distance,i,j));
            }
            fclose(distfile);
        }
    }

    return 0;
}
Пример #7
0
void
subspaceTrain (Subspace *s, Matrix images, ImageList *srt, int numSubjects, int dropNVectors, CutOffMode cutOffMode, double cutOff, int useLDA, int writeTextInterm
               /*START Changed by Zeeshan: For LPP*/
               ,int useLPP, int neighbourCount, int useAdaptiveK, int lppKeepNVectors, char* lppDistance
               /*END Changed by Zeeshan: For LPP*/
               /*START 	Changed by Zeeshan: For ICA*/
               ,int useICA, int arch, double learningRate, int blockSize, int iterations
               /*END 	Changed by Zeeshan: For ICA*/
               )
{
    int i;
    Matrix m;
    int n = 0;    /* The number of eigen vectors to keep */
    double total_energy, energy;
    Matrix tmp;

    /* Initialize structure */

    s->useLDA         = useLDA;
    s->cutOffMode     = cutOffMode;
    s->cutOff         = cutOff;
    s->dropNVectors   = dropNVectors;

    s->numSubjects    = numSubjects;
    s->numPixels      = images->row_dim;

    /*START Changed by Zeeshan: For LPP*/
    s->useLPP 	    = useLPP;
    s->neighbourCount = neighbourCount;
    s->lppDistance    = strdup(lppDistance);
    s->lppKeepNVectors= lppKeepNVectors;
    s->useAdaptiveK   = useAdaptiveK;
    /*END Changed by Zeeshan: For LPP*/

    /*START Changed by Zeeshan: For ICA*/
    s->useICA 	    = useICA;
    s->arch	    = arch;
    s->ica2Basis 	    = NULL;
    s->learningRate   = learningRate;
    s->blockSize 	    = blockSize;
    s->iterations     = iterations;
    /*END Changed by Zeeshan: For ICA*/

    /*START Changed by Zeeshan: For ICA & LPP*/
    /*********************************************************************
    * STEP ZERO: Make sure LDA and LPP are executed exclusively
    ********************************************************************/
    DEBUG_CHECK (!(s->useLDA && s->useLPP) && !(s->useLDA && s->useICA) && !(s->useICA && s->useLPP), 
        "Either LDA, LPP or ICA should be executed.");
    /*END Changed by Zeeshan: For ICA & LPP*/


    /*********************************************************************
    * STEP ONE: Calculate the eigenbasis
    ********************************************************************/

    /* Compute the Eigenvalues and Eigenvectors for the covariance matrix
    derived from the images data matrix. The image data is "centered", meaning
    the mean image is subtracted from all images before PCA is performed.
    This centering is done in place, so after this call images are centered. */

    MESSAGE("Computing the PCA eigenspace.");

    eigentrain (&s->mean, &s->values, &s->basis, images);

    MESSAGE("Finished computing eigenspace.");

    /* Numerical roundoff errors may lead to small negative values.
    Strip those before saving the matrix. */

    m = s->values;
    for (i = 0; i < m->row_dim; i++)
    {
        if (ME(m,i,0) < 0) {
            if (ME(m,i,0) < -1e-10)
                printf("WARNING: Large negative eigenvalue found %f. Truncating to zero.\n", ME(m,i,0));
            ME(m,i,0) = 0;
        }
    }

    /*********************************************************************
    * STEP TWO: Drop eigenvectors from the front or truncate them from
    * the back
    ********************************************************************/

    /* 
    The following is used to filter the vectors that are retained after PCA
    training.  The function first optionally removes the vectors from the matrix
    based on the argument -dropNVectors. This argument is always intrepreted in
    terms of absolute numbers, i.e. a value of 1 means drop the first vector, a
    value of 3 means drop the first three. The function then drops vectors from the
    tail based on -cutOffMode and -cutOff arguments. Here, the mode controls how the
    cutoff is performed. The possible modes are:

    NONE:    Keep all remaining eigenvectors.
    SIMPLE:  Keep a percentage where the percentage is specified by cutOff.
    ENERGY:  Keep the fewest vectors are such that the sum of energy for them just
    exceeds cutOff times the total energy. 
    STRETCH: Keep all eigenvectors that have eigenvalues greater than a percentage 
    of the largest, where the percentage is specied by cutOff. 
    CLASSES: Keep as many eigenvectors as there are LDA classes.

    For both Energy and Stretch, if eigen values/vectors are dropped from the front, 
    these are not included in the determination of the total energy or the max
    eigen value. 
    */

    /* Drop the first vectors  */

    DEBUG_CHECK (s->dropNVectors < (s->basis)->col_dim, "Number of vectors to drop must be less than the number of the eigen vectors");

    /* transpose eigenValues for use in this function */

    tmp = transposeMatrix (s->values);
    freeMatrix (s->values);
    s->values = tmp;

    if (s->dropNVectors && (s->dropNVectors < (s->values)->col_dim))
    {
        tmp = matrixCols (s->basis, s->dropNVectors, (s->basis)->col_dim-1);
        freeMatrix (s->basis);
        s->basis = tmp;

        tmp = matrixCols (s->values, s->dropNVectors, (s->values)->col_dim-1);
        freeMatrix (s->values);
        s->values = tmp;
    }

    /* transpose the eigenValues back to the original order. */

    tmp = transposeMatrix (s->values);
    freeMatrix (s->values);
    s->values = tmp;

    DEBUG_CHECK((s->values)->row_dim - s->dropNVectors > 0, "Too many eigen vectors droped from front. Can not proceed.");

    switch (s->cutOffMode)
    {
    case CUTOFF_NONE:
        n = (s->basis)->col_dim;
        break;

    case CUTOFF_SIMPLE:
        n = (int)((s->basis)->col_dim * s->cutOff / 100.0);
        break;

    case CUTOFF_ENERGY:
        /* compute total energy - this will not include vectors/values dropped from front. */
        total_energy = 0;
        for (i = 0; i < (s->values)->row_dim; i++) {
            total_energy += ME(s->values, i, 0);
        }

        /* compute cutoff point */
        i = 0;
        energy = 0;
        while ((i < (s->values)->row_dim) && (energy < total_energy * s->cutOff / 100.0)) {
            energy += ME(s->values, i, 0);
            i++;
        }
        n = i;
        break;

    case CUTOFF_STRETCH:
        i = 1;
        while ((i < (s->values)->row_dim) &&
            (100.0*(ME(s->values, i, 0) / ME(s->values, s->dropNVectors, 0)) > cutOff )) {
                i++;
        }
        n = i;
        break;

    case CUTOFF_CLASSES:
        n = s->numSubjects;
        break;

    case CUTOFF_DROPVEC:
        n = (int)((s->basis)->col_dim - s->cutOff);
        break;

    default:
        n = 0;
        DEBUG_CHECK (0, "ERROR: Unkown cutoff type");
        break;
    };

    /* Never set the dimensionality of the PCA subspace below the number of
    LDA classes when LDA is being used. Doing so creates a horrible problem
    for LDA: too fee dimensions */

    if (s->useLDA && (n < s->numSubjects))
        n = s->numSubjects;

    DEBUG_CHECK (n <= (s->basis)->col_dim, "Tried to expand, not contract, PCA space.");

    MESSAGE1ARG ("Retaining %d eigen vectors.",n);

    tmp = matrixCols ( s->basis, 0 , n-1);
    freeMatrix (s->basis);
    s->basis = tmp;

    DEBUG_INT (1, "Number of eigen vectors kept.", n);

    DEBUG_CHECK ((s->basis)->col_dim > 0, "All basis vectors deleted after cutoff "
        "and vector drop was processed.");

    MESSAGE2ARG("Truncating PCA Space. Subspace projection expressed "
        "as %d by %d matrix.", s->basis->row_dim, s->basis->col_dim);

    /*********************************************************************
    * STEP THREE: Do the LDA if specified
    ********************************************************************/

    if (s->useLDA)
    {
        /* Need to project original images into PCA space */

        Matrix fisherBasis, fisherValues, combinedBasis;
        Matrix imspca = transposeMultiplyMatrixL (s->basis, images);

        MESSAGE("Computing Fisher Linear Discriminants for "
            "training images projected into PCA subspace.");

        fisherTrain (imspca, srt, &fisherBasis, &fisherValues, writeTextInterm);

        combinedBasis = multiplyMatrix (s->basis, fisherBasis);
        basis_normalize (combinedBasis);

        MESSAGE2ARG ("PCA and LDA Combined. Combined projection expressed as %d by "
            "%d matrix.", combinedBasis->row_dim, combinedBasis->col_dim);

        s->values = fisherValues;
        s->basis  = combinedBasis;
    }

    /*START Changed by Zeeshan: For LPP*/
    /*********************************************************************
    * STEP FOUR: Do the LPP if specified
    ********************************************************************/
    if (s->useLPP)
    {
        /* Need to project original images into PCA space */

        Matrix laplacianBasis, laplacianValues, combinedBasis;
        Matrix imspca = transposeMultiplyMatrixL (s->basis, images);           

        MESSAGE("Computing Locality Preservation Projections for "
            "training images projected into PCA subspace.");

        laplacianTrain (imspca, srt, &laplacianBasis, &laplacianValues, neighbourCount, 
            useAdaptiveK, lppKeepNVectors, &s->values, lppDistance, writeTextInterm);

        combinedBasis = multiplyMatrix (s->basis, laplacianBasis);
        basis_normalize (combinedBasis);

        MESSAGE2ARG ("PCA and LPP Combined. Combined projection expressed as %d by "
            "%d matrix.", combinedBasis->row_dim, combinedBasis->col_dim);

        s->values = calculateStandardDeviation (laplacianBasis);//OPTION4
        //s->values = laplacianValues;//OPTION2
        s->basis  = combinedBasis;

        for (i = 0; i < s->values->row_dim; i++)
        {
            if (ME(s->values, i, 0) <= 0.001)
            {
                if (ME(s->values, i, 0) < -1e-10)
                    printf("WARNING: Large negative value found %f. Truncating to zero.\n", ME(s->values, i, 0));
                ME(s->values, i, 0) = 0.001;
            }
        }


    }
    /*END Changed by Zeeshan: For LPP*/


    /*START Changed by Zeeshan: For ICA*/
    /*********************************************************************
    * STEP FIVE: Do the ICA if specified
    ********************************************************************/
    if (s->useICA)
    {
        /* Need to project original images into PCA space */
        Matrix independentBasis;
        Matrix imspca = transposeMultiplyMatrixL (s->basis, images);           

        MESSAGE("Computing independent components from the principle components.");

        independentTrain(s->basis, imspca, &independentBasis, s->arch, s->blockSize, s->learningRate, s->iterations);

        if (s->arch == 1)
        {
            Matrix combinedBasis;
            combinedBasis = multiplyMatrix (s->basis, independentBasis);
            s->basis  = combinedBasis;
            s->ica2Basis = NULL;

            MESSAGE2ARG ("PCA and ICA Combined. Combined projection expressed as %d by "
                "%d matrix.", combinedBasis->row_dim, combinedBasis->col_dim);	
        }
        else if (s->arch == 2)
        {
            s->ica2Basis = independentBasis;
            MESSAGE2ARG ("PCA and ICA kept separate. ICA projection expressed as %d by "
                "%d matrix.", independentBasis->row_dim, independentBasis->col_dim);	
        }
    }
    /*END Changed by Zeeshan: For ICA*/
}
Пример #8
0
void
writeSubspace (Subspace *s, char *training_filename, char *imageList, int argc, char**argv)
{
    int i, j;
    FILE* file;
    char *cutOffModeStr;
    time_t ttt = time(0);

    switch (s->cutOffMode)
    {
    case CUTOFF_NONE:    cutOffModeStr = "NONE";    break;
    case CUTOFF_SIMPLE:  cutOffModeStr = "SIMPLE";  break;
    case CUTOFF_ENERGY:  cutOffModeStr = "ENERGY";  break;
    case CUTOFF_STRETCH: cutOffModeStr = "STRETCH"; break;
    case CUTOFF_DROPVEC: cutOffModeStr = "DROPVEC"; break;
    default:             cutOffModeStr = "UNKNOWN"; break;
    }

    MESSAGE1ARG ("Saving trianing information to file %s", training_filename);

    file = fopen (training_filename, "wb");
    if (!file) {
        printf ("Error: could not open file <%s>\n", training_filename);
        exit (1);
    }

    fprintf (file, "TRAINING_COMMAND =");

    for (i = 0; i < argc; i++)
        fprintf (file, " %s", argv[i]);

    fprintf (file, "\n");
    fprintf (file, "DATE          = %s", ctime(&ttt));
    fprintf (file, "FILE_LIST     = %s\n", imageList);
    fprintf (file, "VECTOR_LENGTH = %d\n", s->basis->row_dim); /* numPixels */
    fprintf (file, "USE_LDA       = %s\n", s->useLDA ? "YES" : "NO" );

    fprintf (file, "CUTOFF_MODE   = %s\n", cutOffModeStr);
    fprintf (file, "CUTOFF_PERCENTAGE  = %f\n", s->cutOff);
    fprintf (file, "BASIS_VALUE_COUNT  = %d\n", s->values->row_dim);   /* basisDim */
    fprintf (file, "BASIS_VECTOR_COUNT = %d\n", s->basis->col_dim);
    fprintf (file, "DROPPED_FROM_FRONT = %d\n", s->dropNVectors);

    fprintf (file, "USE_LPP = %s\n", s->useLPP ? "YES" : "NO" );
    fprintf (file, "NEIGHBOURS = %d\n", s->neighbourCount);
    fprintf (file, "LPP_DIST = %s\n", s->lppDistance);
    fprintf (file, "LPP_VECTORS = %d\n", s->lppKeepNVectors);
    fprintf (file, "ADAPTIVE_K = %d\n", s->useAdaptiveK);

    fprintf (file, "USE_ICA = %s\n", s->useICA ? "YES" : "NO" );
    fprintf (file, "BLOCKSIZE = %d\n", s->blockSize);
    fprintf (file, "LEARNING_RATE = %e\n", s->learningRate);
    fprintf (file, "ITERATIONS = %d\n", s->iterations);
    fprintf (file, "ARCHITECTURE = %d\n", s->arch);

    for (i = 21; i < 256; i++){
        fprintf (file, "\n");
    }

    /**/

    /* write out the pixel count */
    writeInt (file, s->mean->row_dim);

    /* write out the mean vector */
    for (i = 0; i < s->mean->row_dim; i++) {
        writeDouble (file, ME(s->mean,i,0));
    }

    /* write out the number of eigen values */
    writeInt (file, s->values->row_dim);

    /* write out the eigen values */
    for (i = 0; i < s->values->row_dim; i++) {
        writeDouble (file, ME(s->values,i,0));
    }

    /* write out the number of basis vectors */
    writeInt (file,s->basis->col_dim);

    /* write out the eigen basis.  the size is "pixelcount"X"number of vectors"*/
    for (i = 0; i < s->basis->col_dim; i++) {
        for (j = 0; j < s->basis->row_dim; j++) {
            writeDouble (file, ME(s->basis, j, i));
        }
    }

    if(s->useICA)
    {
        /*START: 	Changed by Zeeshan: for ICA*/
        /* write out the number of rows in ica2 basis */
        writeInt (file, s->ica2Basis->row_dim);

        /* write out the number of cols in ica2 basis */
        writeInt (file, s->ica2Basis->col_dim);

        /* write out the ica 2 basis */
        for (i = 0; i < s->ica2Basis->col_dim; i++) {
            for (j = 0; j < s->ica2Basis->row_dim; j++) {
                writeDouble (file, ME(s->ica2Basis, j, i));
            }
        }
    }
    /*END: 		Changed by Zeeshan: for ICA*/

    fclose (file);
}