62 members.push_back(std::make_pair(pdf, w));
87 if (!isValidMemberIndex(k))
89 _(
"index out of bounds."));
91 return members[k].first;
105 if (!isValidMemberIndex(k))
107 _(
"index out of bounds."));
109 return members[k].second;
123 if (!isValidMemberIndex(k))
125 _(
"index out of bounds."));
127 return members[k].first.GetMean();
141 if (!isValidMemberIndex(k))
143 _(
"index out of bounds."));
145 return members[k].first.GetVariance();
162 if (dimension == dim)
163 members.push_back(std::make_pair(pdf, w));
179 if (isValidMemberIndex(k))
183 if (dimension == dim)
184 members[k] = std::make_pair(pdf, w);
204 for (
auto & elem : members)
205 d += elem.second * elem.first.ValueAt(X);
223 if (!isValidMemberIndex(k))
226 _(
"index out of bounds."));
231 _(
"incompatible dimensions."));
235 return members[k].second * members[k].first.ValueAt(X);
237 return members[k].first.ValueAt(X);
253 if (!isValidMemberIndex(k))
256 _(
"index out of bounds."));
258 else if (x.size() != dimension)
261 _(
"incompatible dimensions."));
264 double val = members[k].first.ValueAt(x);
267 val *= members[k].second;
281 size_t nbPatterns = Data.
GetRows();
286 for (
size_t k = 0; k < nbPatterns; ++k)
288 for (
size_t c = 0; c < dimension; ++c)
289 x.
At(c, 0) = Data[k][c];
308 for (
auto & elem : data)
326 unsigned int nbIterations = 0;
327 size_t nbMembers = nbSeeds;
328 size_t nbPatterns = patterns.
GetRows();
330 dimension = patterns.
GetCols();
342 std::vector<MatrixDouble> g_samples;
347 for (
size_t d = 0; d < dimension; ++d)
353 double delta = (max - min) / (
double(nbMembers) - 1.0);
357 for (
size_t k = 0; k < nbMembers; k++)
358 sample[k][0] = min +
double(k) * delta;
360 g_samples.push_back(sample);
365 for (
size_t d = 0; d < dimension; ++d)
369 g_samples.push_back(sample);
373 for (
size_t k = 0; k < nbMembers; ++k)
379 for (
size_t d = 0; d < dimension; ++d)
380 m[d][0] = g_samples[d][k][0];
393 double likelihood = - std::numeric_limits<double>::infinity();
395 std::vector<double> xi(dimension);
400 while (reloop && (nbIterations < maximalIterations))
406 for (
size_t i = 0; i < nbPatterns; ++i)
409 for (
size_t j = 0; j < dimension; ++j)
410 xi[j] = patterns[i][j];
414 for (
size_t k = 0; k < nbMembers; ++k)
427 for (
size_t k = 0; k < nbMembers; ++k)
429 double cumulPk = 0.0;
435 for (
size_t i = 0; i < nbPatterns; ++i)
437 double pik = proba[i][k];
441 for (
size_t j = 0; j < dimension; ++j)
443 double val = patterns[i][j];
445 mu[j][0] += val * pik;
446 xi[j] = val - mean_k[j][0];
449 for (
size_t r = 0; r < dimension; ++r)
450 for (
size_t c = 0; c < dimension; ++c)
451 m[r][c] = xi[r] * xi[c];
457 double invCumulPk = 1.0 / cumulPk;
462 members[k].second = double(cumulPk) / double(nbPatterns);
466 double newLikelihood =
MLLE(patterns);
467 double likelihoodDiff = newLikelihood - likelihood;
469 likelihood = newLikelihood;
476 if (likelihoodDiff < 0.0)
479 reloop =
IsValid() && (likelihoodDiff > epsilon);
497 unsigned int nbIterations = 0;
498 size_t nbMembers = nbSeeds;
499 size_t nbPatterns = patterns.size();
501 dimension = patterns.front().size();
513 std::vector<MatrixDouble> g_samples;
518 for (
size_t d = 0; d < dimension; ++d)
520 double min = std::numeric_limits<double>::infinity();
521 double max = -std::numeric_limits<double>::infinity();
523 for (
size_t k = 0; k < nbPatterns; ++k)
525 double v = patterns[k][d];
531 double delta = (max - min) / (
double(nbMembers) - 1.0);
535 for (
size_t k = 0; k < nbMembers; ++k)
536 sample[k][0] = min +
double(k) * delta;
538 g_samples.push_back(sample);
543 for (
size_t d = 0; d < dimension; ++d)
547 g_samples.push_back(sample);
551 for (
size_t k = 0; k < nbMembers; ++k)
557 for (
size_t d = 0; d < dimension; ++d)
558 m[d][0] = g_samples[d][k][0];
572 double likelihood = - std::numeric_limits<double>::infinity();
574 std::vector<double> xi;
579 while (reloop && (nbIterations < maximalIterations))
585 for (
size_t i = 0; i < nbPatterns; ++i)
591 for (
size_t k = 0; k < nbMembers; ++k)
604 for (
size_t k = 0; k < nbMembers; ++k)
606 double cumulPk = 0.0;
612 for (
size_t i = 0; i < nbPatterns; ++i)
614 double pik = proba[i][k];
618 for (
size_t j = 0; j < dimension; ++j)
620 double val = patterns[i][j];
622 mu[j][0] += val * pik;
623 xi[j] = val - mean_k[j][0];
626 for (
size_t r = 0; r < dimension; ++r)
627 for (
size_t c = 0; c < dimension; ++c)
628 m[r][c] = xi[r] * xi[c];
634 double invCumulPk = 1.0 / cumulPk;
639 members[k].second = double(cumulPk) / double(nbPatterns);
643 double newLikelihood =
MLLE(patterns);
644 double likelihoodDiff = newLikelihood - likelihood;
646 likelihood = newLikelihood;
651 if (likelihoodDiff < 0.0)
654 reloop =
IsValid() && (likelihoodDiff > epsilon);
669 for (
size_t k = 0; k < members.size(); k++)
686 if (isValidMemberIndex(k))
691 s += members.size() - 1;
692 s += U
"]\nWeight = ";
693 s += members[k].second;
694 s += U
"\n\nMean = \n";
696 s += U
"\nVariance = \n";
size_t GetRows() const noexcept
Returns the number of rows.
Multivariate gaussian mixture.
size_t GetCols() const noexcept
Returns the number of columns.
Matrix MakeCovariance() const
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.
virtual Matrix & Transpose()
Inplace transposition.
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.
Matrix MakeColumn(size_t k) const
Extracts one column from matrix.
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.
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
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.
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.
size_t GetDimension() const noexcept
Returns the number of features.
MultivariateGaussianPDF GetMember(size_t k) const
Returns a given density function.
Matrix MakeColumnMeans() const
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.
const T & At(size_t pos) const noexcept
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.
Square double matrix class.
bool IsValid() const
Check if PDF is valid (with finite values)
A character string class.
Multivariate Gaussian distribution.
MatrixDouble GetMean(size_t k) const
Returns the mean of a given density function.
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.