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);
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";
198template<
typename T>
template <
typename U>
200 , _numComponents(componentVector.size())
218 (*_componentPdfs)[i] = (componentVector[i])->
Clone();
220#ifdef __CONSTRUCTOR__
221 cout <<
"Mixture constructor\n";
227 ,_numComponents(my_mixture.NumComponentsGet())
231 (*_componentWeights) = my_mixture.
WeightsGet();
241#ifdef __CONSTRUCTOR__
242 cout <<
"Mixture copy constructor\n";
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;
270 return _numComponents;
278 for (
int i=0; i<NumComponentsGet();i++)
280 prob= prob + (*_componentWeights)[i] * (*_componentPdfs)[i]->ProbabilityGet(state);
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;
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;
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;
385 MatrixWrapper::SymmetricMatrix result;
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;
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)
474 (*_componentPdfs).push_back(pdf.
Clone() );
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)
494 (*_componentPdfs).push_back(pdf.
Clone() );
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"
Class representing a mixture of PDFs, the mixture can contain different.
bool CumWeightsUpdate()
Updates the cumWeights.
bool DeleteComponent(unsigned int componentNumber)
Delete a component pdf: THIS IS A NON_REALTIME OPERATION.
vector< Probability > WeightsGet() const
Get all component weights.
Pdf< T > * ComponentGet(unsigned int componentNumber) const
Get the pointer to the component pdf of component "componentNumber".
vector< Pdf< T > * > * _componentPdfs
Pointer to the vector of component pdfs.
virtual Mixture * Clone() const
Clone function.
Probability WeightGet(unsigned int componentNumber) const
Get the component weight of component "componentNumber".
vector< Pdf< T > * > ComponentsGet() const
Get the vector of pointers to the component pdfs.
unsigned int NumComponentsGet() const
Get the number of components.
bool WeightsSet(vector< Probability > &weights)
Set all component weights.
void TestNotInit() const
Called when a the number of components=0 and if method is called which.
Mixture(const unsigned int dimension=0)
Constructor: An equal weight is set for all components.
virtual ~Mixture()
Destructor.
vector< Probability > * _componentWeights
Pointer to the vector of mixture weights, the sum of the elements = 1.
int MostProbableComponentGet() const
Get the index of the most probable component, if a few component are.
T ExpectedValueGet() const
Get the expected value E[x] of the pdf.
MatrixWrapper::SymmetricMatrix CovarianceGet() const
Get the Covariance Matrix E[(x - E[x])^2] of the Analytic pdf.
vector< double > _cumWeights
Vector containing the cumulative component weights (for efficient sampling)
Probability ProbabilityGet(const T &state) const
Implementation of virtual base class method.
bool WeightSet(unsigned int componentNumber, Probability w)
Function to change/set the weigth of a single component.
bool NormalizeWeights()
Normalize the component weigths (eg. after setting a component weight)
bool AddComponent(Pdf< T > &pdf)
Add a component pdf: THIS IS A NON-REALTIME OPERATION.
unsigned int _numComponents
The number of components.
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)
Class PDF: Virtual Base class representing Probability Density Functions.
virtual Pdf< T > * Clone() const =0
Pure virtual clone function.
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)
Class representing a probability (a double between 0 and 1)