23 #ifndef CRNMULTIVARIATEGAUSSIANMIXTURE_HEADER
24 #define CRNMULTIVARIATEGAUSSIANMIXTURE_HEADER
67 EM(it_begin, it_end, (
unsigned int)(nb_seeds));
104 double ValueAt(
const std::vector<double> &x,
size_t k,
bool w =
false)
const;
107 unsigned int EM(
const MatrixDouble& patterns,
size_t nbSeeds = 2,
double epsilon = std::numeric_limits<double>::epsilon(),
size_t MaximalIterations = 100);
109 unsigned int EM(
const std::vector<std::vector<double> > &patterns,
size_t nbSeeds = 2,
double epsilon = std::numeric_limits<double>::epsilon(),
size_t MaximalIterations = 100);
122 template<
typename ITER>
unsigned int EM(ITER it_begin, ITER it_end,
size_t nbSeeds = 2,
double epsilon = std::numeric_limits<double>::epsilon(),
size_t MaximalIterations = 100)
124 unsigned int nbIterations = 0;
125 size_t nbMembers = nbSeeds;
126 size_t nbKeys = std::distance(it_begin, it_end);
127 size_t nbPatterns = 0;
129 for (
auto it = it_begin; it != it_end; ++it)
130 nbPatterns += it->second;
132 dimension = it_begin->first.size();
144 std::vector<MatrixDouble> seeds;
149 for (
size_t d = 0; d < dimension; ++d)
151 auto min = std::numeric_limits<double>::infinity();
152 auto max = -std::numeric_limits<double>::infinity();
155 for (
size_t k = 0; k < nbKeys; ++k)
157 double v(it->first[d]);
164 double delta = (max - min) / (
double(nbMembers) - 1.0);
168 for (
size_t k = 0; k < nbMembers; ++k)
169 sample[k][0] = min +
double(k) * delta;
171 seeds.push_back(sample);
176 for (
size_t d = 0; d < dimension; ++d)
180 seeds.push_back(sample);
184 for (
size_t k = 0; k < nbMembers; ++k)
190 for (
size_t d = 0; d < dimension; ++d)
191 m[d][0] = seeds[d][k][0];
205 double likelihood = - std::numeric_limits<double>::infinity();
212 while (reloop && (nbIterations < MaximalIterations))
220 for (
size_t i = 0; i < nbKeys; ++i)
222 const auto& xi = it->first;
224 for (
auto count = 0; count < it->second; ++count)
228 for (
size_t k = 0; k < nbMembers; ++k)
244 for (
size_t k = 0; k < nbMembers; ++k)
246 double cumulPk = 0.0;
253 std::vector<double> tmp_pattern(dimension);
255 for (
size_t i = 0; i < nbKeys; ++i)
257 double pik = proba[i][k];
259 for (
auto count = 0; count < it->second; ++count)
264 for (
size_t j = 0; j < dimension; ++j)
266 double val = it->first[j];
268 mu[j][0] += val * pik;
269 tmp_pattern[j] = val - mean_k[j][0];
272 for (
size_t r = 0; r < dimension; ++r)
273 for (
size_t c = 0; c < dimension; ++c)
274 m[r][c] = tmp_pattern[r] * tmp_pattern[c];
283 double invCumulPk = 1.0 / cumulPk;
288 members[k].second = double(cumulPk) / double(nbPatterns);
292 double newLikelihood =
MLLE(it_begin, it_end);
293 double likelihoodDiff = newLikelihood - likelihood;
295 likelihood = newLikelihood;
300 if (likelihoodDiff < 0.0)
303 reloop =
IsValid() && (likelihoodDiff > epsilon);
317 double MLLE(
const std::vector< std::vector<double> > &data)
const;
319 template<
typename ITER>
double MLLE(ITER it_begin, ITER it_end)
const
323 for (
auto it = it_begin; it != it_end; ++it)
324 e +=
double(it->second) * log(
ValueAt(it->first));
334 bool isValidMemberIndex(
size_t k)
const {
return k < members.size(); }
336 std::vector<std::pair<MultivariateGaussianPDF, double>> members;
Multivariate gaussian mixture.
std::vector< double > MeanPattern(const std::vector< std::vector< double >> &m)
Return mean pattern of sample.
void SetTo(const MultivariateGaussianMixture &m)
Set mixture from another one.
unsigned int EM(const MatrixDouble &patterns, size_t nbSeeds=2, double epsilon=std::numeric_limits< double >::epsilon(), size_t MaximalIterations=100)
Expectation Maximization.
const T & Max(const T &a, const T &b)
Returns the max of two values.
double MLLE(const MatrixDouble &data) const
Maximum log-likelihood estimation.
size_t GetNbMembers() const noexcept
Returns the number of density functions.
void SetMember(const MultivariateGaussianPDF &pdf, double w, size_t k)
Replaces a given density function and its weight.
void AddMember(const MultivariateGaussianPDF &pdf, double Weight)
Adds a density function.
A UTF32 character string class.
double GetWeight(size_t k) const
Returns the weight of a given density function.
virtual ~MultivariateGaussianMixture() override
Destructor.
std::vector< std::vector< double > > MakeCovariance(const std::vector< std::vector< double >> &m)
Return covariance for sample.
String ToString() const
Dumps a summary of the mixture to a string.
MultivariateGaussianMixture(size_t d)
Default constructor.
MultivariateGaussianMixture & operator=(const MultivariateGaussianMixture &)=default
void MultRow(size_t r, double v)
Scale one row from matrix.
double ValueAt(const MatrixDouble &X) const
Evaluates a pattern.
void SetAll(const T &v)
Set all elements.
size_t GetDimension() const noexcept
Returns the number of features.
MultivariateGaussianPDF GetMember(size_t k) const
Returns a given density function.
const T & Min(const T &a, const T &b)
Returns the min of two values.
SquareMatrixDouble GetVariance(size_t k) const
Returns the variance of a given density function.
bool IsValid() const
Test if mixture is valid i.e. if all paratemers have finite values.
void SetDimension(size_t k) noexcept
Sets the number of features.
#define CRN_DECLARE_CLASS_CONSTRUCTOR(classname)
Declares a class constructor.
Square double matrix class.
MultivariateGaussianMixture()
Default constructor.
Multivariate Gaussian distribution.
unsigned int EM(ITER it_begin, ITER it_end, size_t nbSeeds=2, double epsilon=std::numeric_limits< double >::epsilon(), size_t MaximalIterations=100)
double MLLE(ITER it_begin, ITER it_end) const
Maximum log-likelihood estimation.
MatrixDouble GetMean(size_t k) const
Returns the mean of a given density function.
MultivariateGaussianMixture(ITER it_begin, ITER it_end, size_t nb_seeds=2)