23 #ifndef CRNUNIVARIATEGAUSSIANMIXTURE_HEADER
24 #define CRNUNIVARIATEGAUSSIANMIXTURE_HEADER
70 EM(it_begin, it_end, (
unsigned int)(nb_seeds));
103 double ValueAt(
const double x)
const;
105 double ValueAt(
const double x,
size_t k,
bool weight_flag =
false)
const;
108 unsigned int EM(
const MatrixDouble& patterns,
size_t nbSeeds = 2,
double epsilon = std::numeric_limits<double>::epsilon(),
size_t maximalIterations = 100);
110 unsigned int EM(
const std::vector<double> &patterns,
size_t nbSeeds = 2,
double epsilon = std::numeric_limits<double>::epsilon(),
size_t maximalIterations = 100);
112 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);
122 double MLLE(
const std::vector<double> &Data)
const;
124 template<
typename ITER>
double MLLE(ITER it_begin, ITER it_end)
const;
127 double BIC(
double l,
size_t n)
const {
return (-2.0 * log(l) + (
double)members.size() * log((
double)n)) ;}
129 double BIC(
const std::vector<double> &Data)
const {
return (-2.0 *
MLLE(Data) + (
double)members.size() * log((
double)(Data.size()))) ;}
132 std::vector<double>
MakeRandomSample(
size_t n = 1,
size_t m = 100,
bool reseed =
true)
const;
139 bool isValidMemberIndex(
size_t k)
const {
return k < members.size(); }
141 std::vector<std::pair<UnivariateGaussianPDF, double>> members;
146 template<> struct
IsSerializable<UnivariateGaussianMixture> : public std::true_type {};
163 for (
auto it = it_begin; it != it_end; ++it)
164 e +=
double(it->second) * log(
ValueAt(it->first));
182 unsigned int nbIterations = 0;
183 size_t nbMembers = size_t(nbSeeds);
184 size_t nbPatterns = 0;
185 size_t nbKeys = std::distance(it_begin, it_end);
191 auto min_value = std::numeric_limits<double>::infinity();
192 auto max_value = -std::numeric_limits<double>::infinity();
194 for (
auto it = it_begin; it != it_end; ++it)
198 min_value =
Min(min_value, v);
199 max_value =
Max(max_value, v);
200 nbPatterns += it->second;
206 double delta = (max_value - min_value) /
double(nbSeeds);
207 double Seed = min_value + delta / 2.0;
212 for (
size_t k = 0; k < nbMembers; ++k)
218 double sigma = sqrt(var);
224 redo = (
Abs(Seed - it->first) > sigma);
227 if ((it == it_end) && redo)
245 bool Continue =
true;
246 double likelihood = 0.0;
258 for (
size_t i = 0; i < nbKeys; ++i)
260 double xi = it->first;
263 for (
size_t k = 0; k < nbMembers; ++k)
265 double pik = this->
ValueAt(xi, k);
277 for (
size_t k = 0; k < nbMembers; ++k)
279 const auto& Gk = members[k].first;
280 double CumulPk = 0.0;
281 double muk = Gk.GetMean();
288 for (
size_t i = 0; i < nbKeys; ++i)
290 double pik = Proba[i][k];
291 double xi = it->first;
292 double ni = double(it->second);
296 v += ni * pik *
Sqr(xi - muk);
300 if (std::isfinite(mu) && std::isfinite(v))
311 for (
size_t i = 0; i < nbKeys; ++i)
313 double pik = Proba[i][k];
314 double xi = it->first;
315 double ni = double(it->second);
317 mu += ni * pik * xi / CumulPk;
318 v += ni * pik *
Sqr(xi - muk) / CumulPk;
323 members[k].second = CumulPk / double(nbPatterns);
327 double NewLikelihood =
MLLE(it_begin, it_end);
328 double LikelihoodDiff = fabs(NewLikelihood - likelihood);
330 likelihood = NewLikelihood;
333 Continue = ((nbIterations < maximalIterations) && (LikelihoodDiff > epsilon));
#define CRN_SERIALIZATION_CONSTRUCTOR(classname)
Defines a default constructor from xml element.
Univariate Gaussian distribution.
double GetWeight(size_t k) const
Returns the weight of a given density function.
String ToString() const
Dumps a summary of the mixture to a string.
const T & Max(const T &a, const T &b)
Returns the max of two values.
void AddMember(UnivariateGaussianPDF pdf, double Weight)
Adds a density function.
void SetMember(UnivariateGaussianPDF pdf, double w, size_t k)
Replaces a given density function and its weight.
UnivariateGaussianPDF GetMember(size_t k) const
Returns a given density function.
void Deserialize(xml::Element &el)
double ValueAt(const double x) const
Evaluates a pattern.
UnivariateGaussianMixture(ITER it_begin, ITER it_end, size_t nb_seeds=2)
A UTF32 character string class.
virtual ~UnivariateGaussianMixture() override
Destructor.
size_t GetNbMembers() const noexcept
Returns the number of density functions.
UnivariateGaussianMixture()
Default constructor.
unsigned int EM(const MatrixDouble &patterns, size_t nbSeeds=2, double epsilon=std::numeric_limits< double >::epsilon(), size_t maximalIterations=100)
Expectation Maximization.
UnivariateGaussianMixture & operator=(const UnivariateGaussianMixture &)=delete
double BIC(double l, size_t n) const
Bayes Information Criterion estimation.
void MultRow(size_t r, double v)
Scale one row from matrix.
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
void SortMembersByWeights(bool reverse=false)
Sort members by weights.
Univariate Gaussian mixture.
void Abs(Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr) noexcept
Replaces each pixel by its absolute value.
double BIC(const std::vector< double > &Data) const
Bayes Information Criterion estimation.
const T & Min(const T &a, const T &b)
Returns the min of two values.
#define CRN_DECLARE_CLASS_CONSTRUCTOR(classname)
Declares a class constructor.
double GetVariance(size_t k) const
Returns the variance of a given density function.
CRN_ALIAS_SMART_PTR(ImageBW)
std::vector< double > MakeRandomSample(size_t n=1, size_t m=100, bool reseed=true) const
Creates a data sample following the mixture's probability law.
void SortMembersByMeans(bool reverse=false)
Sort members by means.
xml::Element Serialize(xml::Element &parent) const
std::tuple< double, double, double > MeanVarDev(const std::vector< double > &v)
Return mean, variance and standard deviation of sample.
void SortMembersByVariances(bool reverse=false)
Sort members by means.
double MLLE(const MatrixDouble &Data) const
Maximum log-likelihood estimation.
double GetMean(size_t k) const
Returns the mean of a given density function.