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

package yi.stat.em;

import java.util.*;

public class AlignedGaussianMixtureModel
    extends GaussianMixtureModel {

  public double FAKE_0_COVARIANCE = 1e-16;

  protected AlignedGaussianMixtureModel() {

  }

  public AlignedGaussianMixtureModel(int m, double[][] mu, double[][][] sigma,
                                     double[] w, double[][] data) {
    super(m, mu, sigma, w, data);
  }

  public AlignedGaussianMixtureModel(int m, double[][] data, double[] scale) {
    super(m, data, scale);
  }

  public AlignedGaussianMixtureModel(int m, double[][] data, int[] init_labels) {
    super(m, data, init_labels);
  }


  MixtureComponential createEMComponent() {
    AlignedGaussianComponent c = new AlignedGaussianComponent();
    c.setSigularFixer(m_singularFixer);
    return c;
  }

  /**
   * After re-assign the cases, some models may be changed to "bad".  For
   * example, no case is assigned to it.  Then the old model will be kept
   * instead
   */
  protected void checkModelsIntegrity(HashMap new_components, HashMap old_components) {
    Iterator i = new_components.keySet().iterator();
    while (i.hasNext()) {
      Object key = i.next();
      GaussianComponent component = (GaussianComponent)new_components.get(key);
      try {
        double[] means = component.getMeans();
        double[][] cov = component.getCovariance();
        // check whether there are 0 covariance values.  If there are, use a
        // fake one (small enough) instead
        for (int j=0; j<cov.length; j++) {
          if (cov[j][j] < FAKE_0_COVARIANCE) {
            System.err.println("cov["+j+"]["+j+"] = " + cov[j][j] + ", make it = " + FAKE_0_COVARIANCE);
            cov[j][j] = FAKE_0_COVARIANCE;
          }
        }

      } catch (GaussianModelSingularException e) {
        System.out.println("\"" + key.toString() + "\"" + " is singular: " + e.toString());
        double weight = ((Double)m_weights.get(key)).doubleValue();
        System.out.println("Remove the model (weight = " + weight + ")");
        i.remove();
        continue;
      }
    }
  }


}