root/bdm/stat/emix.h @ 182

Revision 182, 7.9 kB (checked in by smidl, 16 years ago)

compilation error!

  • 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//this comes first because it is used inside emix!
23
24/*! \brief Class representing ratio of two densities
25which arise e.g. by applying the Bayes rule.
26It represents density in the form:
27\f[
28f(rv|rvc) = \frac{f(rv,rvc)}{f(rvc)}
29\f]
30where \f$ f(rvc) = \int f(rv,rvc) d\ rv \f$.
31
32In particular this type of arise by conditioning of a mixture model.
33
34At present the only supported operation is evalcond().
35 */
36class mratio: public mpdf {
37        protected:
38        //! Nominator in the form of mpdf
39                const epdf* nom;
40        //!Denominator in the form of epdf
41                epdf* den;
42        //!flag for destructor
43                bool destroynom;
44        public:
45        //!Default constructor. By default, the given epdf is not copied!
46        //! It is assumed that this function will be used only temporarily.
47                mratio(const epdf* nom0, const RV &rv, bool copy=false):mpdf(rv,RV()){
48                        if (copy){
49//                      nom = nom0->_copy_();
50                                destroynom=true;
51                        } else {
52                                nom = nom0;
53                                destroynom = false;
54                        }
55                        rvc = nom->_rv().subt(rv);
56                        it_assert_debug(rvc.length()>0,"Makes no sense to use this object!");
57                        den = nom->marginal(rvc);
58                };
59                double evalcond(const vec &val, const vec &cond) const {
60                        return exp(nom->evalpdflog(concat(val,cond)) - den->evalpdflog(cond));
61                }
62        //! Object takes ownership of nom and will destroy it
63                void ownnom(){destroynom=true;}
64        //! Default destructor
65                ~mratio(){delete den; if (destroynom) {delete nom;}}
66};
67
68/*!
69* \brief Mixture of epdfs
70
71Density function:
72\f[
73f(x) = \sum_{i=1}^{n} w_{i} f_i(x), \quad \sum_{i=1}^n w_i = 1.
74\f]
75where \f$f_i(x)\f$ is any density on random variable \f$x\f$, called \a component,
76
77*/
78class emix : public epdf {
79protected:
80        //! weights of the components
81        vec w;
82        //! Component (epdfs)
83        Array<epdf*> Coms;
84        //!Flag if owning Coms
85        bool destroyComs;
86public:
87        //!Default constructor
88        emix ( const RV &rv ) : epdf ( rv ) {};
89        //! Set weights \c w and components \c Coms
90        //!By default Coms are copied inside. \param copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor.
91        void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=true );
92
93        vec sample() const;
94        vec mean() const {
95                int i; vec mu = zeros ( rv.count() );
96                for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
97                return mu;
98        }
99        double evalpdflog ( const vec &val ) const {
100                int i;
101                double sum = 0.0;
102                for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * Coms ( i )->evalpdflog ( val );}
103                return log ( sum );
104        };
105        vec evalpdflog_m ( const mat &Val ) const {
106                vec x=ones(Val.cols());
107                vec y(Val.cols());
108                for (int i = 0; i < w.length(); i++ ) {
109                        y = w ( i )*exp(Coms ( i )->evalpdflog_m ( Val ) );
110                        elem_mult_inplace(y,x); //result is in x
111                }
112                return log(x);
113        };
114
115        emix* marginal ( const RV &rv ) const;
116        mratio* condition ( const RV &rv ) const; //why not mratio!!
117
118//Access methods
119        //! returns a pointer to the internal mean value. Use with Care!
120        vec& _w() {return w;}
121        virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}}
122        //! Auxiliary function for taking ownership of the Coms()
123        void ownComs() {destroyComs=true;}
124};
125
126/*! \brief Chain rule decomposition of epdf
127
128Probability density in the form of Chain-rule decomposition:
129\[
130f(x_1,x_2,x_3) = f(x_1|x_2,x_3)f(x_2,x_3)f(x_3)
131\]
132Note that
133*/
134class mprod: public compositepdf, public mpdf {
135protected:
136        //! pointers to epdfs - shortcut to mpdfs()._epdf()
137        Array<epdf*> epdfs;
138        //! Indeces of rvc in common rvc
139        Array<ivec> irvcs_rvc;
140        //! Indeces of common rvc in rvcs
141        Array<ivec> irvc_rvcs;
142public:
143        /*!\brief Constructor from list of mFacs,
144        */
145        mprod ( Array<mpdf*> mFacs ) : compositepdf ( mFacs ), mpdf ( getrv ( true ),RV() ), epdfs ( n ), irvcs_rvc ( n ), irvc_rvcs ( n ) {
146                setrvc ( rv,rvc );
147                setindices ( rv );
148                for ( int i = 0;i < n;i++ ) {
149                        // establish link between rvc and rvcs
150                        rvc.dataind ( mpdfs ( i )->_rvc(), irvc_rvcs ( i ), irvcs_rvc ( i ) );
151                }
152
153                for ( int i=0;i<n;i++ ) {
154                        epdfs ( i ) =& ( mpdfs ( i )->_epdf() );
155                }
156        };
157
158        double evalcond ( const vec &val, const vec &cond ) {
159                int i;
160                double res = 0.0;
161                vec condi;
162                for ( i = n - 1;i >= 0;i-- ) {
163                        if ( ( irvcs_rvc ( i ).length() > 0 ) || ( irvcs_rv ( i ).length() > 0 ) ) {
164                                condi = zeros ( irvcs_rvc ( i ).length() +irvcs_rv ( i ).length() );
165                                //copy part of the rvc into condi
166                                set_subvector ( condi, irvcs_rvc ( i ), get_vec ( cond,irvc_rvcs ( i ) ) );
167                                //copy part of the rv into condi
168                                set_subvector ( condi, irvcs_rv ( i ), get_vec ( val,irv_rvcs ( i ) ) );
169                                mpdfs ( i )->condition ( condi );
170                        }
171                        // add logarithms
172                        res += epdfs ( i )->evalpdflog ( val ( rvsinrv ( i ) ) );
173                }
174                return exp ( res );
175        }
176        vec samplecond ( const vec &cond, double &ll ) {
177                vec smp=zeros ( rv.count() );
178                vec condi;
179                vec smpi;
180                ll = 0;
181                for ( int i = ( n - 1 );i >= 0;i-- ) {
182                        if ( ( irvcs_rvc ( i ).length() > 0 ) || ( irvcs_rv ( i ).length() > 0 ) ) {
183                                condi = zeros ( irvcs_rv ( i ).length() + irvcs_rvc ( i ).length() );
184                                // copy data in condition
185                                set_subvector ( condi,irvcs_rvc ( i ), get_vec ( cond, irvc_rvcs ( i ) ) );
186                                // copy data in already generated sample
187                                set_subvector ( condi,irvcs_rv ( i ), get_vec ( smp,irv_rvcs ( i ) ) );
188
189                                mpdfs ( i )->condition ( condi );
190                        }
191                        smpi = epdfs ( i )->sample();
192                        // copy contribution of this pdf into smp
193                        set_subvector ( smp,rvsinrv ( i ), smpi );
194                        // add ith likelihood contribution
195                        ll+=epdfs ( i )->evalpdflog ( smpi );
196                }
197                return smp;
198        }
199        mat samplecond ( const vec &cond, vec &ll, int N ) {
200                mat Smp ( rv.count(),N );
201                for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond,ll ( i ) ) );}
202                return Smp;
203        }
204
205        ~mprod() {};
206};
207
208//! Product of independent epdfs. For dependent pdfs, use mprod.
209class eprod: public epdf {
210protected:
211        //! Components (epdfs)
212        Array<const epdf*> epdfs;
213        //! Array of indeces
214        Array<ivec> rvinds;
215public:
216        eprod ( const Array<const epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),rvinds ( epdfs.length() ) {
217                bool independent=true;
218                for ( int i=0;i<epdfs.length();i++ ) {
219                        independent=rv.add ( epdfs ( i )->_rv() );
220                        it_assert_debug ( independent==true, "eprod:: given components are not independent ." );
221                        rvinds ( i ) = ( epdfs ( i )->_rv() ).dataind ( rv );
222                }
223        }
224
225        vec mean() const {
226                vec tmp ( rv.count() );
227                for ( int i=0;i<epdfs.length();i++ ) {
228                        vec pom = epdfs ( i )->mean();
229                        set_subvector ( tmp,rvinds ( i ), pom );
230                }
231                return tmp;
232        }
233        vec sample() const {
234                vec tmp ( rv.count() );
235                for ( int i=0;i<epdfs.length();i++ ) {
236                        vec pom = epdfs ( i )->sample();
237                        set_subvector ( tmp,rvinds ( i ), pom );
238                }
239                return tmp;
240        }
241        double evalpdflog ( const vec &val ) const {
242                double tmp=0;
243                for ( int i=0;i<epdfs.length();i++ ) {
244                        tmp+=epdfs ( i )->evalpdflog ( val ( rvinds ( i ) ) );
245                }
246                return tmp;
247        }
248        //!access function
249        const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );}
250};
251
252
253/*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal type
254
255*/
256class mmix : public mpdf {
257protected:
258        //! Component (epdfs)
259        Array<mpdf*> Coms;
260        //!Internal epdf
261        emix Epdf;
262public:
263        //!Default constructor
264        mmix ( RV &rv, RV &rvc ) : mpdf ( rv, rvc ), Epdf ( rv ) {ep = &Epdf;};
265        //! Set weights \c w and components \c R
266        void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
267                Array<epdf*> Eps ( Coms.length() );
268
269                for ( int i = 0;i < Coms.length();i++ ) {
270                        Eps ( i ) = & ( Coms ( i )->_epdf() );
271                }
272                Epdf.set_parameters ( w, Eps );
273        };
274
275        void condition ( const vec &cond ) {
276                for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
277        };
278};
279
280#endif //MX_H
Note: See TracBrowser for help on using the browser.