// file: hmm_train.h
//

// make sure definitions are made only once
//
#ifndef __ISIP_HMM_TRAIN
#define __ISIP_HMM_TRAIN

// isip include files
//
#ifndef __ISIP_INTEGRAL
#include <integral.h>
#endif

// forward declaration of classes
//
#ifndef __ISIP_TRAIN_HASH_CELL
#include <train_hash_cell.h>
#endif

#ifndef __ISIP_TRAIN_HASH_TABLE
#include <train_hash_table.h>
#endif

#ifndef __ISIP_TRAIN_LATTICE
#include <train_lattice.h>
#endif

#ifndef __ISIP_TRAIN_LATTICE_NODE
#include <train_lattice_node.h>
#endif

#ifndef __ISIP_TRAIN_LEX_TREE
#include <train_lex_tree.h>
#endif

#ifndef __ISIP_TRAIN_LEX_NODE
#include <train_lex_node.h>
#endif

#ifndef __ISIP_TRAIN_LINK_LIST
#include <train_link_list.h>
#endif

#ifndef __ISIP_TRAIN_LINK_NODE
#include <train_link_node.h>
#endif

#ifndef __ISIP_TRAIN_MEMORY_MANAGER
#include <train_memory_manager.h>
#endif

#ifndef __ISIP_TRAIN_TRAIN_MODEL
#include <train_model.h>
#endif

#ifndef __ISIP_TRAIN_PHONE
#include <train_phone.h>
#endif

#ifndef __ISIP_TRAIN_STATE
#include <train_state.h>
#endif

#ifndef __ISIP_TRAIN_TOKEN
#include <train_token.h>
#endif

#ifndef __ISIP_TRAIN_TRACE
#include <train_trace.h>
#endif

#ifndef __ISIP_TRAIN_WORD
#include <train_word.h>
#endif

// functions to decipher commandline
//
logical_1 expand_filename_cc(char_1*& fname);
logical_1 read_cmdline_cc(int_4 argc, char_1** argv, char_1* prm_file,
			  int_4& context_flag);

// functions to read the parameters file
//
logical_1 read_params_cc(FILE* fp, char_1* mono_file, char_1* trans_file,
			 char_1* state_file, char_1* new_trans_file,
			 char_1* new_state_file, char_1* batch_stats_file,
			 char_1* acc_list_file, char_1* model_file,
			 char_1* phone_file, char_1* lex_file,
			 int_4& align_mode, int_4& input_mode,
                         int_4 level,  char_1* input_file,   
                         char_1* forcealign_list_file, char_1* output_file,
                         int_4& phn, int_4& nbst , float_8*& beam,
			 int_4& mapmi, logical_1& forcealign_mode,
			 int_4& context_mode, float_8& var_floor,
			 logical_1& op_out, logical_1& output_mode,
			 logical_1& train_mode, char_1* sph_file,
			 char_1* state_occ_file, logical_1& occ_mode);


// functions to read transition data from parameter file
//
float_4*** read_trans_cc(int_4& num_trans, int_4*& trans_size, char_1* file);

// functions to read states data from parameter file
//
Train_State** read_states_cc(int_4& num_st, int_4& num_feat, char_1* file);

// functions to read HMM models data from parameter file
//
Train_Model** read_models_cc(int_4& num_mod, char_1* file,
			     Train_State** states, float_4*** trans);

// functions to read phone models data from parameter file
//
char_1** read_monophones_cc(int_4& num_mono, char_1* file);

Train_Phone** read_phones_cc(int_4 num_mono, int_4 ph_size,
			     Train_Model** models,
			     int_4*& ph_map, int_4& num_ph, char_1* file,
			     int_4 context_mode);

int_4 get_nphone_ind_cc(int_4 ph_size, int_4 num_mono, int_4* ph_map,
			int_4 context_mode, int_4 num_sph_a,
			int_4* sph_index_a);

// functions to read lexicon and grammar data from parameter file
//
Train_Hash_table* read_lexicon_cc(int_4& num_words, int_4 num_mono,
			    char_1** monophones, char_1* file);

// functions to read input acoustic data from parameter file
//
logical_1 read_input_cc(FILE* fp, int_4 num_feat, int_4 input_mode,
			float_8* data);

logical_1 print_occ_cc(FILE* fp_out, int_4** st_count,
		       int_4 num_st, int_4 num_mix);

// functions to read keyborad input in demo mode
//
int_4 read_key_cc(int_4& num);

// functions to project traces and advance paths
//
logical_1 project_states_cc(Train_Link_list** token_list, int_4 frame,
			    float_8* feat, int_4 sp_phone,
			    Train_Link_list** phtr_list, int_4* ph_active,
			    int_4 ph_numact, int_4 alignment_mode,
			    Train_Phone** phones, int_4*& ngen, int_4*& ndel,
			    int_4& napmi, float_8*& score,
			    Train_Link_node** ph_marker);

