// file: bw_model_2.cc
//

// isip include files
//
#include "bw_train.h"
#include "bw_train_constants.h"

// method: max_mprob_cc
//
// arguments:
//  float_8& max_mprob : (output) maximum probability of being in current model
//  int_4 frame : (input) the current frame
//  int_4 cur_mod : (input) current model index
//  int_4 end_mod : (input) last model index
//  int_4* model_list : (input) indexes of each model
//  Model** models : (input) the whole sequence of models
//  float_8*** back_prob : (input) backward probabilities
//  float_8** for_probt : (input) forward probabilities for current frame
//
// return a logical flag indicating success
//
// this method calculates the maximum probability of being in the
// current model at the given frame
//
logical_1 comp_maxmp_cc(float_8& max_mprob_a, int_4 frame_a, int_4 cur_mod_a,
			int_4 end_mod_a, int_4* model_list_a,
			Train_Model** models_a, float_8*** back_prob_a,
			float_8** for_probt_a) {

  // local variables
  //
  int_4 mod_ind = (int_4)0;
  int_4 loc_st = (int_4)0;
  int_4 tmp_ind = (int_4)0;
  float_8 tmp_prob = (float_8)0;
  float_4** trans = (float_4**)NULL;
  Train_Model* model = (Train_Model*)NULL;
  
  // assign the initial value
  //
  if (cur_mod_a == 1) {
    max_mprob_a = BW_LOG_ZERO;
  }

  // if this is not the first model
  //
  else {
    mod_ind = model_list_a[cur_mod_a-2];
    model = models_a[mod_ind];
    loc_st = model->get_num_states_cc();

    // if the backward probabilty is null
    // calculate the maximum probability
    //
    if (back_prob_a[frame_a][cur_mod_a-1] != (float_8*)NULL) {
      max_mprob_a = for_probt_a[cur_mod_a-1][loc_st] +
	back_prob_a[frame_a][cur_mod_a-1][loc_st];
    }
    else {
      max_mprob_a = BW_LOG_ZERO;
    }
  
    for (int_4 i = cur_mod_a-1; i>end_mod_a; i--) {
      
      trans = models_a[model_list_a[i-1]]->get_transitions_cc();
      if (trans[0][loc_st-1] > BW_LOG_MIN) {
	tmp_ind = i-1;
	loc_st = models_a[model_list_a[tmp_ind]]->get_num_states_cc();
	if (back_prob_a[frame_a][tmp_ind] != (float_8*)NULL) {
	  tmp_prob = for_probt_a[tmp_ind][loc_st] +
	    back_prob_a[frame_a][tmp_ind][loc_st];
	  if (tmp_prob > max_mprob_a) {
	    max_mprob_a = tmp_prob;
	  }
	}
	else {
	  max_mprob_a = BW_LOG_ZERO;
	}
      }
      else {
	break;
      }
    }
  }

  // compare all model probabilities inside the current model
  //
  model = models_a[model_list_a[cur_mod_a-1]];
  loc_st = model->get_num_states_cc();
  if (back_prob_a[frame_a][cur_mod_a] != (float_8*)NULL) {
    for (int_4 i = 1; i < loc_st; i++) {
      tmp_prob = for_probt_a[cur_mod_a][i] +
	back_prob_a[frame_a][cur_mod_a][i];
      if (tmp_prob > max_mprob_a) {
	max_mprob_a = tmp_prob;
      }
    }
  }

  // clean up
  //
  trans = (float_4**)NULL;
  model = (Train_Model*)NULL;
  
  // exit gracefully
  //
  return(ISIP_TRUE);
}
