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

package yi.stat.em;

import java.util.*;
import yi.util.data.*;


/**
 * Implement the idea suggested by Jeff.  A feature vector will be added to the
 * clusters corresponding to the objects an image contains.  The probability of an
 * object cluster is predefined (or not?)
 */
public class ControlledInitGMM extends GaussianMixtureModel
{

  protected ControlledInitGMM() {}

  /**
   * Initialize the GaussianMixtureModel using pre-knowledge.
   *
   * @param feature_map Store the mapping from image to its feature vector list.
   *        The key is the name of the image and the value is a double[]
   *        collection
   * @param cluster_map Store the mapping from image to its object list.  The
   *        key is the name of the image and the value is a String collection
   */
  public ControlledInitGMM(HashMap feature_map, HashMap cluster_map)
  {
    // save all the feature vectors (from all the images)
    LinkedList all_data = new LinkedList();

    // for each image
    for (Iterator i= feature_map.keySet().iterator(); i.hasNext(); ) {
      String img = (String)i.next();
      Collection feature_list = (Collection)feature_map.get(img);
      all_data.addAll(feature_list);
      Collection cluster_list = (Collection)cluster_map.get(img);

      // add every feature vector in the image to every object cluster if the
      // object appears in the image cluster
      for (Iterator c = cluster_list.iterator(); c.hasNext(); ) {
        String cluster_name = (String)c.next();
        if (!m_initComponents.containsKey(cluster_name)) {
          MixtureComponential g = (MixtureComponential)createEMComponent();
          m_initComponents.put(cluster_name, g);
        }
        MixtureComponential cluster = (MixtureComponential)m_initComponents.get(cluster_name);
        for (Iterator f = feature_list.iterator(); f.hasNext(); ) {
          double[] data = (double[]) f.next();
          // the data will be added to every cluster from cluster_list, so each
          // one takes the weight of 1/|cluster_list|
          cluster.add(data, 1.0/cluster_list.size());
        }
      }
    }

    m_data = Conversion.to2DDoubleArray(all_data);
    m_numComponents = m_initComponents.size();

    // calculate the weight of each cluster
    super.recalculateWeights(m_initComponents);

  }

  protected void recalculateWeights(ComponentHashMap accumulators) {
//    Iterator iter = accumulators.keySet().iterator();
//    while (iter.hasNext()) {
//      Object key = iter.next();
//      double weight = ((Double)m_weights.get(key)).doubleValue();
//      System.out.println(key.toString() + "=" + weight + "  ");
//    }
  }

}
