/************************************************************************ * * * Program package T O O L D I A G * * * * Version 1.5 * * Date: Tue Feb 8 13:39:06 1994 * * * * NOTE: This program package is copyrighted in the sense that it * * may be used for scientific purposes. The package as a whole, or * * parts thereof, cannot be included or used in any commercial * * application without written permission granted by the author. * * No programs contained in this package may be copied for commercial * * distribution. * * * * All comments concerning this program package may be sent to the * * e-mail address 'tr@fct.unl.pt'. * * * ************************************************************************/ #include #include #include "def.h" #include "matrix.h" extern universe *U; extern bool verbose, feat_description; extern char **feature_desc; static bool done; static str80 buf, name, lfxName, lvqFile; static FILE *xf = NULL; static FeatVector SampleBuf = NULL; static Matrix LFX = { 0, 0, NULL }; /* Linear feature extractor */ /*******************************************/ /***** EXTRACTION METHODS *****/ /*******************************************/ #define LDA 0 #define NUM_EXTRACTION_METHODS 1 int num_extr_methods = NUM_EXTRACTION_METHODS; struct feature_extraction_methods { int index; char *name; } extraction_method[] = { { LDA, "Linear discriminant analysis" } }; int extr_method = LDA; /* default */ /*--------------------------------------------------------------*/ static void show_linear_extractor( W ) Matrix *W; { int i, j; if( W->Elem == NULL || W->row == 0 || W->col == 0 ) { printf("Feature extractor is empty..."); gets( buf ); return; } printf("\n\n ***** %d x %d FEATURE EXTRACTOR: *****\n", W->row, W->col ); print_Matrix( W ); printf("..."); gets(buf); } static void save_linear_extractor( W ) Matrix *W; { int i, j; if( W->Elem == NULL || W->row == 0 || W->col == 0 ) { printf("Feature extractor is empty..."); gets( buf ); return; } strcpy( lfxName, DATA_DIR ); printf("Saving linear feature extractor to: %s", lfxName ); gets( name ); if( name[0] != '\0' ) { strcat( lfxName, name ); xf = fopen( lfxName, f_open_text_w ); if( xf == NULL ) { printf("Cannot open %s! Exitus...\n", lfxName ); exit(1); } fprintf( xf, "# Universe:\n%s\n", U->name ); fprintf( xf, "# Row and column dimension of the linear feature extractor\n"); fprintf( xf, "%d %d\n", W->row, W->col ); for( i = 0; i < W->row; i++ ) { for( j = 0; j < W->col; j++) fprintf( xf, " %20.15f ", (float)W->Elem[i*W->col+j]); fprintf( xf, "\n"); } fprintf( xf, "\n"); fclose( xf ); } else printf("\tNothing saved...\n"); } static void load_extr( fname, W ) char *fname; Matrix *W; { int i, j; xf = fopen( fname, f_open_text_r ); if( xf == NULL ) {printf("Cannot open %s! nothing done...", fname );gets(buf);return;} if( verbose ) printf("\nLoading feature extractor from\n\t%s", fname ); dataline( xf, buf ); if( strcmp( buf, U->name ) != 0 ) {printf("Warning universe names different: %s --- %s\n", buf, U->name );} dataline( xf, buf ); Matrix_Free( W ); sscanf( buf, "%d %d", &(W->row), &(W->col) ); if( U->nrFeat != W->row ) { printf("\nERROR:\n"); printf("Row size(%d) of the extractor is different", W->row ); printf(" from nr. of features(%d)\n", U->nrFeat ); printf("\tReturning..."); gets(buf); return; } Matrix_Alloc( W ); for( i = 0; i < W->row; i++ ) for( j = 0; j < W->col; j++) fscanf( xf, "%lf", &(W->Elem[i*W->col+j]) ); fclose( xf ); if( verbose ) show_linear_extractor( W ); } static void load_linear_extractor( W ) Matrix *W; { int i, j; strcpy( lfxName, DATA_DIR ); printf("Loading linear feature extractor from:\n\t%s", lfxName ); gets( name ); if( name[0] == '\0' ) return; strcat( lfxName, name ); load_extr( lfxName, W ); } #ifdef OLD static void extract_samples( W ) Matrix *W; { int i, j, k, nrSmp, nrVal, D, d; Matrix WT, Y, XI; if( W->Elem == NULL || W->row == 0 || W->col == 0 ) { printf("Feature extractor is empty..."); gets( buf ); return; } D = U->nrFeat; init_Matrix( &WT ); init_Matrix( &Y ); init_Matrix( &XI ); Transpose_Matrix( W, &WT ); Y.row = D; Y.col = 1; Matrix_Alloc( &Y ); /* Class by class take the samples, extract the reduced sample and write back, destroy any feature description if exists, and set all new, extracted features as selected */ d = W->col; for( i = 0; i < U->nrClass; i++ ) { /* save the samples of the actual class to buffer */ FREE( SampleBuf ); nrSmp = U->C[i].numSampl; nrVal = nrSmp * D; SampleBuf = (FeatVector) malloc( nrVal * sizeof(FeatVector*) ); CHKPTR(SampleBuf); for( k = 0; k < nrVal; k++ ) SampleBuf[k] = U->C[i].S[k]; FREE( U->C[i].S ); U->C[i].S = (FeatVector) malloc( nrSmp * d * sizeof(FeatVector*) ); CHKPTR( U->C[i].S ); for( j = 0; j < nrSmp; j++ ) { /* generate the vector to be mapped */ for( k = 0; k < D; k++ ) Y.Elem[k] = SampleBuf[j*D+k]; /* extract */ Mult_Matrix( &WT, &Y, &XI ); /* write vector back to universe */ for( k = 0; k < d; k++ ) U->C[i].S[j*d+k] = XI.Elem[k]; } } /* Set all features as selected and destroy eventual description */ U->nrFeat = d; U->nrSelFeat = d; FREE( U->FSV ); U->FSV = (feature*) malloc( U->nrSelFeat * sizeof(struct feature_) ); for( i = 0; i < U->nrSelFeat; i++ ) { U->FSV[i].rank = i; U->FSV[i].crit = (float)EMPTY; } if( feat_description ) { for( i = 0; i < D; i++ ) FREE( feature_desc[i] ); FREE( feature_desc ); feat_description = FALSE; } printf(" ...done.\n"); Matrix_Free( &WT ); Matrix_Free( &Y ); Matrix_Free( &XI ); } #endif static void extract_samples( W ) Matrix *W; { int i, j, k, nrSmp, nrVal, D, d; Matrix WT, Y, XI; FILE *lvq = NULL; if( W->Elem == NULL || W->row == 0 || W->col == 0 ) { printf("Feature extractor is empty..."); gets( buf ); return; } D = U->nrFeat; d = W->col; init_Matrix( &WT ); init_Matrix( &Y ); init_Matrix( &XI ); Transpose_Matrix( W, &WT ); Y.row = D; Y.col = 1; Matrix_Alloc( &Y ); strcpy( lvqFile, DATA_DIR ); printf("Saving the extracted data in LVQ format in file:\n\t\t%s", lvqFile ); gets( name ); if( name[0] == '\0' ) { printf("Nothing saved...\n"); return; } strcat( lvqFile, name ); lvq = fopen( lvqFile, f_open_text_w ); if( lvq == NULL ) { printf("Cannot open %s! Exitus...\n", lvqFile ); exit(1); } if( verbose ) printf("Generating LVQ-File: %s\n", lvqFile ); fprintf( lvq, "%d\n", d ); for( i = 0; i < U->nrClass; i++ ) { for( j = 0; j < U->C[i].numSampl; j++ ) { /* generate the vector to be mapped */ for( k = 0; k < D; k++ ) Y.Elem[k] = U->C[i].S[j*D+k]; /* extract */ Mult_Matrix( &WT, &Y, &XI ); for( k = 0; k < d; k++ ) fprintf( lvq, "%f ", (float)XI.Elem[k] ); fprintf( lvq, "%s\n", U->C[i].name ); } } fclose( lvq ); printf(" ...done.\n"); Matrix_Free( &WT ); Matrix_Free( &Y ); Matrix_Free( &XI ); } static void featExtract( method ) int method; { Matrix_Free( &LFX ); switch( method ) { case LDA : featExtrDiscrimAnalysis( &LFX ); break; } /* Check if there was at least one non-zero eigenvalue */ if( LFX.col != 0 ) { show_linear_extractor( &LFX ); save_linear_extractor( &LFX ); /* extract the data to file */ printf("Do you want to save the extracted samples (y/n)? y\b"); gets( buf ); if( buf[0] == 'n' || buf[0] == 'N' ) return; extract_samples( &LFX ); } } static void featExtractLoop() { int method; printf("\n>>>>>----- FEATURE EXTRACTION MENU -----<<<<<<\n\n"); printf("--------------- Method ----------------\n"); for( method = 0; method < num_extr_methods; method++ ) { printf("(%d) %s", method+1, extraction_method[method].name ); printf("\n"); } printf("\n--------------- Tools -----------------\n"); printf("(S)ave linear feature extractor matrix to file\n"); printf("(L)oad linear feature extractor matrix from file\n"); printf("S(H)ow matrix\n"); printf("(E)xtract samples in memory with actual extractor\n"); printf("(Q)uit\n\n"); printf("Choice: "); gets(buf); done = FALSE; switch( buf[0] ) { case '\0' : break; case 's': case 'S': save_linear_extractor( &LFX ); break; case 'l': case 'L': load_linear_extractor( &LFX ); break; case 'h': case 'H': show_linear_extractor( &LFX ); break; case 'e': case 'E': extract_samples( &LFX ); break; case 'q': case 'Q': done = TRUE; break; default: sscanf( buf, "%d", &method ); if( method >= 1 && method <= num_extr_methods ) { extr_method = extraction_method[method-1].index; featExtract( extr_method ); } break; } } void featExtractMain() { if( U->nrClass > 1 ) { do { featExtractLoop(); } while( !done ); Matrix_Free( &LFX ); } else { printf(" Please load universe first !..." ); gets( buf ); } }