STK++ 0.9.13
STK_Gamma_aj_bk.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._DOT_I..._AT_stkpp.org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Clustering
27 * created on: 5 sept. 2013
28 * Author: iovleff, serge.iovleff@stkpp.org
29 **/
30
35#ifndef STK_GAMMA_AJ_BK_H
36#define STK_GAMMA_AJ_BK_H
37
39#include "../GammaModels/STK_GammaBase.h"
40
41#define MAXITER 400
42#define TOL 1e-8
43
44namespace STK
45{
46template<class Array>class Gamma_aj_bk;
47
48namespace hidden
49{
53template<class Array_>
60
61} // namespace Clust
62
72template<class Array>
73class Gamma_aj_bk: public GammaBase< Gamma_aj_bk<Array> >
74{
75 public:
77 using Base::param_;
78
79 using Base::p_data;
80 using Base::meanjk;
81 using Base::variancejk;
82
98 void randomInit( CArrayXX const* const& p_tik, CPointX const* const& p_tk) ;
100 bool run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) ;
102 inline int computeNbFreeParameters() const
103 { return(this->nbCluster()+p_data()->sizeCols());}
104};
105
106/* Initialize randomly the parameters of the gamma mixture. The centers
107 * will be selected randomly among the data set and the standard-deviation
108 * will be set to 1.
109 */
110template<class Array>
111void Gamma_aj_bk<Array>::randomInit( CArrayXX const* const& p_tik, CPointX const* const& p_tk)
112{
113 // compute moments
114 this->moments(p_tik);
115 // simulate aj
116 for (int j=p_data()->beginCols(); j < p_data()->endCols(); ++j)
117 {
118 Real value= 0.;
119 for (int k= p_tik->beginCols(); k < p_tik->endCols(); ++k)
120 {
121 Real mean = meanjk(j,k), variance = variancejk(j,k);
122 value += p_tk->elt(k) * mean*mean/variance;
123 }
124 param_.shape_[j] = Law::Exponential::rand(value/(this->nbSample()));
125 }
126 // simulates bk
127 for (int k= p_tik->beginCols(); k < p_tik->endCols(); ++k)
128 { param_.scale_[k] = Law::Exponential::rand((this->variancek(k)/this->meank(k)));}
129#ifdef STK_MIXTURE_VERY_VERBOSE
130 stk_cout << _T(" Gamma_aj_bk<Array>::randomInit done\n");
131#endif
132}
133
134/* Compute the weighted mean and the common variance. */
135template<class Array>
136bool Gamma_aj_bk<Array>::run( CArrayXX const* const& p_tik, CPointX const* const& p_tk)
137{
138 bool flag = true;
139 if (!this->moments(p_tik)) { flag = false;}
140 // start estimations of the ajk and bj
141 Real qvalue = this->qValue(p_tik, p_tk);
142 // enter iterative algorithm
143 int iter;
144 for(iter = 0; iter<MAXITER; ++iter)
145 {
146 // compute aj
147 for (int j=p_data()->beginCols(); j<p_data()->endCols(); ++j)
148 {
149 // moment estimate and oldest value
150 Real y = 0, x0 = 0;
151 for (int k= p_tik->beginCols(); k < p_tik->endCols(); ++k)
152 {
153 Real mean = meanjk(j,k), variance = variancejk(j,k);
154 y += p_tk->elt(k) * (param_.meanLog_[k][j] - std::log(param_.scale_[k]));
155 x0 += p_tk->elt(k) * mean*mean/variance;
156 }
157 y /= this->nbSample();
158 x0/= this->nbSample();
159 Real x1 = param_.shape_[j];
160 if ((x0 <=0.) || !Arithmetic<Real>::isFinite(x0))
161 { x0 = 1; flag = false;}
162 // compute shape
164 Real a = x0; // use moment estimate
165 try
166 {
167 a = Algo::findZero(f, x0, x1, 1e-08);
168 }
169 catch (...)
170 {
171 #ifdef STK_MIXTURE_DEBUG
172 stk_cout << "ML estimation failed in Gamma_aj_bk::run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) \n";
173 stk_cout << "x0 =" << x0 << _T("\n";);
174 stk_cout << "f(x0) =" << f(x0) << _T("\n";);
175 stk_cout << "x1 =" << x1 << _T("\n";);
176 stk_cout << "f(x1) =" << f(x1) << _T("\n";);
177 #endif
178 a = x0; // use moment estimate
179 flag = false;
180 }
182 {
183#ifdef STK_MIXTURE_DEBUG
184 stk_cout << _T("ML estimation failed in Gamma_aj_bk::run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) \n");
185 stk_cout << "x0 =" << x0 << _T("\n";);
186 stk_cout << "f(x0) =" << f(x0) << _T("\n";);
187 stk_cout << "x1 =" << x1 << _T("\n";);
188 stk_cout << "f(x1) =" << f(x1) << _T("\n";);
189#endif
190 a = 1.;
191 flag = false;
192 }
193 param_.shape_[j] = a;
194 // compute bk
195 Real sum = param_.shape_.sum();
196 for (int k= p_tik->beginCols(); k < p_tik->endCols(); ++k)
197 { // update bk
198 param_.scale_[k] = param_.mean_[k].sum()/sum;
199 }
200 }
201 // check convergence
202 Real value = this->qValue(p_tik, p_tk);
203#ifdef STK_MIXTURE_VERBOSE
204 if (value < qvalue)
205 {
206 stk_cout << _T("In Gamma_aj_bk::run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) : run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) diverge\n");
207 stk_cout << _T("New value =") << value << _T(", qvalue =") << qvalue << _T("\n");
208 }
209#endif
210 if ((value - qvalue) < TOL) break;
211 qvalue = value;
212 }
213#ifdef STK_MIXTURE_VERBOSE
214 if (iter == MAXITER)
215 {
216 stk_cout << _T("In Gamma_aj_bk::run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) : run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) did not converge\n");
217 stk_cout << _T("qvalue =") << qvalue << _T("\n");
218 }
219#endif
220 return flag;
221}
222
223} // namespace STK
224
225#undef MAXITER
226#undef TOL
227
228#endif /* STK_Gamma_AJ_BK_H */
#define TOL
In this file we implement the exponential law.
#define MAXITER
#define stk_cout
Standard stk output stream.
#define _T(x)
Let x unmodified.
Base class for the gamma models.
Parameters param_
parameters of the derived mixture model.
Real meanjk(int j, int k)
get the weighted mean of the jth variable of the kth cluster.
Real variancejk(int j, int k)
get the weighted variance of the jth variable of the kth cluster.
Gamma_aj_bk is a mixture model of the following form.
Gamma_aj_bk(Gamma_aj_bk const &model)
copy constructor
void randomInit(CArrayXX const *const &p_tik, CPointX const *const &p_tk)
Initialize randomly the parameters of the Gamma mixture.
Gamma_aj_bk(int nbCluster)
default constructor
bool run(CArrayXX const *const &p_tik, CPointX const *const &p_tk)
Compute the run( CArrayXX const* const& p_tik, CPointX const* const& p_tk) .
int computeNbFreeParameters() const
~Gamma_aj_bk()
destructor
GammaBase< Gamma_aj_bk< Array > > Base
virtual Real rand() const
Generate a pseudo Exponential random variate.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Functor computing the difference between the psi function and a fixed value.
Real findZero(IFunction< Function > const &f, Real const &x0, Real const &x1, Real tol)
find the zero of a function.
Arrays::SumOp< Lhs, Rhs >::result_type sum(Lhs const &lhs, Rhs const &rhs)
convenience function for summing two arrays
double Real
STK fundamental type of Real values.
hidden::SliceVisitorSelector< Derived, hidden::MeanVisitor, Arrays::by_col_ >::type_result mean(Derived const &A)
If A is a row-vector or a column-vector then the function will return the usual mean value of the vec...
The namespace STK is the main domain space of the Statistical ToolKit project.
Arithmetic properties of STK fundamental types.
ModelParameters< Clust::Gamma_aj_bk_ > Parameters
Type of the structure storing the parameters of a Gamma_aj_bk model.
Main class for the mixtures traits policy.