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

Revision 739, 6.7 kB (checked in by mido, 14 years ago)

the rest of h to cpp movements, with exception of from_setting and validate to avoid conflicts with Sarka

  • 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        }
105        //! set debug file
106        void set_debug_file ( const string fname ) {
107                if ( DBG ) delete dbg_file;
108                dbg_file = new it_file ( fname );
109                if ( dbg_file ) DBG = true;
110        }
111        //! Set internal parameters used in approximation
112        void set_method ( MERGER_METHOD MTH = DFLT_METHOD, double beta0 = DFLT_beta ) {
113                METHOD = MTH;
114                beta = beta0;
115        }
116        //! Set support points from a pdf by drawing N samples
117        void set_support ( const epdf &overall, int N ) {
118                eSmp.set_statistics ( overall, N );
119                Npoints = N;
120        }
121
122        //! Destructor
123        virtual ~merger_base() {
124                for ( int i = 0; i < Nsources; i++ ) {
125                        delete dls ( i );
126                        delete zdls ( i );
127                }
128                if ( DBG ) delete dbg_file;
129        };
130        //!@}
131
132        //! \name Mathematical operations
133        //!@{
134
135        //!Merge given sources in given points
136        virtual void merge ();
137
138        //! Merge log-likelihood values in points using method specified by parameter METHOD
139        vec merge_points ( mat &lW );
140
141
142        //! sample from merged density
143//! weight w is a
144        vec mean() const;
145
146        mat covariance() const;
147
148        vec variance() const;
149
150        //!@}
151
152        //! \name Access to attributes
153        //! @{
154
155        //! Access function
156        eEmp& _Smp() {
157                return eSmp;
158        }
159
160        //! load from setting
161        void from_setting ( const Setting& set ) {
162                // get support
163                // find which method to use
164                string meth_str;
165                UI::get<string> ( meth_str, set, "method", UI::compulsory );
166                if ( !strcmp ( meth_str.c_str(), "arithmetic" ) )
167                        set_method ( ARITHMETIC );
168                else {
169                        if ( !strcmp ( meth_str.c_str(), "geometric" ) )
170                                set_method ( GEOMETRIC );
171                        else if ( !strcmp ( meth_str.c_str(), "lognormal" ) ) {
172                                set_method ( LOGNORMAL );
173                                set.lookupValue ( "beta", beta );
174                        }
175                }
176                string dbg_file;
177                if ( UI::get ( dbg_file, set, "dbg_file" ) )
178                        set_debug_file ( dbg_file );
179                //validate() - not used
180        }
181
182        void validate() {
183                bdm_assert ( eSmp._w().length() > 0, "Empty support, use set_support()." );
184                bdm_assert ( dim == eSmp._samples() ( 0 ).length(), "Support points and rv are not compatible!" );
185                bdm_assert ( isnamed(), "mergers must be named" );
186        }
187        //!@}
188};
189UIREGISTER ( merger_base );
190SHAREDPTR ( merger_base );
191
192//! Merger using importance sampling with mixture proposal density
193class merger_mix : public merger_base {
194protected:
195        //!Internal mixture of EF models
196        MixEF Mix;
197        //!Number of components in a mixture
198        int Ncoms;
199        //! coefficient of resampling [0,1]
200        double effss_coef;
201        //! stop after niter iterations
202        int stop_niter;
203
204        //! default value for Ncoms
205        static const int DFLT_Ncoms;
206        //! default value for efss_coef;
207        static const double DFLT_effss_coef;
208
209public:
210        //!\name Constructors
211        //!@{
212        merger_mix () : Ncoms ( 0 ), effss_coef ( 0 ), stop_niter ( 0 ) { }
213
214        merger_mix ( const Array<shared_ptr<pdf> > &S ) :
215                        Ncoms ( 0 ), effss_coef ( 0 ), stop_niter ( 0 ) {
216                set_sources ( S );
217        }
218
219        //! Set sources and prepare all internal structures
220        void set_sources ( const Array<shared_ptr<pdf> > &S ) {
221                merger_base::set_sources ( S );
222                Nsources = S.length();
223        }
224
225        //! Set internal parameters used in approximation
226        void set_parameters ( int Ncoms0 = DFLT_Ncoms, double effss_coef0 = DFLT_effss_coef ) {
227                Ncoms = Ncoms0;
228                effss_coef = effss_coef0;
229        }
230        //!@}
231
232        //! \name Mathematical operations
233        //!@{
234
235        //!Merge values using mixture approximation
236        void merge ();
237
238        //! sample from the approximating mixture
239        vec sample () const {
240                return Mix.posterior().sample();
241        }
242        //! loglikelihood computed on mixture models
243        double evallog ( const vec &yt ) const {
244                vec dtf = ones ( yt.length() + 1 );
245                dtf.set_subvector ( 0, yt );
246                return Mix.logpred ( dtf );
247        }
248        //!@}
249
250        //!\name Access functions
251        //!@{
252//! Access function
253        MixEF& _Mix() {
254                return Mix;
255        }
256        //! Access function
257        emix* proposal() {
258                emix* tmp = Mix.epredictor();
259                tmp->set_rv ( rv );
260                return tmp;
261        }
262        //! from_settings
263        void from_setting ( const Setting& set ) {
264                merger_base::from_setting ( set );
265                set.lookupValue ( "ncoms", Ncoms );
266                set.lookupValue ( "effss_coef", effss_coef );
267                set.lookupValue ( "stop_niter", stop_niter );
268        }
269
270        //! @}
271
272};
273UIREGISTER ( merger_mix );
274SHAREDPTR ( merger_mix );
275
276}
277
278#endif // MER_H
Note: See TracBrowser for help on using the browser.