#ifndef EM_GAUSSIAN_H
#define EM_GAUSSIAN_H

#include <vector>

class EMGaussian
{
  public:
  public:
    EMGaussian(int cluster_count_);

    void train();
    void add_time(double value);

    void print();

    double get_density_at(double phase) const;
    int get_cluster_count() const;
    double get_loglikelihood() const;

  private:
    void expectation();
    double maximisation();

    int cluster_count;

    class Cluster {
      public:
        Cluster();
        Cluster(double mu_, double sigma_, double weight_);
        double mu;
        double sigma;
        double weight;

        void print();

        double density_at(double value) const;
    };

    class Measurement {
      public:
        Measurement(double value_, int cluster_count);
        double value;
        std::vector<double> alpha;
    };

    std::vector<Cluster> clusters;
    std::vector<Measurement> measurements;
};

#endif // EM_GAUSSIAN_H
