root/library/bdm/base/datasources.h @ 676

Revision 676, 10.3 kB (checked in by smidl, 15 years ago)

logger refactoring

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Common DataSources.
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 DATASOURCE_H
14#define DATASOURCE_H
15
16
17#include "../base/bdmbase.h"
18#include "../stat/exp_family.h"
19#include "../base/user_info.h"
20
21namespace bdm {
22/*!
23* \brief Memory storage of off-line data column-wise
24
25The data are stored in an internal matrix \c Data . Each column of Data corresponds to one discrete time observation \f$t\f$. Access to this matrix is via indices \c rowid.
26
27The data can be loaded from a file.
28*/
29class MemDS : public DS {
30        protected:
31                //! internal matrix of data
32                mat Data;
33                //! active column in the Data matrix
34                int time;
35                //!  vector of rows that are presented in Dt
36                ivec rowid;
37
38        public:
39                int max_length() {return Data.cols();}
40                void getdata ( vec &dt ) const;
41                void getdata ( vec &dt, const ivec &indeces );
42                void set_drv (const RV &drv,const  RV &urv );
43
44                void write ( const vec &ut ) {
45                        bdm_error ( "MemDS::write is not supported" );
46                }
47
48                void write ( const vec &ut, const ivec &indices ) {
49                        bdm_error ( "MemDS::write is not supported" );
50                }
51
52                void step();
53                //!Default constructor
54                MemDS () {};
55                //! Convenience constructor
56                MemDS ( mat &Dat, ivec &rowid0);
57                /*! Create object from the following structure
58                \code
59                { class = "MemDS";
60                   Data = (...);            // Data matrix or data vector
61                   --- optional ---
62                   drv = {class="RV"; ...} // Identification how rows of the matrix Data will be known to others
63                   time = 0;               // Index of the first column to user_info,
64                   rowid = [1,2,3...];     // ids of rows to be used
65                }
66                \endcode
67               
68                If the optional fields are not given, they will be filled as follows:
69                \code
70                rowid= [0, 1, 2, ...number_of_rows_of_Data];
71                drv = {names=("ch0", "ch1", "ch2", ..."number_of_rows_of_Data");
72                      sizes=( 1    1    1 ...);
73                          times=( 0    0    0 ...);
74                          };
75                time = 0;
76                \endcode
77                If \c rowid is given, \c drv will be named after indeces in rowids.
78               
79                Hence the data provided by method \c getdata() will be full column of matrix Data starting from the first record.
80                */
81                void from_setting(const Setting &set){
82                        UI::get(Data, set, "Data", UI::compulsory);
83                        if(!UI::get(time, set,"time", UI::optional)) {time =0;}
84                        if(!UI::get(rowid, set, "rowid",UI::optional)) {rowid =linspace(0,Data.rows()-1);}
85                        shared_ptr<RV> r=UI::build<RV>(set,"drv",UI::optional);
86                        if (!r) {r=new RV();
87                                for (int i=0; i<rowid.length(); i++){ r->add(RV("ch"+num2str(rowid(i)), 1, 0));}
88                        }
89                        set_drv(*r,RV()); //empty urv
90                        dtsize=r->_dsize();
91                        ytsize = dtsize;
92                        utsize=0;
93                }
94};
95UIREGISTER(MemDS);
96
97/*!  \brief Simulate data from a static pdf (epdf)
98
99Trivial example of a data source, could be used for tests of some estimation algorithms. For example, simulating data from a mixture model and feeding them to mixture model estimators.
100*/
101
102class EpdfDS: public DS {
103        protected:
104                //! internal pointer to epdf from which we samplecond
105                shared_ptr<epdf> iepdf;
106                //! internal storage of data sample
107                vec dt;
108        public:
109                void step() {
110                        dt=iepdf->sample();
111                }
112                void getdata ( vec &dt_out ) const {
113                        dt_out = dt;
114                }
115                void getdata ( vec &dt_out, const ivec &ids ) {
116                        dt_out = dt ( ids );
117                }
118                const RV& _drv() const {
119                        return iepdf->_rv();
120                }
121
122                /*!
123                \code
124                class = "EpdfDS";
125                epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
126                \endcode
127
128                */
129                void from_setting ( const Setting &set ) {
130                        iepdf=UI::build<epdf> ( set,"epdf",UI::compulsory );
131                        bdm_assert(iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly");
132                        dt =  zeros(iepdf->dimension());
133                        dtsize=dt.length();
134                        set_drv(iepdf->_rv(),RV());
135                        utsize =0;
136                        validate();
137                }
138                void validate() {
139                        dt = iepdf->sample();
140                }
141};
142UIREGISTER ( EpdfDS );
143
144/*!  \brief Simulate data from conditional density
145Still having only one density but allowing conditioning on either input or delayed values.
146*/
147class MpdfDS :public DS {
148        protected:
149                //! internal pointer to epdf from which we samplecond
150                shared_ptr<mpdf> impdf;
151                //! internal storage of data sample
152                vec yt;
153                //! input vector
154                vec ut;
155                //! datalink between ut and regressor
156                datalink_buffered ut2rgr;
157                //! datalink between yt and regressor
158                datalink_buffered yt2rgr;
159                //! numeric values of regressor
160                vec rgr;
161               
162        public:
163                void step() {
164                        yt2rgr.step(yt); // y is now history
165                        ut2rgr.filldown ( ut,rgr );
166                        yt2rgr.filldown ( yt,rgr );
167                        yt=impdf->samplecond ( rgr );
168                        ut2rgr.step(ut); //u is now history
169                }
170                void getdata ( vec &dt_out ) const {
171                        bdm_assert_debug(dt_out.length()>=utsize+ytsize,"Short output vector");
172                        dt_out.set_subvector(0, yt);
173                        dt_out.set_subvector(ytsize, ut);
174                }
175                void write(const vec &ut0){ut=ut0;}
176
177                /*!
178                \code
179                class = "MpdfDS";
180                mpdf = {class="mpdf_offspring", ...};  // mpdf to simulate
181                --- optional ---
182                init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
183                init_values = [...];                   // vector of initial values corresponding to init_rv
184                \endcode
185
186                If init_rv is not given, init_values are set to zero.
187                */
188                void from_setting ( const Setting &set ) {
189                        impdf=UI::build<mpdf> ( set,"mpdf",UI::compulsory );
190                       
191                        Yrv = impdf->_rv();
192                        // get unique rvs form rvc
193                        RV rgrv0=impdf->_rvc().remove_time();
194                        // input is what in not in Yrv
195                        Urv=rgrv0.subt(Yrv); 
196                        set_drv(Yrv, Urv);
197                        // connect input and output to rvc
198                        ut2rgr.set_connection(impdf->_rvc(), Urv); 
199                        yt2rgr.set_connection(impdf->_rvc(), Yrv); 
200                       
201                        //set history - if given
202                        shared_ptr<RV> rv_ini=UI::build<RV>(set,"init_rv",UI::optional);
203                        if(rv_ini){ // check if
204                                vec val;
205                                UI::get(val, set, "init_values", UI::optional);
206                                if (val.length()!=rv_ini->_dsize()){
207                                        bdm_error("init_rv and init_values fields have incompatible sizes");
208                                } else {
209                                        ut2rgr.set_history(*rv_ini, val);
210                                        yt2rgr.set_history(*rv_ini, val);
211                                }
212                        }
213
214                        yt = zeros ( impdf->dimension() );
215                        rgr = zeros ( impdf->dimensionc() );
216                        ut = zeros(Urv._dsize());
217
218                        ytsize=yt.length();
219                        utsize=ut.length();
220                        dtsize = ytsize+utsize;
221                        validate();
222                }
223                void validate() {
224                        //taken from sample() - shift of history is not done here
225                        ut2rgr.filldown ( ut,rgr );
226                        yt2rgr.filldown ( yt,rgr );
227                        yt=impdf->samplecond ( rgr );
228                }
229};
230UIREGISTER ( MpdfDS );
231
232/*! Pseudovirtual class for reading data from files
233
234*/
235class FileDS: public MemDS {
236
237        public:
238                void getdata ( vec &dt ) {
239                        dt = Data.get_col ( time );
240                }
241
242                void getdata ( vec &dt, const ivec &indices ) {
243                        vec tmp = Data.get_col ( time );
244                        dt = tmp ( indices );
245                }
246
247                //! returns number of data in the file;
248                int ndat() {
249                        return Data.cols();
250                }
251                //! no sense to log this type
252                void log_register(logger &L, const string &prefix){};
253                //! no sense to log this type
254                void log_write ( ) const {};
255};
256
257/*!
258* \brief Read Data Matrix from an IT file
259
260The constructor creates an internal matrix \c Data from an IT++ file. The file is binary and can be made using the IT++ library or the Matlab/Octave function itsave. NB: the data are stored columnwise, i.e. each column contains the data for time \f$t\f$!
261
262*/
263class ITppFileDS: public FileDS {
264
265        public:
266                //! Convenience constructor
267                ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
268                        it_file it ( fname );
269                        it << Name ( varname );
270                        it >> Data;
271                        time = 0;
272                        //rowid and delays are ignored
273                };
274
275                ITppFileDS () : FileDS() {
276                };
277
278                void from_setting ( const Setting &set );
279
280                // TODO dodelat void to_setting( Setting &set ) const;
281
282};
283
284UIREGISTER ( ITppFileDS );
285SHAREDPTR ( ITppFileDS );
286
287/*!
288* \brief CSV file data storage
289The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
2901. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
2912. \c BY_ROW if the data are stored the classical CSV style. Then each column stores the values for data item, for ex. \f$[y_{t} y_{t-1} ...]\f$, one row for each discrete time instant.
292
293*/
294class CsvFileDS: public FileDS {
295
296        public:
297                //! Constructor - create DS from a CSV file.
298                CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
299};
300
301
302
303// ARXDs - DELETED
304
305//! State-space data source simulating two densities
306class stateDS : public DS {
307        private:
308                //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
309                shared_ptr<mpdf> IM;
310
311                //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
312                shared_ptr<mpdf> OM;
313
314        protected:
315                //! result storage
316                vec dt;
317                //! state storage
318                vec xt;
319                //! input storage
320                vec ut;
321                //! Logger
322                int L_xt;
323
324        public:
325                void getdata ( vec &dt0 ) {
326                        dt0 = dt;
327                }
328
329                void getdata ( vec &dt0, const ivec &indices ) {
330                        dt0 = dt ( indices );
331                }
332                //! convenience constructor
333                stateDS ( const shared_ptr<mpdf> &IM0, const shared_ptr<mpdf> &OM0, int usize ) : IM ( IM0 ), OM ( OM0 ),
334                                dt ( OM0->dimension() ), xt ( IM0->dimension() ),
335                                ut ( usize ), L_xt ( 0 ) { }
336
337                stateDS() : L_xt ( 0 ) { }
338
339                virtual void step() {
340                        xt = IM->samplecond ( concat ( xt, ut ) );
341                        dt = OM->samplecond ( concat ( xt, ut ) );
342                }
343
344                virtual void log_register(logger &L, const string &prefix){
345                        DS::log_register ( L, prefix ); //ids 0 and 1
346                       
347                        logrec->ids.set_size(3,true);//copy
348                        logrec->ids(2)=logrec->L.add ( IM->_rv(), "true" );
349                }
350                virtual void log_write () {
351                        DS::log_write ( );
352                        logrec->L.logit ( logrec->ids(2), xt );
353                }
354
355                /*! UI for stateDS
356
357                The DS is constructed from a structure with fields:
358                \code
359                system = {
360                        type = "stateDS";
361                        //Internal model
362                        IM = { type = "mpdf"; //<-- valid offspring! e.g. "mlnorm"
363                                rv = { //description of x_t
364                                        names=["name1",...];
365                                        sizes=[2,1]; // optional default=[1,1...];
366                                        times=[0,0]; // optional default=[0,0...];
367                                        }
368                                rvu= { //description of  u_t
369                                        //optional default=empty
370                                        }
371
372                                // remaining fields depending on the chosen type
373                                };
374                        //Observation model
375                        OM = { type = "mpdf-offspring";
376                                rv = {}; //description of d_t
377                                rvu = {type="internal", path="system.IM.rvu"}; //description of u_t
378
379                                //remaining fields
380                        }
381                };
382                \endcode
383                */
384                void from_setting ( const Setting &set );
385
386                // TODO dodelat void to_setting( Setting &set ) const;
387
388};
389
390UIREGISTER ( stateDS );
391SHAREDPTR ( stateDS );
392
393}; //namespace
394
395#endif // DS_H
Note: See TracBrowser for help on using the browser.