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

Revision 660, 10.1 kB (checked in by smidl, 15 years ago)

doc - doxygen warnings

  • 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 );
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                        utsize=0;
92                }
93};
94UIREGISTER(MemDS);
95
96/*!  \brief Simulate data from a static pdf (epdf)
97
98Trivial 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.
99*/
100
101class EpdfDS: public DS {
102        protected:
103                //! internal pointer to epdf from which we samplecond
104                shared_ptr<epdf> iepdf;
105                //! internal storage of data sample
106                vec dt;
107        public:
108                void step() {
109                        dt=iepdf->sample();
110                }
111                void getdata ( vec &dt_out ) {
112                        dt_out = dt;
113                }
114                void getdata ( vec &dt_out, const ivec &ids ) {
115                        dt_out = dt ( ids );
116                }
117                const RV& _drv() const {
118                        return iepdf->_rv();
119                }
120
121                /*!
122                \code
123                class = "EpdfDS";
124                epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
125                \endcode
126
127                */
128                void from_setting ( const Setting &set ) {
129                        iepdf=UI::build<epdf> ( set,"epdf",UI::compulsory );
130                        bdm_assert(iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly");
131                        dt =  zeros(iepdf->dimension());
132                        dtsize=dt.length();
133                        set_drv(iepdf->_rv(),RV());
134                        utsize =0;
135                        validate();
136                }
137                void validate() {
138                        dt = iepdf->sample();
139                }
140};
141UIREGISTER ( EpdfDS );
142
143/*!  \brief Simulate data from conditional density
144Still having only one density but allowing conditioning on either input or delayed values.
145*/
146class MpdfDS :public DS {
147        protected:
148                //! internal pointer to epdf from which we samplecond
149                shared_ptr<mpdf> impdf;
150                //! internal storage of data sample
151                vec yt;
152                //! input vector
153                vec ut;
154                //! datalink between ut and regressor
155                datalink_buffered ut2rgr;
156                //! datalink between yt and regressor
157                datalink_buffered yt2rgr;
158                //! numeric values of regressor
159                vec rgr;
160               
161        public:
162                void step() {
163                        yt2rgr.step(yt); // y is now history
164                        ut2rgr.filldown ( ut,rgr );
165                        yt2rgr.filldown ( yt,rgr );
166                        yt=impdf->samplecond ( rgr );
167                        ut2rgr.step(ut); //u is now history
168                }
169                void getdata ( vec &dt_out ) {
170                        bdm_assert_debug(dt_out.length()>=utsize+ytsize,"Short output vector");
171                        dt_out.set_subvector(0, yt);
172                        dt_out.set_subvector(ytsize, ut);
173                }
174                void write(const vec &ut0){ut=ut0;}
175
176                /*!
177                \code
178                class = "MpdfDS";
179                mpdf = {class="mpdf_offspring", ...};  // mpdf to simulate
180                --- optional ---
181                init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
182                init_values = [...];                   // vector of initial values corresponding to init_rv
183                \endcode
184
185                If init_rv is not given, init_values are set to zero.
186                */
187                void from_setting ( const Setting &set ) {
188                        impdf=UI::build<mpdf> ( set,"mpdf",UI::compulsory );
189                       
190                        Yrv = impdf->_rv();
191                        // get unique rvs form rvc
192                        RV rgrv0=impdf->_rvc().remove_time();
193                        // input is what in not in Yrv
194                        Urv=rgrv0.subt(Yrv); 
195                        set_drv(Yrv, Urv);
196                        // connect input and output to rvc
197                        ut2rgr.set_connection(impdf->_rvc(), Urv); 
198                        yt2rgr.set_connection(impdf->_rvc(), Yrv); 
199                       
200                        //set history - if given
201                        shared_ptr<RV> rv_ini=UI::build<RV>(set,"init_rv",UI::optional);
202                        if(rv_ini){ // check if
203                                vec val;
204                                UI::get(val, set, "init_values", UI::optional);
205                                if (val.length()!=rv_ini->_dsize()){
206                                        bdm_error("init_rv and init_values fields have incompatible sizes");
207                                } else {
208                                        ut2rgr.set_history(*rv_ini, val);
209                                        yt2rgr.set_history(*rv_ini, val);
210                                }
211                        }
212
213                        yt = zeros ( impdf->dimension() );
214                        rgr = zeros ( impdf->dimensionc() );
215                        ut = zeros(Urv._dsize());
216
217                        ytsize=yt.length();
218                        utsize=ut.length();
219                        dtsize = ytsize+utsize;
220                        validate();
221                }
222                void validate() {
223                        //taken from sample() - shift of history is not done here
224                        ut2rgr.filldown ( ut,rgr );
225                        yt2rgr.filldown ( yt,rgr );
226                        yt=impdf->samplecond ( rgr );
227                }
228};
229UIREGISTER ( MpdfDS );
230
231/*! Pseudovirtual class for reading data from files
232
233*/
234class FileDS: public MemDS {
235
236        public:
237                void getdata ( vec &dt ) {
238                        dt = Data.get_col ( time );
239                }
240
241                void getdata ( vec &dt, const ivec &indices ) {
242                        vec tmp = Data.get_col ( time );
243                        dt = tmp ( indices );
244                }
245
246                //! returns number of data in the file;
247                int ndat() {
248                        return Data.cols();
249                }
250                //! no sense to log this type
251                void log_add ( logger &L ) {};
252                //! no sense to log this type
253                void logit ( logger &L ) {};
254};
255
256/*!
257* \brief Read Data Matrix from an IT file
258
259The 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$!
260
261*/
262class ITppFileDS: public FileDS {
263
264        public:
265                //! Convenience constructor
266                ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
267                        it_file it ( fname );
268                        it << Name ( varname );
269                        it >> Data;
270                        time = 0;
271                        //rowid and delays are ignored
272                };
273
274                ITppFileDS () : FileDS() {
275                };
276
277                void from_setting ( const Setting &set );
278
279                // TODO dodelat void to_setting( Setting &set ) const;
280
281};
282
283UIREGISTER ( ITppFileDS );
284SHAREDPTR ( ITppFileDS );
285
286/*!
287* \brief CSV file data storage
288The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
2891. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
2902. \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.
291
292*/
293class CsvFileDS: public FileDS {
294
295        public:
296                //! Constructor - create DS from a CSV file.
297                CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
298};
299
300
301
302// ARXDs - DELETED
303
304//! State-space data source simulating two densities
305class stateDS : public DS {
306        private:
307                //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
308                shared_ptr<mpdf> IM;
309
310                //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
311                shared_ptr<mpdf> OM;
312
313        protected:
314                //! result storage
315                vec dt;
316                //! state storage
317                vec xt;
318                //! input storage
319                vec ut;
320                //! Logger
321                int L_xt;
322
323        public:
324                void getdata ( vec &dt0 ) {
325                        dt0 = dt;
326                }
327
328                void getdata ( vec &dt0, const ivec &indices ) {
329                        dt0 = dt ( indices );
330                }
331                //! convenience constructor
332                stateDS ( const shared_ptr<mpdf> &IM0, const shared_ptr<mpdf> &OM0, int usize ) : IM ( IM0 ), OM ( OM0 ),
333                                dt ( OM0->dimension() ), xt ( IM0->dimension() ),
334                                ut ( usize ), L_xt ( 0 ) { }
335
336                stateDS() : L_xt ( 0 ) { }
337
338                virtual void step() {
339                        xt = IM->samplecond ( concat ( xt, ut ) );
340                        dt = OM->samplecond ( concat ( xt, ut ) );
341                }
342
343                virtual void log_add ( logger &L ) {
344                        DS::log_add ( L );
345                        L_xt = L.add ( IM->_rv(), "true" );
346                }
347                virtual void logit ( logger &L ) {
348                        DS::logit ( L );
349                        L.logit ( L_xt, xt );
350                }
351
352                /*! UI for stateDS
353
354                The DS is constructed from a structure with fields:
355                \code
356                system = {
357                        type = "stateDS";
358                        //Internal model
359                        IM = { type = "mpdf"; //<-- valid offspring! e.g. "mlnorm"
360                                rv = { //description of x_t
361                                        names=["name1",...];
362                                        sizes=[2,1]; // optional default=[1,1...];
363                                        times=[0,0]; // optional default=[0,0...];
364                                        }
365                                rvu= { //description of  u_t
366                                        //optional default=empty
367                                        }
368
369                                // remaining fields depending on the chosen type
370                                };
371                        //Observation model
372                        OM = { type = "mpdf-offspring";
373                                rv = {}; //description of d_t
374                                rvu = {type="internal", path="system.IM.rvu"}; //description of u_t
375
376                                //remaining fields
377                        }
378                };
379                \endcode
380                */
381                void from_setting ( const Setting &set );
382
383                // TODO dodelat void to_setting( Setting &set ) const;
384
385};
386
387UIREGISTER ( stateDS );
388SHAREDPTR ( stateDS );
389
390}; //namespace
391
392#endif // DS_H
Note: See TracBrowser for help on using the browser.