package yi.iu.imgdb.learn;

import java.util.*;
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 GMMNNAdapterNoComp extends GMMNNAdapter{
  public GMMNNAdapterNoComp(ImgDataCenter data_center, LinkedList img_list,
                            LinkedList ft_list, LinkedList obj_list) {
    super(data_center, img_list, ft_list, obj_list);

    NN_HIDDEN_VAR_NUM = ft_list.size();
  }

  /**
   * 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);

    // if the image doesn't has any feature vector for the feature, then the
    // score for the components should be all 0
    if (features.size() == 0) {
      double[] scores = new double[1];
      java.util.Arrays.fill(scores, Double.NEGATIVE_INFINITY);
      return scores;
    }

    double[][] data = features.as2DDoubleArray();
    yi.ds.hash.DoubleScoreHashMap score_map = new yi.ds.hash.DoubleScoreHashMap();
    for (int i=0; i<data.length; i++) {
      double[] d = data[i];

      HashMap scores = new HashMap();

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

      score_map.putScoreWhenHigher(scores);
    }

    // print out the probabilities under different components
    double minimum = ((Double)m_gmmUniformDensity.get(obj, feature)).doubleValue();
    double[] scores = new double[score_map.size()];
    ArrayList keys = new ArrayList(score_map.keySet());
    java.util.Collections.sort(keys);
    int i_index = 0;
    for (Iterator i = keys.iterator(); i.hasNext(); i_index++) {
      Object key = i.next();
      double p = score_map.getScore(key);
      if (p < minimum) p = minimum;
      scores[i_index] = Math.log(p);
    }

    return scores;

  }

}