root/library/bdm/stat/merger.h @ 799

Revision 799, 7.1 kB (checked in by smidl, 14 years ago)

making testsuite work again

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Mergers for combination 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 MERGER_H
14#define MERGER_H
15
16
17#include "../estim/mixtures.h"
18#include "discrete.h"
19
20namespace bdm {
21using std::string;
22
23//!Merging methods
24enum MERGER_METHOD {ARITHMETIC = 1, GEOMETRIC = 2, LOGNORMAL = 3};
25
26/*!
27@brief Base class for general combination of pdfs on discrete support
28
29Mixtures of Gaussian densities are used internally. Switching to other densities should be trivial.
30
31The merged pdfs are expected to be of the form:
32 \f[ f(x_i|y_i),  i=1..n \f]
33where the resulting merger is a density on \f$ \cup [x_i,y_i] \f$ .
34Note that all variables will be joined.
35
36As a result of this feature, each source must be extended to common support
37\f[ f(z_i|y_i,x_i) f(x_i|y_i) f(y_i)  i=1..n \f]
38where \f$ z_i \f$ accumulate variables that were not in the original source.
39These extensions are calculated on-the-fly.
40
41However, these operations can not be performed in general. Hence, this class merges only sources on common support, \f$ y_i={}, z_i={}, \forall i \f$.
42For merging of more general cases, use offsprings merger_mix and merger_grid.
43*/
44
45class merger_base : public epdf {
46protected:
47        //! Elements of composition
48        Array<shared_ptr<pdf> > pdfs;
49
50        //! Data link for each pdf in pdfs
51        Array<datalink_m2e*> dls;
52
53        //! Array of rvs that are not modelled by pdfs at all, \f$ z_i \f$
54        Array<RV> rvzs;
55
56        //! Data Links for extension \f$ f(z_i|x_i,y_i) \f$
57        Array<datalink_m2e*> zdls;
58
59        //! number of support points
60        int Npoints;
61
62        //! number of sources
63        int Nsources;
64
65        //! switch of the methoh used for merging
66        MERGER_METHOD METHOD;
67        //! Default for METHOD
68        static const MERGER_METHOD DFLT_METHOD;
69
70        //!Prior on the log-normal merging model
71        double beta;
72        //! default for beta
73        static const double DFLT_beta;
74
75        //! Projection to empirical density (could also be piece-wise linear)
76        eEmp eSmp;
77
78        //! debug or not debug
79        bool DBG;
80
81        //! debugging file
82        it_file* dbg_file;
83public:
84        //! \name Constructors
85        //! @{
86
87        //! Default constructor
88        merger_base () : Npoints ( 0 ), Nsources ( 0 ), DBG ( false ), dbg_file ( 0 ) {
89        }
90
91        //!Constructor from sources
92        merger_base ( const Array<shared_ptr<pdf> > &S );
93
94        //! Function setting the main internal structures
95        void set_sources ( const Array<shared_ptr<pdf> > &Sources );
96
97        //! Set support points from rectangular grid
98        void set_support ( rectangular_support &Sup );
99
100        //! Set support points from dicrete grid
101        void set_support ( discrete_support &Sup ) {
102                Npoints = Sup.points();
103                eSmp.set_parameters ( Sup._Spoints() );
104                eSmp.validate();
105        }
106        //! set debug file
107        void set_debug_file ( const string fname ) {
108                if ( DBG ) delete dbg_file;
109                dbg_file = new it_file ( fname );
110                if ( dbg_file ) DBG = true;
111        }
112        //! Set internal parameters used in approximation
113        void set_method ( MERGER_METHOD MTH = DFLT_METHOD, double beta0 = DFLT_beta ) {
114                METHOD = MTH;
115                beta = beta0;
116        }
117        //! Set support points from a pdf by drawing N samples
118        void set_support ( const epdf &overall, int N ) {
119                eSmp.set_statistics ( overall, N );
120                Npoints = N;
121        }
122
123        //! Destructor
124        virtual ~merger_base() {
125                for ( int i = 0; i < Nsources; i++ ) {
126                        delete dls ( i );
127                        delete zdls ( i );
128                }
129                if ( DBG ) delete dbg_file;
130        };
131        //!@}
132
133        //! \name Mathematical operations
134        //!@{
135
136        //!Merge given sources in given points
137        virtual void merge ();
138
139        //! Merge log-likelihood values in points using method specified by parameter METHOD
140        vec merge_points ( mat &lW );
141
142
143        //! sample from merged density
144//! weight w is a
145        vec mean() const;
146
147        mat covariance() const;
148
149        vec variance() const;
150
151        //! Compute log-probability of argument \c val
152        virtual double evallog ( const vec &val ) const NOT_IMPLEMENTED(0);
153
154        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
155        virtual vec sample() const NOT_IMPLEMENTED(0);
156
157        //!@}
158
159        //! \name Access to attributes
160        //! @{
161
162        //! Access function
163        eEmp& _Smp() {
164                return eSmp;
165        }
166
167        //! load from setting
168        void from_setting ( const Setting& set ) {
169                // get support
170                // find which method to use
171                string meth_str;
172                UI::get<string> ( meth_str, set, "method", UI::compulsory );
173                if ( !strcmp ( meth_str.c_str(), "arithmetic" ) )
174                        set_method ( ARITHMETIC );
175                else {
176                        if ( !strcmp ( meth_str.c_str(), "geometric" ) )
177                                set_method ( GEOMETRIC );
178                        else if ( !strcmp ( meth_str.c_str(), "lognormal" ) ) {
179                                set_method ( LOGNORMAL );
180                                set.lookupValue ( "beta", beta );
181                        }
182                }
183                string dbg_file;
184                if ( UI::get ( dbg_file, set, "dbg_file" ) )
185                        set_debug_file ( dbg_file );
186                //validate() - not used
187        }
188
189        void validate() {
190//              bdm_assert ( eSmp._w().length() > 0, "Empty support, use set_support()." );
191//              bdm_assert ( dim == eSmp._samples() ( 0 ).length(), "Support points and rv are not compatible!" );
192                bdm_assert ( isnamed(), "mergers must be named" );
193        }
194        //!@}
195};
196UIREGISTER ( merger_base );
197SHAREDPTR ( merger_base );
198
199//! Merger using importance sampling with mixture proposal density
200class merger_mix : public merger_base {
201protected:
202        //!Internal mixture of EF models
203        MixEF Mix;
204        //!Number of components in a mixture
205        int Ncoms;
206        //! coefficient of resampling [0,1]
207        double effss_coef;
208        //! stop after niter iterations
209        int stop_niter;
210
211        //! default value for Ncoms
212        static const int DFLT_Ncoms;
213        //! default value for efss_coef;
214        static const double DFLT_effss_coef;
215
216public:
217        //!\name Constructors
218        //!@{
219        merger_mix () : Ncoms ( 0 ), effss_coef ( 0 ), stop_niter ( 0 ) { }
220
221        merger_mix ( const Array<shared_ptr<pdf> > &S ) :
222                        Ncoms ( 0 ), effss_coef ( 0 ), stop_niter ( 0 ) {
223                set_sources ( S );
224        }
225
226        //! Set sources and prepare all internal structures
227        void set_sources ( const Array<shared_ptr<pdf> > &S ) {
228                merger_base::set_sources ( S );
229                //Nsources = S.length();
230        }
231
232        //! Set internal parameters used in approximation
233        void set_parameters ( int Ncoms0 = DFLT_Ncoms, double effss_coef0 = DFLT_effss_coef ) {
234                Ncoms = Ncoms0;
235                effss_coef = effss_coef0;
236        }
237        //!@}
238
239        //! \name Mathematical operations
240        //!@{
241
242        //!Merge values using mixture approximation
243        void merge ();
244
245        //! sample from the approximating mixture
246        vec sample () const {
247                return Mix.posterior().sample();
248        }
249        //! loglikelihood computed on mixture models
250        double evallog ( const vec &yt ) const {
251                vec dtf = ones ( yt.length() + 1 );
252                dtf.set_subvector ( 0, yt );
253                return Mix.logpred ( dtf );
254        }
255        //!@}
256
257        //!\name Access functions
258        //!@{
259//! Access function
260        MixEF& _Mix() {
261                return Mix;
262        }
263        //! Access function
264        emix* proposal() {
265                emix* tmp = Mix.epredictor();
266                tmp->set_rv ( rv );
267                return tmp;
268        }
269        //! from_settings
270        void from_setting ( const Setting& set ) {
271                merger_base::from_setting ( set );
272                Ncoms=DFLT_Ncoms;
273                UI::get( Ncoms, set, "ncoms", UI::optional );
274                effss_coef=DFLT_effss_coef;
275                UI::get (effss_coef , set,  "effss_coef", UI::optional);
276                stop_niter=10;
277                UI::get ( stop_niter, set,"stop_niter", UI::optional );
278               
279                validate();
280        }
281        void validate() {
282                bdm_assert(Ncoms>0,"Ncoms too small");
283        }
284
285        //! @}
286
287};
288UIREGISTER ( merger_mix );
289SHAREDPTR ( merger_mix );
290
291}
292
293#endif // MER_H
Note: See TracBrowser for help on using the browser.