Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #if !defined(ALIZE_DistribGD_cpp)
00056 #define ALIZE_DistribGD_cpp
00057
00058 #if defined(_WIN32)
00059 #include <cfloat>
00060 #define ISNAN(x) _isnan(x)
00061
00062
00063 #elif defined(linux) || defined(__linux) || defined(__CYGWIN__) || defined(__APPLE__)
00064 #define ISNAN(x) isnan(x)
00065 #else
00066 #error "Unsupported OS\n"
00067 #endif
00068
00069 #include <new>
00070 #include <cmath>
00071 #include <cstdlib>
00072 #include <memory.h>
00073 #include "DistribGD.h"
00074 #include "alizeString.h"
00075 #include "Feature.h"
00076 #include "Exception.h"
00077 #include "Config.h"
00078
00079 using namespace alize;
00080 using namespace std;
00081
00082
00083 DistribGD::DistribGD(unsigned long vectSize)
00084 :Distrib(vectSize), _covInvVect(_vectSize, _vectSize)
00085 { reset(); }
00086
00087 DistribGD::DistribGD(const Config& c)
00088 :Distrib(c.getParam_vectSize()>0?c.getParam_vectSize():1),
00089 _covInvVect(_vectSize, _vectSize) { reset(); }
00090
00091 void DistribGD::reset()
00092 {
00093
00094 _covVect.setSize(_vectSize);
00095
00096 for (unsigned long i=0; i< _vectSize; i++)
00097 {
00098 _covVect[i] = (rand()+1.0)/(RAND_MAX+1.0);
00099 _meanVect[i] = (double)rand()*2/RAND_MAX - 1.0;
00100 }
00101 computeAll();
00102 }
00103
00104 DistribGD& DistribGD::create(const K&, unsigned long vectSize)
00105 {
00106 DistribGD* p = new (std::nothrow) DistribGD(vectSize);
00107 assertMemoryIsAllocated(p, __FILE__, __LINE__);
00108 return *p;
00109 }
00110
00111 DistribGD& DistribGD::create(const K&, const Config& c)
00112 { return create(K::k, c.getParam_vectSize()); }
00113
00114 DistribGD::DistribGD(const DistribGD& d)
00115 :Distrib(d._vectSize), _covVect(d._covVect), _covInvVect(d._covInvVect)
00116 {
00117 _meanVect = d._meanVect;
00118 _det = d._det;
00119 _cst = d._cst;
00120 }
00121
00122 const Distrib& DistribGD::operator=(const Distrib& d)
00123 {
00124 const DistribGD* p = dynamic_cast<const DistribGD*>(&d);
00125 if (p == NULL)
00126 throw Exception("incompatible distrib", __FILE__, __LINE__);
00127 return operator=(*p);
00128 }
00129
00130 const DistribGD& DistribGD::operator=(const DistribGD& d)
00131 {
00132 if (_vectSize != d.getVectSize())
00133 throw Exception("target distrib vectSize ("
00134 + String::valueOf(_vectSize) + ") != source distrib vectSize ("
00135 + String::valueOf(d._vectSize) + ")", __FILE__, __LINE__);
00136 _meanVect = d._meanVect;
00137 _covInvVect = d._covInvVect;
00138 _covVect = d._covVect;
00139 _det = d._det;
00140 _cst = d._cst;
00141 return *this;
00142 }
00143
00144 bool DistribGD::operator==(const Distrib& d) const
00145 {
00146 const DistribGD* p = dynamic_cast<const DistribGD*>(&d);
00147 return (p != NULL && _meanVect == p->_meanVect &&
00148 _covInvVect == p->_covInvVect);
00149 }
00150
00151 DistribGD& DistribGD::duplicate(const K&) const
00152 { return static_cast<DistribGD&>(clone()); }
00153
00154 Distrib& DistribGD::clone() const
00155 {
00156 DistribGD* p = new (std::nothrow) DistribGD(*this);
00157 assertMemoryIsAllocated(p, __FILE__, __LINE__);
00158 return *p;
00159 }
00160
00161
00162
00163 lk_t DistribGD::computeLK(const Feature& frame) const
00164 {
00165 if (frame.getVectSize() != _vectSize)
00166 throw Exception("distrib vectSize ("
00167 + String::valueOf(_vectSize) + ") != feature vectSize ("
00168 + String::valueOf(frame.getVectSize()) + ")", __FILE__, __LINE__);
00169 real_t tmp = 0.0;
00170 real_t* m = _meanVect.getArray();
00171 real_t* c = _covInvVect.getArray();
00172 Feature::data_t* f = frame.getDataVector();
00173
00174 for (unsigned long i=0; i<_vectSize; i++)
00175 tmp += (f[i] - m[i]) * (f[i] - m[i]) * c[i];
00176
00177 tmp = _cst * exp(-0.5*tmp);
00178 if (ISNAN(tmp))
00179 return EPS_LK;
00180 return tmp;
00181 }
00182
00183 lk_t DistribGD::computeLK(const Feature& frame, unsigned long i) const
00184 {
00185 real_t fm = frame[i] - _meanVect[i];
00186 real_t tmp = _cst * exp(-0.5 * fm * fm * _covInvVect[i]);
00187 if (ISNAN(tmp))
00188 return EPS_LK;
00189 return tmp;
00190 }
00191
00192 void DistribGD::computeAll()
00193 {
00194 real_t* vect = getCovVect().getArray();
00195 assert(vect != NULL);
00196 unsigned long i;
00197
00198
00199
00200 _det = 1.0;
00201 for (i=0; i< _vectSize; i++)
00202 {
00203 _det *= vect[i];
00204 }
00205
00206
00207
00208 for (i=0; i< _vectSize; i++)
00209 {
00210 if( vect[i] == 0.0) { throw Exception( "Assertion 'vect[i] != 0.0' - Can't invert covariance vector - This error is mainly due to bad parametric data !", __FILE__, __LINE__) ; }
00211 _covInvVect[i] = 1.0/vect[i];
00212 }
00213
00214
00215
00216 if (_det > EPS_LK)
00217 _cst = 1.0 / ( pow(_det, 0.5) * pow( PI2 , _vectSize/2.0 ) );
00218 else
00219 _cst = 1.0 / ( pow(EPS_LK, 0.5) * pow( PI2 , _vectSize/2.0 ) );
00220
00221
00222 _covVect.setSize(0, true);
00223 }
00224
00225 void DistribGD::setCov(real_t v, unsigned long i)
00226 {
00227 if (v < MIN_COV)
00228 getCovVect()[i] = MIN_COV;
00229 else
00230 getCovVect()[i] = v;
00231 }
00232
00233 void DistribGD::setCovInv(const K&, real_t v, unsigned long i)
00234 { _covInvVect[i] = v; }
00235
00236 real_t DistribGD::getCov(unsigned long i)
00237 { return getCovVect()[i];}
00238
00239 real_t DistribGD::getCov(unsigned long i) const
00240 { return getCovVect()[i];}
00241
00242 real_t DistribGD::getCovInv(unsigned long i) const {return _covInvVect[i];}
00243
00244 DoubleVector& DistribGD::getCovInvVect() { return _covInvVect; }
00245
00246 const DoubleVector& DistribGD::getCovInvVect() const { return _covInvVect; }
00247
00248 DoubleVector& DistribGD::getCovVect()
00249 {
00250 return const_cast<DoubleVector&>(
00251 const_cast<const DistribGD*>(this)->getCovVect());
00252 }
00253
00254 const DoubleVector& DistribGD::getCovVect() const
00255 {
00256 if (_covVect.size() != _vectSize)
00257 {
00258 _covVect.setSize(_vectSize);
00259 for (unsigned long i=0; i< _vectSize; i++)
00260 {
00261 if (_covInvVect[i] < 1.0/MIN_COV)
00262 _covVect[i] = 1.0/_covInvVect[i];
00263 else
00264 _covVect[i] = MIN_COV;
00265 }
00266 }
00267 return _covVect;
00268 }
00269
00270
00271 String DistribGD::getClassName() const { return "DistribGD"; }
00272
00273 String DistribGD::toString() const
00274 {
00275 String s = Object::toString()
00276 + "\n vectSize = " + String::valueOf(_vectSize)
00277 + "\n det = " + String::valueOf(_det)
00278 + "\n cst = " + String::valueOf(_cst);
00279
00280
00281 if (_covVect.size() != 0)
00282 for (unsigned long i=0; i<_vectSize; i++)
00283 {
00284 s += "\n cov[" + String::valueOf(i) + "] = "
00285 + String::valueOf(_covVect[i])
00286 + " covInv[" + String::valueOf(i) + "] = "
00287 + String::valueOf(_covInvVect[i])
00288 + " mean[" + String::valueOf(i) + "] = "
00289 + String::valueOf(_meanVect[i]);
00290 }
00291 else
00292 for (unsigned long i=0; i<_vectSize; i++)
00293 {
00294 s += "\n covInv[" + String::valueOf(i) + "] = "
00295 + String::valueOf(_covInvVect[i])
00296 + " mean[" + String::valueOf(i) + "] = "
00297 + String::valueOf(_meanVect[i]);
00298 }
00299 return s;
00300 }
00301
00302 DistribGD::~DistribGD() {}
00303
00304 #endif // !defined(ALIZE_DistribGD_cpp)
00305