34 #include "discretepdf.h" 35 #include "../wrappers/matrix/vector_wrapper.h" 36 #include "../wrappers/matrix/matrix_wrapper.h" 37 #include "../wrappers/rng/rng.h" 79 Mixture(
const unsigned int dimension=0);
84 template <
typename U>
Mixture(
const U &componentVector);
102 bool SampleFrom (vector<
Sample<T> >& list_samples,
103 const unsigned int num_samples,
104 const SampleMthd method = SampleMthd::DEFAULT,
105 void * args = NULL)
const;
107 bool SampleFrom (
Sample<T>& one_sample,
const SampleMthd method = SampleMthd::DEFAULT,
void * args = NULL)
const;
128 bool WeightsSet(vector<Probability> & weights);
185 , _cumWeights(_numComponents+1)
192 #ifdef __CONSTRUCTOR__ 193 cout <<
"Mixture constructor\n";
194 #endif // __CONSTRUCTOR__ 198 template<
typename T>
template <
typename U>
200 , _numComponents(componentVector.size())
218 (*_componentPdfs)[i] = (componentVector[i])->
Clone();
220 #ifdef __CONSTRUCTOR__ 221 cout <<
"Mixture constructor\n";
222 #endif // __CONSTRUCTOR__ 225 template<
typename T >
227 ,_numComponents(my_mixture.NumComponentsGet())
231 (*_componentWeights) = my_mixture.WeightsGet();
239 (*_componentPdfs)[i] = (my_mixture.ComponentGet(i))->
Clone();
241 #ifdef __CONSTRUCTOR__ 242 cout <<
"Mixture copy constructor\n";
243 #endif // __CONSTRUCTOR__ 249 #ifdef __CONSTRUCTOR__ 250 cout <<
"Mixture destructor\n";
253 delete _componentWeights;
254 for (
int i=0; i<NumComponentsGet();i++)
256 delete (*_componentPdfs)[i];
258 delete _componentPdfs;
264 return new Mixture(*
this);
270 return _numComponents;
277 Probability prob(0.0);
278 for (
int i=0; i<NumComponentsGet();i++)
280 prob= prob + (*_componentWeights)[i] * (*_componentPdfs)[i]->ProbabilityGet(state);
286 bool Mixture<T>::SampleFrom (vector<Sample<T> >& list_samples,
287 const unsigned int num_samples,
288 const SampleMthd method,
294 case SampleMthd::DEFAULT:
297 case SampleMthd::RIPLEY:
299 list_samples.resize(num_samples);
301 std::vector<double> unif_samples(num_samples);
302 for (
unsigned int i = 0; i < num_samples ; i++)
303 unif_samples[i] = runif();
306 unif_samples[num_samples-1] = pow(unif_samples[num_samples-1],
307 double (1.0/num_samples));
309 for (
int i = num_samples-2; i >= 0 ; i--)
310 unif_samples[i] = pow(unif_samples[i],
double (1.0/(i+1))) * unif_samples[i+1];
313 unsigned int index = 0;
314 unsigned int num_states = NumComponentsGet();
315 vector<double>::const_iterator CumPDFit = _cumWeights.begin();
316 typename vector<Sample<T> >::iterator sit = list_samples.begin();
318 for (
unsigned int i = 0; i < num_samples ; i++)
320 while ( unif_samples[i] > *CumPDFit )
323 assert(index <= num_states);
328 (*_componentPdfs)[index-1]->SampleFrom(*sit,method,args);
334 cerr <<
"Mixture::Samplefrom(T, void *): No such sampling method" << endl;
339 bool Mixture<T>::SampleFrom (Sample<T>& one_sample,
const SampleMthd method,
void * args)
const 344 case SampleMthd::DEFAULT:
347 double unif_sample; unif_sample = runif();
349 unsigned int index = 0;
350 while ( unif_sample > _cumWeights[index] )
352 assert(index <= NumComponentsGet());
357 (*_componentPdfs)[index-1]->SampleFrom(one_sample,method,args);
361 cerr <<
"Mixture::Samplefrom(T, void *): No such sampling method" 370 cerr <<
"Mixture ExpectedValueGet: not implemented for the template parameters you use." 371 << endl <<
"Use template specialization as shown in mixture.cpp " << endl;
374 return expectedValue;
377 template <
typename T>
381 cerr <<
"Mixture CovarianceGet: not implemented since so far I don't believe its usefull" 382 << endl <<
"If you decide to implement is: Use template specialization as shown in mcpdf.cpp " << endl;
393 return *_componentWeights;
400 assert((
int)componentNumber >= 0 && componentNumber < NumComponentsGet());
401 return (*_componentWeights)[componentNumber];
408 assert(weights.size() == NumComponentsGet());
409 *_componentWeights = weights;
411 return (NormalizeWeights() && CumWeightsUpdate());
418 assert((
int)componentNumber >= 0 && componentNumber < NumComponentsGet());
419 assert((
double)weight<=1.0);
421 if (NumComponentsGet() == 1)
423 (*_componentWeights)[0] = weight;
430 Probability old_weight = WeightGet(componentNumber);
431 if ((
double)old_weight!=1.0) {
432 double normalization_factor = (1-weight)/(1-old_weight);
433 for (
int i=0; i<NumComponentsGet();i++)
435 (*_componentWeights)[i] = (Probability)( (
double)( (*_componentWeights)[i] )* normalization_factor);
439 for (
int i=0; i<NumComponentsGet();i++)
441 (*_componentWeights)[i] = (Probability)( (1-weight)/(NumComponentsGet()-1));
444 (*_componentWeights)[componentNumber] = weight;
446 return CumWeightsUpdate();
453 int index_mostProbable= -1;
454 Probability prob_mostProbable= 0.0;
455 for (
int component = 0 ; component < NumComponentsGet() ; component++)
457 if ( (*_componentWeights)[component] > prob_mostProbable)
459 index_mostProbable= component;
460 prob_mostProbable= (*_componentWeights)[component];
463 return index_mostProbable;
469 if (NumComponentsGet()==0)
470 return AddComponent(pdf, Probability(1.0));
474 (*_componentPdfs).push_back(pdf.Clone() );
476 (*_componentWeights).push_back(Probability(0.0));
477 _cumWeights.push_back(0.0);
479 assert(NumComponentsGet()==(*_componentPdfs).size());
480 assert(NumComponentsGet()==(*_componentWeights).size());
481 assert(NumComponentsGet()+1==_cumWeights.size());
482 return (NormalizeWeights() && CumWeightsUpdate());
489 if (NumComponentsGet()==0 && w!=1.0)
490 return AddComponent(pdf, Probability(1.0));
494 (*_componentPdfs).push_back(pdf.Clone() );
495 (*_componentWeights).push_back(Probability(0.0));
496 _cumWeights.resize(NumComponentsGet()+1);
498 assert(NumComponentsGet()==(*_componentPdfs).size());
499 assert(NumComponentsGet()==(*_componentWeights).size());
500 assert(NumComponentsGet()+1==_cumWeights.size());
501 WeightSet(_numComponents-1,w);
502 return (NormalizeWeights() && CumWeightsUpdate());
510 assert(NumComponentsGet()==(*_componentPdfs).size());
511 assert(NumComponentsGet()==(*_componentWeights).size());
512 assert(NumComponentsGet()+1==_cumWeights.size());
515 assert((
int)componentNumber >= 0 && componentNumber < NumComponentsGet());
517 Pdf<T>* pointer = (*_componentPdfs)[componentNumber];
519 (*_componentPdfs).erase((*_componentPdfs).begin()+componentNumber);
520 (*_componentWeights).erase((*_componentWeights).begin()+componentNumber);
521 _cumWeights.resize(NumComponentsGet()+1);
523 assert(NumComponentsGet()==(*_componentPdfs).size());
524 assert(NumComponentsGet()==(*_componentWeights).size());
525 assert(NumComponentsGet()+1==_cumWeights.size());
526 if(_numComponents==0)
529 return (NormalizeWeights() && CumWeightsUpdate());
536 return _componentPdfs;
543 return (*_componentPdfs)[componentNumber];
549 if (NumComponentsGet() == 0)
551 cerr <<
"Mixture method called which requires that the number of components is not zero" 552 << endl <<
"Current number of components: " << NumComponentsGet() << endl;
560 double SumOfWeights = 0.0;
561 for (
unsigned int i = 0; i < NumComponentsGet() ; i++){
562 SumOfWeights += (*_componentWeights)[i];
564 if (SumOfWeights > 0){
565 for (
unsigned int i = 0; i < NumComponentsGet() ; i++){
566 (*_componentWeights)[i] = (Probability)( (
double) ( (*_componentWeights)[i]) /SumOfWeights);
571 cerr <<
"Mixture::NormalizeProbs(): SumOfWeights = " << SumOfWeights << endl;
581 static vector<double>::iterator CumWeightsit;
582 CumWeightsit = _cumWeights.begin();
586 for (
unsigned int i = 0; i < NumComponentsGet(); i++)
590 CumSum += ( (*_componentWeights)[i] );
591 *CumWeightsit = CumSum;
594 assert( (_cumWeights[NumComponentsGet()] >= 1.0 - NUMERIC_PRECISION) &&
595 (_cumWeights[NumComponentsGet()] <= 1.0 + NUMERIC_PRECISION) );
597 _cumWeights[NumComponentsGet()]=1;
603 #include "mixture.cpp" MatrixWrapper::SymmetricMatrix CovarianceGet() const
Get the Covariance Matrix E[(x - E[x])^2] of the Analytic pdf.
Class PDF: Virtual Base class representing Probability Density Functions.
virtual bool SampleFrom(vector< Sample< T > > &list_samples, const unsigned int num_samples, const SampleMthd method=SampleMthd::DEFAULT, void *args=NULL) const
Draw multiple samples from the Pdf (overloaded)
vector< Probability > WeightsGet() const
Get all component weights.
int MostProbableComponentGet() const
Get the index of the most probable component, if a few component are.
virtual ~Mixture()
Destructor.
unsigned int NumComponentsGet() const
Get the number of components.
Mixture(const unsigned int dimension=0)
Constructor: An equal weight is set for all components.
Probability WeightGet(unsigned int componentNumber) const
Get the component weight of component "componentNumber".
bool DeleteComponent(unsigned int componentNumber)
Delete a component pdf: THIS IS A NON_REALTIME OPERATION.
Pdf< T > * ComponentGet(unsigned int componentNumber) const
Get the pointer to the component pdf of component "componentNumber".
virtual Mixture * Clone() const
Clone function.
Class representing a mixture of PDFs, the mixture can contain different.
vector< Pdf< T > * > ComponentsGet() const
Get the vector of pointers to the component pdfs.
vector< double > _cumWeights
Vector containing the cumulative component weights (for efficient sampling)
bool WeightsSet(vector< Probability > &weights)
Set all component weights.
bool NormalizeWeights()
Normalize the component weigths (eg. after setting a component weight)
bool WeightSet(unsigned int componentNumber, Probability w)
Function to change/set the weigth of a single component.
unsigned int _numComponents
The number of components.
vector< Probability > * _componentWeights
Pointer to the vector of mixture weights, the sum of the elements = 1.
bool CumWeightsUpdate()
Updates the cumWeights.
Probability ProbabilityGet(const T &state) const
Implementation of virtual base class method.
T ExpectedValueGet() const
Get the expected value E[x] of the pdf.
void TestNotInit() const
Called when a the number of components=0 and if method is called which.
bool AddComponent(Pdf< T > &pdf)
Add a component pdf: THIS IS A NON-REALTIME OPERATION.
Class representing a probability (a double between 0 and 1)
vector< Pdf< T > * > * _componentPdfs
Pointer to the vector of component pdfs.