Skip to content
Snippets Groups Projects
Select Git revision
  • b5e356df3e24d5f24dede0615ba311f5b881a290
  • master default protected
  • loss
  • producer
4 results

buildAppImage.sh

Blame
  • predict_fct.c 23.02 KiB
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include "predict.h"
    
    void predict_help_message(context *ctx)
    {
    	context_general_help_message(ctx);
    	context_language_help_message(ctx);
    	context_fplm_help_message(ctx);
    	context_maca_data_path_help_message(ctx);
    	context_features_filename_help_message(ctx);    
    	context_weights_matrix_filename_help_message(ctx);
    	context_features_model_help_message(ctx);
    	context_code_class_help_message(ctx);
    	context_cascade_help_message(ctx);
    	exit(1);
    }
    
    void new_input_files(Input_files* in_files)
    {
    	in_files->f_fplm = NULL;
    	in_files->code_class = NULL;
    	in_files->all_real_morphos = NULL;
    	in_files->code_class_tense = NULL;
    	in_files->code_class_person = NULL;
    	in_files->code_class_gender = NULL;
    	in_files->code_class_number = NULL;
    	in_files->predict_tense = NULL;
    	in_files->predict_person = NULL;
    	in_files->predict_gender = NULL;
    	in_files->predict_number = NULL;
    }
    
    void init_input_files(Input_files* in_files, char* fplm_name, char* code, 
    	char* all, char* c1, char* c2, char* c3, char* c4, char* p1, char* p2, char* p3, char* p4)
    {
    	new_input_files(in_files);
    	if(fplm_name != NULL)
    	{
    		in_files->f_fplm = fopen(fplm_name,"r");
    		if(in_files->f_fplm == NULL)
    		{
    			fprintf(stderr, "Could not open the fplm file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(code != NULL)
    	{
    		in_files->code_class = fopen(code,"r");
    		if(in_files->code_class == NULL)
    		{
    			fprintf(stderr, "Could not open the code_class file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(all != NULL)
    	{
    		in_files->all_real_morphos = fopen(all,"r");
    		if(in_files->all_real_morphos == NULL)
    		{
    			fprintf(stderr, "Could not open the all real classes file. Use fplm2cff with -t all to generate it.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(c1 != NULL)
    	{
    		in_files->code_class_tense = fopen(c1,"r");
    		if(in_files->code_class_tense == NULL)
    		{
    			fprintf(stderr, "Could not open the code class tense file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(c2 != NULL)
    	{
    		in_files->code_class_person = fopen(c2,"r");
    		if(in_files->code_class_person == NULL)
    		{
    			fprintf(stderr, "Could not open the code class person file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(c3 != NULL)
    	{
    		in_files->code_class_gender = fopen(c3,"r");
    		if(in_files->code_class_gender == NULL)
    		{
    			fprintf(stderr, "Could not open the code class gender file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(c4 != NULL)
    	{
    		in_files->code_class_number = fopen(c4,"r");
    		if(in_files->code_class_number == NULL)
    		{
    			fprintf(stderr, "Could not open the code class number file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(p1 != NULL)
    	{
    		in_files->predict_tense = fopen(p1,"r");
    		if(in_files->predict_tense== NULL)
    		{
    			fprintf(stderr, "Could not open the predict tense file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(p2 != NULL)
    	{
    		in_files->predict_person = fopen(p2,"r");
    		if(in_files->predict_person == NULL)
    		{
    			fprintf(stderr, "Could not open the predict person file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(p3 != NULL)
    	{
    		in_files->predict_gender = fopen(p3,"r");
    		if(in_files->predict_gender == NULL)
    		{
    			fprintf(stderr, "Could not open the predict gender file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    	if(p4 != NULL)
    	{
    		in_files->predict_number = fopen(p4,"r");
    		if(in_files->predict_number == NULL)
    		{
    			fprintf(stderr, "Could not open the predict number file.\n");
    			exit(EXIT_FAILURE); 
    		}
    	}
    }
    
    void new_output_files(Output_files* out_files)
    {
    	out_files->f_error = NULL;
    	out_files->f_predict = NULL;
    	out_files->new_fplm = NULL;
    	out_files->morpho_predicted = NULL;	
    }
    void init_output_files(Output_files* out_files, char* error_name, char* predict_name, char* fplm_name, char* morpho_name)
    {
    	new_output_files(out_files);
    	if(error_name != NULL)
    	{
    		out_files->f_error = fopen(error_name, "w");
    		if(out_files->f_error==NULL)
    		{
    			fprintf(stderr,"Problem with the error file.\n");
    			exit(EXIT_FAILURE);
    		}
    	}
    	if(predict_name != NULL)
    	{
    		out_files->f_predict = fopen(predict_name, "w");
    		if(out_files->f_predict==NULL)
    		{
    			fprintf(stderr,"Problem with the predict file.\n");
    			exit(EXIT_FAILURE);
    		}
    	}
    	if(fplm_name != NULL)
    	{
    		out_files->new_fplm = fopen(fplm_name, "w");
    		if(out_files->new_fplm==NULL)
    		{
    			fprintf(stderr,"Problem with the new fplm file.\n");
    			exit(EXIT_FAILURE);
    		}
    	}
    	if(morpho_name != NULL)
    	{
    		out_files->morpho_predicted = fopen(morpho_name, "w+");
    		if(out_files->morpho_predicted==NULL)
    		{
    			fprintf(stderr,"Problem with the morpho_predicted file.\n");
    			exit(EXIT_FAILURE);
    		}
    	}
    }
    
    void free_input_files(Input_files* in_files)
    {
    	if(in_files->f_fplm != NULL) fclose(in_files->f_fplm);
    	if(in_files->code_class != NULL) fclose(in_files->code_class);
    	if(in_files->all_real_morphos != NULL) fclose(in_files->all_real_morphos);
    	if(in_files->code_class_tense != NULL) fclose(in_files->code_class_tense);
    	if(in_files->code_class_person != NULL) fclose(in_files->code_class_person);
    	if(in_files->code_class_gender != NULL) fclose(in_files->code_class_gender);
    	if(in_files->code_class_number != NULL) fclose(in_files->code_class_number);
    	if(in_files->predict_tense != NULL) fclose(in_files->predict_tense);
    	if(in_files->predict_person != NULL) fclose(in_files->predict_person);
    	if(in_files->predict_gender != NULL) fclose(in_files->predict_gender);
    	if(in_files->predict_number != NULL) fclose(in_files->predict_number);
    	free(in_files);
    }
    
    void free_output_files(Output_files* out_files)
    {
    	if(out_files->f_error != NULL) fclose(out_files->f_error);
    	if(out_files->f_predict != NULL) fclose(out_files->f_predict);
    	if(out_files->new_fplm != NULL) fclose(out_files->new_fplm);
    	if(out_files->morpho_predicted != NULL) fclose(out_files->morpho_predicted);
    	free(out_files);
    }
    	
    		/**Fonctions for all classes' prediction (morpho is a class)**/
    void predict_all_classes(context* ctx)
    {
    	Output_files* out_files = malloc(sizeof(Output_files));
    	Input_files* in_files = malloc(sizeof(Input_files));
    	FPLM* fplm = new_fplm();
    	feature_table *cfw = feature_table_load(ctx->cfw_filename, ctx->verbose);
    	feat_vec *fv = feat_vec_new(10);
    	dico *dico_features = dico_read(ctx->features_filename, 0.5);
    	feat_model *fm = feat_model_read(ctx->fm_filename, feat_lib_build(), ctx->verbose); 
    	int line_nb=0;
    	int fields_nb;
    	int errors = 0;
    	
    	init_output_files(out_files, "error.txt", NULL, NULL, NULL);
    	init_input_files(in_files,ctx->fplm_filename,ctx->code_class_filename,
    					NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
    	while((fields_nb = read_line_fplm(in_files->f_fplm, fplm)) != -1)
    	{
    		if(fields_nb!=4)
    		{
    			if(ctx->debug_mode)
    			{
    				fprintf(stderr, "form = %s pos = %s lemma = %s morpho = %s\n", fplm->form, fplm->pos, fplm->lemma, fplm->morpho); 
    				fprintf(stderr, "incorrect fplm entry, skipping it\n");
    			}
    			continue;
    		}
    		line_nb++;
    		make_prediction_all_classes(ctx, out_files->f_error, in_files->code_class, &errors, fplm, cfw, fv, dico_features, fm);
    	}
    	printf("Success rate : %lf %%\n", 100-((float)errors*100/line_nb));
    	if(ctx->features_filename)
    		dico_print(ctx->features_filename, dico_features);
    		
    	free_fplm(fplm);
    	free_input_files(in_files);
    	free_output_files(out_files);
    }
    
    /** Predict a class for the current word **/
    void make_prediction_all_classes(context* ctx, FILE* error_file, FILE* code_class, int* errors, FPLM* fplm, feature_table *cfw, feat_vec *fv, dico *dico_features, feat_model *fm)
    {
    	int class_predicted;
    	float max;
    	form2fv(fplm, fv, fm, dico_features, LOOKUP_MODE);
    	class_predicted = feature_table_argmax(fv, cfw, &max);
    	if(ctx->separate_classes)
    		errors_nb_all_classes_separated(error_file, code_class, fplm, class_predicted, errors);
    	else
    		errors_nb_all_classes_not_separated(error_file, code_class, fplm,class_predicted, errors);
    }
    
    	/**Fonctions for not-separated classes**/
    	
    /** Increment the number of errors if the programm has predicted the wrong class **/
    void errors_nb_all_classes_not_separated(FILE* error_file, FILE* code_class, FPLM* fplm, int class_predicted, int* errors)
    {
    	int real_class = extract_real_class_not_separated(code_class, fplm->morpho, 1);
    	if(class_predicted != real_class)
    	{
    		*errors = *errors+1;
    		fprintf(error_file, "form = %s | class predicted = %d | real class = %d\n", fplm->form, class_predicted, real_class);
    	}
    }
    
    /** Return the word's real class (also used to predict one target)**/
    int extract_real_class_not_separated(FILE* code_class, char* target_class, int all_classes)
    {
    	return associate_number_to_classes(code_class, target_class, all_classes);
    }
    
    	/**Fonctions for separated classes**/
    	
    void errors_nb_all_classes_separated(FILE* error_file, FILE* code_class, FPLM* fplm, int class_predicted, int* errors)
    {
    	int i;
    	int size = 10;
    	int real_class[40];
    	size = extract_real_class_all_classes_separated(code_class, real_class, fplm->morpho);
    	for(i=0; i<=size; i++)
    		if(class_predicted == real_class[i])
    			return;
    	*errors = *errors+1;
    	fprintf(error_file, "form = %s | class predicted = %d | real class =", fplm->form, class_predicted);
    	for(i=0; i<=size; i++)
    		fprintf(error_file, " %d", real_class[i]);
    	fprintf(error_file,"\n");
    }
    
    int extract_real_class_all_classes_separated(FILE* code_class, int* real_class, char* morpho)
    {
    	int size = -1;
    	char tense_class[10];
    	char person_class[10];
    	char gender_class[10];
    	char number_class[10];
    	char all_target[20];
    	int i,j;
    	extract_classes_from_morpho(TENSE, tense_class, morpho);
    	extract_classes_from_morpho(PERSON, person_class, morpho);
    	extract_classes_from_morpho(GENDER, gender_class, morpho);
    	extract_classes_from_morpho(NUMBER, number_class, morpho);
    	for(i=0; i<(int)strlen(tense_class); i++)
    	{
    		for(j=0; j<(int)strlen(person_class); j++)
    		{
    			all_target[0] = tense_class[i];
    			all_target[1] = person_class[j];
    			all_target[2] = gender_class[0];
    			all_target[3] = number_class[0];
    			all_target[4] = '\0';
    			size++;
    			real_class[size] = associate_number_to_classes(code_class, all_target, 1);
    		}
    	}
    	return size;
    }
    
    
    		/**Fonctions for a target's prediction**/
    void predict_target(context* ctx)
    {
    	Input_files* in_files = malloc(sizeof(Input_files));
    	Output_files* out_files = malloc(sizeof(Output_files));
    	feature_table *cfw = feature_table_load(ctx->cfw_filename, ctx->verbose);
    	feat_vec *fv = feat_vec_new(10);
    	dico *dico_features = dico_read(ctx->features_filename, 0.5);
    	feat_model *fm = feat_model_read(ctx->fm_filename, feat_lib_build(), ctx->verbose); 
    	int line_nb=0;
    	int fields_nb;
    	int errors = 0;
    	char target_name[10];
    	char output_fplm_name[20];
    	char predict_name[50];
    	FPLM* fplm = new_fplm();
    	TARGET target;
    	init_input_files(in_files, ctx->fplm_filename, ctx->code_class_filename, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); 
    	if(fscanf(in_files->code_class,"%s",target_name)!=1)
    	{
    		fprintf(stderr, "Your code_class file is not conform.\n");
    		exit(EXIT_FAILURE);
    	}
    	strcpy(predict_name,"predict_");
    	strcat(predict_name,target_name);
    	target = choose_target(target_name);
    	if(ctx->cascade)
    	{
    		strcpy(output_fplm_name,"fplm_");
    		strcat(output_fplm_name,target_name);
    		init_output_files(out_files, "predict_error", predict_name, output_fplm_name, NULL);
    	}
    	else
    		init_output_files(out_files, "predict_error", predict_name, NULL, NULL); 
    	
    	while((fields_nb = read_line_fplm(in_files->f_fplm, fplm)) != -1)
    	{
    		if(fields_nb!=4)
    		{
    			if(ctx->debug_mode)
    			{
    				fprintf(stderr, "form = %s pos = %s lemma = %s morpho = %s\n", fplm->form, fplm->pos, fplm->lemma, fplm->morpho); 
    				fprintf(stderr, "incorrect fplm entry, skipping it\n");
    			}
    			continue;
    		}
    		line_nb++;
    		if(ctx->cascade) 
    			fprintf(out_files->new_fplm,"%s\t%s\t%s\t",fplm->form, fplm->pos, fplm->lemma);
    		make_prediction(ctx, out_files, in_files->code_class, target, &errors, fplm, cfw, fv, dico_features, fm);
    	}
    	printf("Success rate : %lf %%\n", 100-((float)errors*100/line_nb));
    	if(ctx->features_filename)
    		dico_print(ctx->features_filename, dico_features);
    	
    	free_fplm(fplm);
    	free_input_files(in_files);
    	free_output_files(out_files);
    }
    
    void make_prediction(context* ctx, Output_files* out_files, FILE* code_class, TARGET target, int* errors, FPLM* fplm, feature_table *cfw, feat_vec *fv, dico *dico_features, feat_model *fm)
    {
    	int class_predicted;
    	float max;
    	form2fv(fplm, fv, fm, dico_features, LOOKUP_MODE);
    	class_predicted = feature_table_argmax(fv, cfw, &max);
    	fprintf(out_files->f_predict,"%d\n",class_predicted);
    	if(ctx->separate_classes)
    		errors_nb_separated(out_files->f_error, code_class, target, class_predicted, errors, fplm);
    	else
    		errors_nb_not_separated(out_files->f_error, code_class, target, fplm, class_predicted, errors);
    	
    	if(ctx->cascade)
    		write_new_fplm(fplm, target, out_files->new_fplm, code_class, class_predicted);
    
    }
    
    void write_new_fplm(FPLM* fplm, TARGET target, FILE* new_fplm, FILE* code_class, int class_predicted)
    {
    	int code;
    	int i=0;
    	int ok=1;
    	int cpt_diese = 0;
    	char tmp[20];
    	char new_morpho[30]; //will contain the morpho feature with the prediction
    	int position_morpho = 0;
    	int position = extract_class_position(target); //position = the num of the diese we want
    	while(i<(int)strlen(fplm->morpho) && cpt_diese!=position)
    	{
    		new_morpho[i] = fplm->morpho[i];
    		if(fplm->morpho[i]=='#')
    			cpt_diese++;
    		i++;
    	}
    	position = i; //position is now where we will include the class predicted
    	position_morpho = position;
    	while(position_morpho<(int)strlen(fplm->morpho) && fplm->morpho[position_morpho]!='#')
    		position_morpho++; //position_morpho is where we will copy the initial morpho feature in the new morpho feature
    
    	if(class_predicted==0)
    	{
    		while(position_morpho<(int)strlen(fplm->morpho)) //writting the initial morpho feature's rest in the new morpho feature
    		{
    			new_morpho[position] = fplm->morpho[position_morpho];
    			position++;
    			position_morpho++;
    		}
    		new_morpho[position]='\0';
    		ok=0;
    	}
    
    	rewind(code_class);
    	fscanf(code_class,"%s",tmp); //read the target name
    	while(ok && fscanf(code_class,"%d %s\n",&code,tmp)==2) //tmp = class
    	{
    		if(class_predicted==code && code!=0) //including the class predicted
    		{
    			i=0;
    			while(i<(int)strlen(tmp))
    			{
    				new_morpho[position]=tmp[i];
    				i++;
    				position++;
    			}
    			while(position_morpho<(int)strlen(fplm->morpho)) //writting the initial morpho feature's rest in the new morpho feature
    			{
    				new_morpho[position] = fplm->morpho[position_morpho];
    				position++;
    				position_morpho++;
    			}
    			new_morpho[position]='\0';
    			ok=0;
    		}
    	}
    	fprintf(new_fplm,"%s\n",new_morpho);	
    }
    
    	/**Fonctions for separated classes**/
    void errors_nb_separated(FILE* error_file, FILE* code_class, TARGET target, int class_predicted, int* errors, FPLM* fplm)
    {
    	int i;
    	int size = 0;
    	int real_class[10];
    	char target_class[10];
    	extract_classes_from_morpho(target,target_class,fplm->morpho);
    	size = extract_real_class_separated(code_class, target_class, real_class);
    	for(i=0; i<=size; i++)
    		if(class_predicted == real_class[i])
    			return;
    	*errors = *errors+1;
    	fprintf(error_file, "form = %s | class predicted = %d | real class =", fplm->form, class_predicted);
    	for(i=0; i<=size; i++)
    		fprintf(error_file, " %d",real_class[i]);
    	fprintf(error_file, "\n");
    	
    }
    
    int extract_real_class_separated(FILE* code_class, char* target_class, int* real_class)
    {
    	int size = -1;
    	int i;
    	for(i=0; i<(int)strlen(target_class); i++) 
    	{
    		size++;
    		real_class[size] = associate_number_to_classes_separated(code_class,target_class,i);
    	}
    	return size;
    }
    
    	/**Fonctions for not-separated classes**/
    void errors_nb_not_separated(FILE* error_file, FILE* code_class, TARGET target, FPLM* fplm, int class_predicted, int* errors)
    {
    	int real_class;
    	char target_class[10];
    	extract_classes_from_morpho(target, target_class, fplm->morpho);
    	real_class = extract_real_class_not_separated(code_class, target_class, 0);
    	if(class_predicted != real_class)
    	{
    		*errors = *errors+1;
    		fprintf(error_file, "form = %s | class predicted = %d | real class = %d\n", fplm->form, class_predicted, real_class);
    	}
    }
    			/** Fonctions for all target's prediction after having predicted each targets **/
    void predict_each_and_all_targets(context* ctx)
    {
    	Input_files* in_files = malloc(sizeof(Input_files));
    	Output_files* out_files = malloc(sizeof(Output_files));
    	int class_predicted_array[4];
    	int fields_nb = 0;
    	int global_error = 0;
    	int line_nb = 0;
    	FPLM* fplm = new_fplm();
    	init_output_files(out_files, NULL, NULL, NULL, "morpho_predicted");
    	init_input_files(in_files,ctx->fplm_filename, NULL, "code_class", "code_class_tense", "code_class_person", "code_class_gender",
    			"code_class_number", "predict_tense", "predict_person", "predict_gender", "predict_number");
    	
    	while((fields_nb = read_line_fplm(in_files->f_fplm, fplm)) != -1)
    	{
    		line_nb++;
    		calculate_global_success_rate(ctx,in_files,out_files->morpho_predicted,&global_error,class_predicted_array,fplm->morpho);
    	}
    	compare_morpho_predicted_and_real_morphos(in_files->all_real_morphos, out_files->morpho_predicted, line_nb);
    	printf("Global success rate : %lf %%\n", 100-((float)global_error*100/line_nb));
    	free_fplm(fplm);
    	free_input_files(in_files);
    	free_output_files(out_files);
    }
    
    void calculate_global_success_rate(context* ctx, Input_files* in_files, FILE* morpho_predicted, int* global_error, int* class_predicted_array,char* morpho)
    {
    	fscanf(in_files->predict_tense, "%d", &class_predicted_array[0]); //tense
    	fscanf(in_files->predict_person, "%d", &class_predicted_array[1]); //person
    	fscanf(in_files->predict_gender, "%d", &class_predicted_array[2]); //gender
    	fscanf(in_files->predict_number, "%d", &class_predicted_array[3]); //number
    
    	if(ctx->separate_classes)
    	{
    		create_morpho_predicted_file(morpho_predicted,class_predicted_array,in_files);
    		compare_predicted_and_real_class(in_files,morpho,global_error,class_predicted_array);
    	}
    	else
    	{
    		int real_classes_array[4];
    		put_in_array_real_classes(real_classes_array,in_files,morpho);
    		create_morpho_predicted_file(morpho_predicted,class_predicted_array,in_files);
    		for(int i=0; i<4; i++)
    			if(class_predicted_array[i]!=real_classes_array[i])
    			{
    				*global_error = *global_error + 1;
    				return;
    			}
    	}
    }
    
    /**The morpho predicted file is used to know if there are incoherent labels predicted**/
    void create_morpho_predicted_file(FILE* morpho_predicted,int* class_predicted_array,Input_files* in_files)
    {
    	int size=-1;
    	int i, ok = 1;
    	int code;
    	char tmp[20];
    	char new_morpho[20];
    	if(class_predicted_array[0]!=0)
    	{
    		rewind(in_files->code_class_tense);
    		i=0;
    		fscanf(in_files->code_class_tense,"%s",tmp);
    		while(fscanf(in_files->code_class_tense,"%d %s\n",&code,tmp)==2)
    		{
    			if(code==class_predicted_array[0])
    			{
    				while(tmp[i]!='\0')
    				{
    					size++;
    					new_morpho[size]=tmp[i];
    					i++;
    				}
    			}
    		}
    	}
    	size++;
    	new_morpho[size]='#';
    	if(class_predicted_array[1]!=0)
    	{
    		rewind(in_files->code_class_person);
    		i=0;
    		fscanf(in_files->code_class_person,"%s",tmp);
    		while(fscanf(in_files->code_class_person,"%d %s\n",&code,tmp)==2)
    		{
    			if(code==class_predicted_array[1])
    			{
    				while(tmp[i]!='\0')
    				{
    					size++;
    					new_morpho[size]=tmp[i];
    					i++;
    				}
    			}
    		}
    	}
    	size++;
    	new_morpho[size]='#';
    	if(class_predicted_array[2]!=0)
    	{
    		rewind(in_files->code_class_gender);
    		i=0;
    		fscanf(in_files->code_class_gender,"%s",tmp);
    		while(fscanf(in_files->code_class_gender,"%d %s\n",&code,tmp)==2)
    		{
    			if(code==class_predicted_array[2])
    			{
    				while(tmp[i]!='\0')
    				{
    					size++;
    					new_morpho[size]=tmp[i];
    					i++;
    				}
    			}
    		}
    	}
    	size++;
    	new_morpho[size]='#';
    	if(class_predicted_array[3]!=0)
    	{
    		rewind(in_files->code_class_number);
    		i=0;
    		fscanf(in_files->code_class_number,"%s",tmp);
    		while(fscanf(in_files->code_class_number,"%d %s\n",&code,tmp)==2)
    		{
    			if(code==class_predicted_array[3])
    			{
    				while(tmp[i]!='\0')
    				{
    					size++;
    					new_morpho[size]=tmp[i];
    					i++;
    				}
    			}
    		}
    	}
    	size++;
    	new_morpho[size]='#';
    	size++;
    	new_morpho[size]='\0';
    	
    	//don't duplicate the morpho feature predicted
    	rewind(morpho_predicted);
    	while(ok && fscanf(morpho_predicted,"%s\n",tmp)==1)
    		if(!strcmp(tmp,new_morpho))
    			ok=0;
    	if(ok)
    		fprintf(morpho_predicted,"%s\n",new_morpho); 
    }
    
    /**Return the number of incoherent labels in the morpho predicted file**/
    void compare_morpho_predicted_and_real_morphos(FILE* all_real_morphos, FILE* morpho_predicted, int line_nb)
    {
    	//all_real_morphos est le fichier code_class du grand fplm (faire cff avec toutes les classes)
    	int cpt_diese_max = 4;
    	int code;
    	int i,j;
    	int incoherence, ok, cpt_incoherence=0;
    	char tmp[20];
    	char real_morpho[20];
    	char morpho_predicted_array[20];
    	rewind(morpho_predicted);
    	while(fscanf(morpho_predicted,"%s\n",morpho_predicted_array)==1)
    	{
    		rewind(all_real_morphos);
    		incoherence = 1;
    		ok=1;
    		while(ok && fscanf(all_real_morphos,"%d %s\n",&code,tmp)==2)
    		{
    			j=0;
    			i=0;
    			while(i<cpt_diese_max)
    			{
    				if(tmp[j]=='#')
    					i++;
    				real_morpho[j]=tmp[j];
    				j++;
    			}
    			real_morpho[j]='\0';
    			if(!strcmp(real_morpho,morpho_predicted_array))
    			{
    				incoherence = 0;
    				ok=0;
    			}
    		}
    		if(incoherence)
    		{
    			printf("incorrect = %s\n",morpho_predicted_array);
    			cpt_incoherence++;
    		}
    	}
    	printf("Number of incoherent labels = %d\nIncoherence rate = %lf %%\n",cpt_incoherence,(float)cpt_incoherence*100/line_nb);
    }
    
    /**for not-separated classes**/
    void put_in_array_real_classes(int* real_classes_array, Input_files* in_files, char* morpho)
    {
    	char target_class[10];
    	extract_classes_from_morpho(TENSE,target_class,morpho);
    	real_classes_array[0] = extract_real_class_not_separated(in_files->code_class_tense, target_class, 0); 
    	extract_classes_from_morpho(PERSON,target_class,morpho);
    	real_classes_array[1] = extract_real_class_not_separated(in_files->code_class_person, target_class, 0); 
    	extract_classes_from_morpho(GENDER,target_class,morpho);
    	real_classes_array[2] = extract_real_class_not_separated(in_files->code_class_gender, target_class, 0); 
    	extract_classes_from_morpho(NUMBER,target_class,morpho);
    	real_classes_array[3] = extract_real_class_not_separated(in_files->code_class_number, target_class, 0); 
    }
    
    /**for separated classes**/
    void compare_predicted_and_real_class(Input_files* in_files,char* morpho, int* global_error, int* class_predicted_array)
    {
    	char target_class[10];
    	int real_class[10];
    	int size = -1;
    	int i;
    	int err_glo=1;
    	
    	extract_classes_from_morpho(TENSE,target_class,morpho);
    	size = extract_real_class_separated(in_files->code_class_tense, target_class, real_class);
    	for(i=0; i<=size; i++)
    		if(class_predicted_array[0] == real_class[i])
    			err_glo=0;
    	if(err_glo)
    	{
    		*global_error = *global_error+1;
    		return;
    	}
    
    	extract_classes_from_morpho(PERSON,target_class,morpho);
    	size = extract_real_class_separated(in_files->code_class_person, target_class, real_class);
    	err_glo=1;
    	for(i=0; i<=size; i++)
    		if(class_predicted_array[1] == real_class[i])
    			err_glo=0;
    	if(err_glo)
    	{
    		*global_error = *global_error+1;
    		return;
    	}
    	
    	extract_classes_from_morpho(GENDER,target_class,morpho);
    	size = extract_real_class_separated(in_files->code_class_gender, target_class, real_class);
    	err_glo=1;
    	for(i=0; i<=size; i++)
    		if(class_predicted_array[2] == real_class[i])
    			err_glo=0;
    	if(err_glo)
    	{
    		*global_error = *global_error+1;
    		return;
    	}
    	
    	extract_classes_from_morpho(NUMBER,target_class,morpho);
    	size = extract_real_class_separated(in_files->code_class_number, target_class, real_class);
    	err_glo=1;
    	for(i=0; i<=size; i++)
    		if(class_predicted_array[3] == real_class[i])
    			err_glo=0;
    	if(err_glo)
    		*global_error = *global_error+1;
    }