root/bdm/stat/emix.h @ 176

Revision 176, 5.1 kB (checked in by smidl, 16 years ago)

Corrections to mixtures & merger

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Probability distributions for Mixtures of pdfs
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef MX_H
14#define MX_H
15
16#include "libBM.h"
17#include "libEF.h"
18//#include <std>
19
20using namespace itpp;
21
22/*!
23* \brief Mixture of epdfs
24
25Density function:
26\f[
27f(x) = \sum_{i=1}^{n} w_{i} f_i(x), \quad \sum_{i=1}^n w_i = 1.
28\f]
29where \f$f_i(x)\f$ is any density on random variable \f$x\f$, called \a component,
30
31*/
32class emix : public epdf {
33protected:
34        //! weights of the components
35        vec w;
36        //! Component (epdfs)
37        Array<epdf*> Coms;
38public:
39        //!Default constructor
40        emix ( RV &rv ) : epdf ( rv ) {};
41        //! Set weights \c w and components \c R
42        void set_parameters ( const vec &w, const Array<epdf*> &Coms );
43
44        vec sample() const;
45        vec mean() const {
46                int i; vec mu = zeros ( rv.count() );
47                for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
48                return mu;
49        }
50        double evalpdflog ( const vec &val ) const {
51                int i;
52                double sum = 0.0;
53                for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * Coms ( i )->evalpdflog ( val );}
54                return log ( sum );
55        };
56
57//Access methods
58        //! returns a pointer to the internal mean value. Use with Care!
59        vec& _w() {return w;}
60};
61
62/*! \brief Chain rule decomposition of epdf
63
64Probability density in the form of Chain-rule decomposition:
65\[
66f(x_1,x_2,x_3) = f(x_1|x_2,x_3)f(x_2,x_3)f(x_3)
67\]
68Note that
69*/
70class mprod: public compositepdf, public mpdf {
71protected:
72        // pointers to epdfs
73        Array<epdf*> epdfs;
74        //! Indeces of rvc in common rvc
75        Array<ivec> rvcinds;
76public:
77        /*!\brief Constructor from list of mFacs,
78        Additional parameter overlap is left for future use. Do not set to true for mprod.
79        */
80        mprod ( Array<mpdf*> mFacs): compositepdf(mFacs), mpdf(getrv(true),RV()), epdfs(n), rvcinds(n)
81        {       setrvc(rv,rvc);
82                setrvcinrv(rvc,rvcinds);
83                setindices(rv); 
84        for(int i=0;i<n;i++){epdfs(i)=&(mpdfs(i)->_epdf());}
85        };
86
87        double evalpdflog ( const vec &val ) const {
88                int i;
89                double res = 0.0;
90                for ( i = n - 1;i > 0;i++ ) {
91                        if ( rvcinds ( i ).length() > 0 )
92                                {mpdfs ( i )->condition ( val ( rvcinds ( i ) ) );}
93                        // add logarithms
94                        res += epdfs ( i )->evalpdflog ( val ( rvsinrv ( i ) ) );
95                }
96                return res;
97        }
98        vec samplecond ( const vec &cond, double &ll ) {
99                vec smp=zeros ( rv.count() );
100                vec condi;
101                vec smpi;
102                ll = 0;
103                for ( int i = ( n - 1 );i >= 0;i-- ) {
104                        if ( rvcinds ( i ).length() > 0 ) {
105                                condi = zeros ( rvcsinrv.length() + rvcinds.length() );
106                                // copy data in condition
107                                set_subvector ( condi,rvcinds ( i ), cond );
108                                // copy data in already generated sample
109                                set_subvector ( condi,rvcsinrv ( i ), smp );
110
111                                mpdfs ( i )->condition ( condi );
112                        }
113                        smpi = epdfs ( i )->sample();
114                        // copy contribution of this pdf into smp
115                        set_subvector ( smp,rvsinrv ( i ), smpi );
116                        // add ith likelihood contribution
117                        ll+=epdfs ( i )->evalpdflog ( smpi );
118                }
119                return smp;
120        }
121        mat samplecond ( const vec &cond, vec &ll, int N ) {
122                mat Smp ( rv.count(),N );
123                for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond,ll ( i ) ) );}
124                return Smp;
125        }
126
127        ~mprod() {};
128};
129
130//! Product of independent epdfs. For dependent pdfs, use mprod.
131class eprod: public epdf {
132protected:
133        //! Components (epdfs)
134        Array<const epdf*> epdfs;
135        //! Array of indeces
136        Array<ivec> rvinds;
137public:
138        eprod ( const Array<const epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),rvinds ( epdfs.length() ) {
139                bool independent=true;
140                for ( int i=0;i<epdfs.length();i++ ) {
141                        independent=rv.add ( epdfs ( i )->_rv() );
142                        it_assert_debug ( independent==true, "eprod:: given components are not independent ." );
143                        rvinds ( i ) = ( epdfs ( i )->_rv() ).dataind ( rv );
144                }
145        }
146
147        vec mean() const {
148                vec tmp ( rv.count() );
149                for ( int i=0;i<epdfs.length();i++ ) {
150                        vec pom = epdfs ( i )->mean();
151                        set_subvector ( tmp,rvinds ( i ), pom );
152                }
153                return tmp;
154        }
155        vec sample() const {
156                vec tmp ( rv.count() );
157                for ( int i=0;i<epdfs.length();i++ ) {
158                        vec pom = epdfs ( i )->sample();
159                        set_subvector ( tmp,rvinds ( i ), pom );
160                }
161                return tmp;
162        }
163        double evalpdflog ( const vec &val ) const {
164                double tmp=0;
165                for ( int i=0;i<epdfs.length();i++ ) {
166                        tmp+=epdfs(i)->evalpdflog(val(rvinds(i)));
167                }
168                return tmp;
169        }
170        //!access function
171        const epdf* operator () (int i) const {it_assert_debug(i<epdfs.length(),"wrong index");return epdfs(i);}
172};
173
174
175/*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal type
176
177*/
178class mmix : public mpdf {
179protected:
180        //! Component (epdfs)
181        Array<mpdf*> Coms;
182        //!Internal epdf
183        emix Epdf;
184public:
185        //!Default constructor
186        mmix ( RV &rv, RV &rvc ) : mpdf ( rv, rvc ), Epdf ( rv ) {ep = &Epdf;};
187        //! Set weights \c w and components \c R
188        void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
189                Array<epdf*> Eps ( Coms.length() );
190
191                for ( int i = 0;i < Coms.length();i++ ) {
192                        Eps ( i ) = & ( Coms ( i )->_epdf() );
193                }
194                Epdf.set_parameters ( w, Eps );
195        };
196
197        void condition ( const vec &cond ) {
198                for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
199        };
200};
201#endif //MX_H
Note: See TracBrowser for help on using the browser.