//Source file: D:\\Projects\\src\\yi\\stat\\em\\ControlledIEBgGMM.java

package yi.stat.em;

import java.util.*;


/**
 * Make the bg object has a uniformed density
 */
public class ControlledIEBgGMM extends ControlledIEGMM
{
  protected HashSet m_allObjects = new HashSet();

  public ControlledIEBgGMM(HashMap feature_map, HashMap cluster_map)
  {
    super(feature_map, cluster_map);
    for (Iterator i=cluster_map.keySet().iterator(); i.hasNext(); ) {
      m_allObjects.addAll((Collection)cluster_map.get(i.next()));
    }
  }

  /**
   * only change the weight of background
   * @param accumulators
   */
  protected void recalculateWeights(ComponentHashMap accumulators) {
    Iterator iter = accumulators.keySet().iterator();
    while (iter.hasNext()) {
      Object key = iter.next();
      // only chan
      if (((String)key).compareToIgnoreCase("bg")==0) {
        GaussianComponent cumulator = (GaussianComponent) accumulators.get(key);
        double prob = cumulator.getProbabilitySum() / m_data.length;
        m_weights.put(key, new Double(prob));
        System.out.println("background weight = " + prob);
      }
    }

  }

  protected HashMap getDensitiesUnderComponents(HashMap cumulators,
                                         HashMap model_probs, double[] data) {
    Collection cand_objs = (Collection)m_clusterMap.get(m_fv2imgMap.get(data));
    if (cand_objs == null) { // because this is a testing data. its objects is un-known
      cand_objs = m_allObjects;
    }

    Iterator iter = cand_objs.iterator();
    HashMap probs = new HashMap();
    double prob_sum = 0;
    while (iter.hasNext()) {
      Object key = iter.next();
      GaussianComponent cumulator = (GaussianComponent) cumulators.get(key);
      try {
        double prob = cumulator.getDensity(data);
        if (((String)key).compareToIgnoreCase("bg")==0) {
          //prob = Math.max(prob, 1);
          prob = 1;
          System.out.println("set " + key + " prob = " + prob);
        }
        double model_prob = ( (Double) model_probs.get(key)).doubleValue();
        prob *= model_prob;
        if (prob > 0) {
          probs.put(key, new Double(prob));
          prob_sum += prob;
        }
      }
      catch (GaussianModelSingularException e) {
        e.printStackTrace();
      }
    }

    // normalize
    iter = probs.keySet().iterator();
    while (iter.hasNext()) {
      Object key = iter.next();
      double prob = ( (Double) probs.get(key)).doubleValue();
      probs.put(key, new Double(prob / prob_sum));
    }
    return probs;
  }

}
