package yi.iu.imgdb.learn;

import java.util.*;
import yi.stat.nn.*;
import yi.stat.em.*;

/**
 * As a comparison base case, we try use just GMM to give p(I|gmm) instead of
 * breaking the gmm into components.  Since there is only one results for
 * each image, the hidden layer of nn can only have 1 node for 1 feature case,
 * maybe more for multiple feature case
 */

public class GMMNNAdapterNoCompMean extends GMMNNAdapterNoComp{
  public GMMNNAdapterNoCompMean(ImgDataCenter data_center, LinkedList img_list,
                            LinkedList ft_list, LinkedList obj_list) {
    super(data_center, img_list, ft_list, obj_list);

  }

  /**
   * Fake the scores on components as there is only one component.  Actually,
   * the probability from the whole gmm will be returned instead
   * @param gmm
   * @param images
   * @param feature
   * @param fix_low_prob change low prob (like prob(0) to the smallest
   *        valid probability finded in the training stage
   * @return
   */
  double[] scoreOnComponents(GaussianMixtureModel gmm, String img, String feature, String obj) {
    // get the feature vectors
    FeatureRepresentationList features = m_imgDataCenter.getImgFeatureList(
        img, // image name
        feature);

    double[] scores = new double[1];

    // scores are set to 0 first to summarize
    if (features.size() == 0) {
      return scores;
    }

    double[][] data = features.as2DDoubleArray();
    double minimum = ((Double)m_gmmUniformDensity.get(obj, feature)).doubleValue();
    for (int i=0; i<data.length; i++) {
      double[] d = data[i];
      HashMap scores_map = new HashMap();

      double score = 0;
      try {
        score = gmm.getDensity(d);
      } catch (yi.stat.em.ModelSingularException e) {
      }
      scores_map.put(new Integer(1), new Double(score));

      // print out the probabilities under different components
      // since some components may be deleted due to singularity.  its
      // key doesn't continuous any more.  So I sorted them and use that as
      // index
      double[] scores_data = new double[scores_map.size()];
      ArrayList keys = new ArrayList(scores_map.keySet());
      java.util.Collections.sort(keys);
      int j_index = 0;
      for (Iterator j = keys.iterator(); j.hasNext(); j_index++) {
        Object key = j.next();
        double p = ((Double)scores_map.get(key)).doubleValue();
        if (p < minimum) p = minimum;
        scores_data[j_index] = Math.log(p);
      }
      for (int k = 0; k < scores_data.length; k++) {
        scores[k] += scores_data[k];
      }

    }
    for (int k=0; k<scores.length; k++) {
      scores[k] /= data.length;
    }

    return scores;

  }


}