logical_1 project_phones_cc(Train_Link_node** wdmarker, Train_Link_node** phmarker,
			    Train_Link_list** token_list, Train_Phone** phones,
			    Train_Link_list* treelist, Train_Lattice* lattice,
			    int_4 num_mono, int_4 ph_size, int_4* ph_map,
			    int_4*& wd_active, int_4& wd_numact,
			    int_4*& ph_active, int_4& ph_numact,
			    int_4*& ngen, float_8& max_score,
			    int_4 context_mode, logical_1 mlf_mode,
			    int_4 num_sph, int_4* sph_index);

logical_1 generate_phones_cc(Train_Trace* trace, Train_Link_list** token_list,
			     Train_Phone** phones, Train_Link_list* treelist,
			     Train_Lattice* lattice, int_4 num_mono, int_4 ph_size,
			     int_4* ph_map, int_4*& wd_active,
			     int_4& wd_numact, int_4*& ph_active,
			     int_4& ph_numact, int_4*& ngen,
			     float_8& max_score, int_4 context_mode,
			     logical_1 mlf_mode, int_4 num_sph,
			     int_4* sph_index);

logical_1 grow_phone_cc(Train_Trace* trace, Train_Link_list** token_list, Train_Phone** phones,
			Train_Link_list* treelist, Train_Lattice* lattice,
			Train_Lattice_node* curr_lat,	Train_Lex_node* currlex,
			Train_Lex_node* lexch, int_4 ph_size, int_4 num_mono,
			int_4* ph_map, int_4*& phn, int_4*& wd_active,
			int_4& wd_numact, int_4*& ph_active, int_4& ph_numact,
			int_4*& ngen, float_8& max_score,
			int_4 context_mode, logical_1 mlf_mode,
			int_4 num_sph, int_4* sph_index);

logical_1 grow_trace_cc(Train_Trace* trace, Train_Link_list*& tok_list, Train_Lex_node* lexnode,
			Train_Lattice_node* latnode, float_8 lmscore,
			Train_Phone** phones, int_4 phn, int_4*& wd_active,
			int_4& wd_numact, int_4*& ph_active, int_4& ph_numact,
			int_4*& ngen, float_8& max_score);

logical_1 active_trace_cc(Train_Link_list** phtr_list, Train_Link_node** phmarker,
			  Train_Link_node** prev_phmark, Train_Link_list** wdtr_list,
			  Train_Link_node** wdmarker, Train_Link_node** prev_wdmark,
			  int_4* ph_active, int_4 ph_numact,
			  int_4* wd_active, int_4 wd_numact,
			  float_8 sp, float_4 penalty,
			  int_4*& ngen, int_4*& ndel, float_8& max_score);

// functions to insert traces in appropriate links
//
logical_1 insert_token_cc(Train_Link_list*& tok_list, Train_Trace* trace, int_4 st,
			  int_4& ngen, float_8& max_score);
logical_1 insert_trace_cc(Train_Link_list*& tr_list, Train_Trace* trace, Train_Link_node* marker,
			  int_4& ref, int_4& ngen, int_4& nact,
			  float_8& max_score);
logical_1 insert_trace_cc(Train_Link_list*& tr_list, Train_Trace* trace, Train_Link_node* marker,
			  int_4& ngen, float_8& max_score);

// functions to determine the top n best hypotheses
//
logical_1 find_nbest_cc(Train_Link_list** trace_list, Train_Link_node** marker,
			int_4 num_nbest, int_4* active, int_4 num_act,
			int_4& num_hyp, Train_Trace** array);
logical_1 backtrace_cc(Train_Link_node* marker, int_4 num_nbest,
		       int_4& num_hyp, Train_Trace** array);

// functions to print the recognition results to output file
//
logical_1 print_hyps_cc(int_4 hyps, char_1* file, Train_Trace** array, int_4 frame,
			Train_Phone** phones, int_4 ph_size, int_4* ngen,
			int_4* ndel, int_4* ntr);

// functions to perform beam pruning
//
logical_1 token_prune_cc(Train_Link_list** token_list, int_4* active, int_4 num_act,
			 float_8 beam_score, int_4*& ndel);
logical_1 trace_prune_cc(Train_Link_list** trace_list, Train_Link_node** marker,
			 int_4* act_phone, int_4 num_act_ph,
			 float_8 beam_score, int_4 level, int_4& ndel);
logical_1 sort_traces_cc(Train_Link_node** marker, int_4* act_phone,
			 int_4 num_act_ph, int_4 nact, int_4 max_act,
			 float_8& thresh);
logical_1 garbage_prune_cc(Train_Link_list** trace_list, int_4* active,
			   int_4 num_act, int_4& ndel);

