//Source file: D:\\Projects\\src\\yi\\iu\\imgdb\\learn\\ObjGMMBayCIEAdapter.java

package yi.iu.imgdb.learn;

import yi.stat.em.ControlledIEGMM;
import java.util.*;
import yi.util.data.*;
import yi.stat.em.*;

/**
 * For each object, construct a mixture model.  Each model will be generated by
 * ControlledIEGMM (controlled initialization and controlled E-step).  For
 * example, a model will be trained for "tree" images.  The initial clusters of
 * that model will be generated using images containing "sky", images containing
 * "grass", images containing "tree", etc.  No cluster containing "bg" since
 * that cluster is the same as the "tree" cluster for "tree" images.  For "bg"
 * images, generate initial clusters corresponding to "sky" images, "grass"
 * images, "tree" images and "bg" images.
 */
public class ObjGMMBayCIEAdapter extends ObjGMMBayAdapter
{

  public ObjGMMBayCIEAdapter(ImgDataCenter data_center, LinkedList img_list, LinkedList ft_list, LinkedList obj_list)
  {
    super();
    // copy from  StatModelAdapter(ImgDataCenter data_center, LinkedList img_list, LinkedList ft_list, LinkedList obj_list)
    m_imgDataCenter = data_center;
    m_featureList = (ft_list != null)? ft_list: data_center.getFeatureList();
    m_imageList = (img_list != null)? img_list: data_center.getImageList();
    m_objectList = (obj_list != null)? obj_list: data_center.getObjectList();


    // this method only learns on one feature
    m_feature = (String)m_featureList.getFirst();

    int feature_len = data_center.getFeatureLength(m_feature);

    // learn the objects one by one
    for (Iterator o = m_objectList.iterator(); o.hasNext(); ) {
      Object object = o.next();

      // get training set
      LinkedList posTrainImgs = getPositiveInstances(img_list, object);

      // number of images having the object (it will be used for p(o)
      m_weights.putScore(object, posTrainImgs.size());

      System.out.println();
      System.out.println("learning on " + object + ", #image=" + posTrainImgs.size() + "\n");

      // get the image->objects map and images->feature map
      HashMap feature_map = new HashMap();
      HashMap object_map = new HashMap();
      for (Iterator i = posTrainImgs.iterator(); i.hasNext(); ) {
        String img_name = (String) i.next();
        // get the image feature vectors
        double[][] feature_vects = data_center.getImgFeatureList(img_name,
            m_feature).as2DDoubleArray();
        LinkedList ft_vt_list = Conversion.toLinedList(feature_vects);

        // get the image description keywords
        LinkedList desc_list = (LinkedList) data_center.getImgDescriptions(
            img_name).clone();
        feature_map.put(img_name, ft_vt_list);
        for (Iterator j = desc_list.iterator(); j.hasNext(); ) {
          String desc = (String) j.next();
          // check whether the description is in the object list to learn
          // if not, just remove it
          if (!m_objectList.contains(desc))
            j.remove();
        }
//        System.out.println(img_name + " #desc= " + desc_list.size());
        if (object.toString().compareToIgnoreCase("bg")!=0) {
          desc_list.remove("bg");
        }
//        System.out.println(img_name + "  #obj= " + desc_list.size());
        object_map.put(img_name, desc_list);

      }

      GaussianMixtureModel gmm =
          new ControlledIEGMM(feature_map, object_map); // suppose the data is within [0,1)
      gmm.learnTheModel();

      m_models.put(object, gmm);

    } // end loop of objects

  }
}