// functions to manage lexical trees
//
logical_1 update_trees_cc(Train_Link_list* treelist_a);

// functions to build lattice
//
logical_1 build_lattice_cc(Train_Trace** array, int_4 num_hyp, float_4 lmscale,
			   float_4 wdpenalty, Train_Lattice*& lattice);
logical_1 construct_lattice_cc(Train_Trace* trace, Train_Lattice_node* latnode,
			       float_8 score, float_4 lmscale,
			       float_4 wdpenalty, int_4& num_nodes,
			       int_4& num_arcs, Train_Hash_table*& lathash);

logical_1 build_dm_lat_cc(Train_Lattice* lattice_a, Train_Hash_table* words_a);

// function to compute the state index
//
logical_1 get_ind_st_cc(Train_Trace* trace, int_4& st_ind, int_4* mod_map,
			int_4** st_map);

logical_1 count_state_cc(Train_Trace* trace, float_8** data, float_8*** mean,
			 float_8*** covar, int_4** count, int_4 num_feat,
			 int_4 num_st, int_4 num_mix, Train_State** states,
			 int_4* mod_map, int_4** st_map);

logical_1 count_arc_cc(Train_Trace* tr, Train_Trace* pre_tr, int_4*** trans,
		       int_4* trans_map, int_4* mod_map, Train_Model** models);

logical_1 para_estimate_cc(int_4 num_hyps, Train_Trace** array, float_8** data,
			   Train_State** states, Train_Model** models,
			   float_8*** mean,
			   float_8*** covar, int_4** count,
			   int_4 num_feat, int_4 num_st, int_4 num_mix,
			   int_4*** trans, int_4* mod_map,
			   int_4** st_map, int_4* trans_map,
			   int_4 sp_phn_ind);

Train_Phone** read_new_phones_cc(int_4 num_mono, int_4 ph_size,
				 Train_Model** models,
				 int_4*& ph_map, int_4& num_ph, char_1* file,
				 int_4*& mod_map, int_4 context_mode,
				 int_4& sp_phone_ind);

Train_Model** read_new_models_cc(int_4& num_mod, char_1* file,
			   Train_State** states, float_4*** trans,
			   int_4**& st_map, int_4*& trans_map);

logical_1 update_cc(float_4*** transitions, Train_State** states,
		    float_8*** mean, float_8*** covar,
		    int_4** st_count, int_4*** trans_count, int_4* trans_size,
		    int_4 num_feat, int_4 num_st, int_4 num_mix,
		    int_4 num_trans, float_8 var_floor);

logical_1 combine_acc_cc(float_4*** transitions, Train_State** states,
			 int_4* trans_size, int_4 num_st,
			 int_4 num_mix, int_4 num_feat,
			 int_4 num_trans, float_8 var_floor,
			 FILE* fpcc_list, int_4** state_count);

logical_1 dump_stats_cc(FILE* fp_out, float_8*** mean, 
			float_8***covar, int_4** st_count,
			int_4*** trans_count, int_4* trans_size,
			int_4 num_st, int_4 num_mix,
			int_4 num_feat, int_4 num_trans);
  
logical_1 print_state_cc(char_1* file, Train_State** states, int_4 num_st,
			 int_4 num_feat, logical_1 output_mode);

logical_1 print_bin_state_cc(char_1* file, Train_State** states, int_4 num_st,
			     int_4 num_feat);

logical_1 print_ascii_state_cc(char_1* file, Train_State** states, int_4 num_st,
			       int_4 num_feat);

logical_1 print_trans_cc(char_1*file, int_4 num_trans, int_4* trans_size,
			 float_4*** transitions);

logical_1 init_train_cc(int_4 num_states, int_4 num_mix,
			int_4 num_features, float_8*** train_mean,
			float_8*** train_covar, int_4** count,
			int_4 num_trans, int_4 state_num,
			int_4*** trans_count, float_4*** transitions);

logical_1 get_phlist_cc(FILE* fp, int_4* phn_list, char_1** monophones,
			int_4 num_mono, int_4 ph_size,
			int_4 context_mode, int_4* phone_map, int_4* phones,
			int_4& num_ph, int_4 sph_num, int_4* sph_index);

int_4 get_phn_index_cc(char_1* phn_list, char_1** monophones,
		       int_4 num_mono, int_4 ph_size,
		       int_4 context_mode, int_4* phone_map,
		       int_4& mid_phn, int_4 num_sph, int_4* phn_index);

// handling special phones that need special treatment wrt context
//
int_4* read_sph_cc(int_4& num_sph, char_1** monophones, int_4 num_mono,
		   char_1* file);
logical_1 check_sph_cc(int_4 curr_phn, int_4 num_sph, int_4* sph_index);

// end of file
//
#endif



