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

Revision 613, 13.2 kB (checked in by smidl, 15 years ago)

documentation

  • 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_rvs ( RV &drv, RV &urv );
43
44                void write ( vec &ut ) {
45                        bdm_error ( "MemDS::write is not supported" );
46                }
47
48                void write ( vec &ut, ivec &indices ) {
49                        bdm_error ( "MemDS::write is not supported" );
50                }
51
52                void step();
53                //!Default constructor
54                MemDS () {};
55                MemDS ( mat &Dat, ivec &rowid0);
56                /*! Create object from the following structure
57                \code
58                { class = "MemDS";
59                   Data = (...);            // Data matrix or data vector
60                   --- optional ---
61                   drv = {class="RV"; ...} // Identification how rows of the matrix Data will be known to others
62                   time = 0;               // Index of the first column to user_info,
63                   rowid = [1,2,3...];     // ids of rows to be used
64                }
65                \endcode
66               
67                If the optional fields are not given, they will be filled as follows:
68                \code
69                rowid= [0, 1, 2, ...number_of_rows_of_Data];
70                drv = {names=("ch0", "ch1", "ch2", ..."number_of_rows_of_Data");
71                      sizes=( 1    1    1 ...);
72                          times=( 0    0    0 ...);
73                          };
74                time = 0;
75                \endcode
76                If \c rowid is given, \c drv will be named after indeces in rowids.
77               
78                Hence the data provided by method \c getdata() will be full column of matrix Data starting from the first record.
79                */
80                void from_setting(const Setting &set){
81                        UI::get(Data, set, "Data", UI::compulsory);
82                        if(!UI::get(time, set,"time", UI::optional)) {time =0;}
83                        if(!UI::get(rowid, set, "rowid",UI::optional)) {rowid =linspace(0,Data.rows()-1);}
84                        shared_ptr<RV> r=UI::build<RV>(set,"drv",UI::optional);
85                        if (!r) {r=new RV();
86                                for (int i=0; i<rowid.length(); i++){ r->add(RV("ch"+num2str(rowid(i)), 1, 0));}
87                        }
88                        set_drv(*r,RV()); //empty urv
89                        dtsize=r->_dsize();
90                        utsize=0;
91                }
92};
93UIREGISTER(MemDS);
94
95/*!  \brief Simulate data from a static pdf (epdf)
96
97Trivial 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.
98*/
99
100class EpdfDS: public DS {
101        protected:
102                //! internal pointer to epdf from which we samplecond
103                shared_ptr<epdf> iepdf;
104                //! internal storage of data sample
105                vec dt;
106        public:
107                void step() {
108                        dt=iepdf->sample();
109                }
110                void getdata ( vec &dt_out ) {
111                        dt_out = dt;
112                }
113                void getdata ( vec &dt_out, const ivec &ids ) {
114                        dt_out = dt ( ids );
115                }
116                const RV& _drv() {
117                        return iepdf->_rv();
118                }
119
120                /*!
121                \code
122                class = "EpdfDS";
123                epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
124                \endcode
125
126                */
127                void from_setting ( const Setting &set ) {
128                        iepdf=UI::build<epdf> ( set,"epdf",UI::compulsory );
129                        bdm_assert(iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly");
130                        dt =  zeros(iepdf->dimension());
131                        dtsize=dt.length();
132                        set_drv(iepdf->_rv(),RV());
133                        utsize =0;
134                }
135                void validate() {
136                        dt = iepdf->sample();
137                }
138};
139UIREGISTER ( EpdfDS );
140
141/*!  \brief Simulate data from conditional density
142Still having only one density but allowing conditioning on either input or delayed values.
143*/
144class MpdfDS :public DS {
145        protected:
146                //! internal pointer to epdf from which we samplecond
147                shared_ptr<mpdf> impdf;
148                //! internal storage of data sample
149                vec yt;
150                //! input vector
151                vec ut;
152                //! datalink between ut and regressor
153                datalink_buffered ut2rgr;
154                //! datalink between yt and regressor
155                datalink_buffered yt2rgr;
156                //! numeric values of regressor
157                vec rgr;
158               
159        public:
160                void step() {
161                        yt2rgr.step(yt); // y is now history
162                        ut2rgr.filldown ( ut,rgr );
163                        yt2rgr.filldown ( yt,rgr );
164                        yt=impdf->samplecond ( rgr );
165                        ut2rgr.step(ut); //u is now history
166                }
167                void getdata ( vec &dt_out ) {
168                        bdm_assert_debug(dt_out.length()>=utsize+ytsize,"Short output vector");
169                        dt_out.set_subvector(0, yt);
170                        dt_out.set_subvector(ytsize, ut);
171                }
172                void write(const vec &ut0){ut=ut0;}
173
174                /*!
175                \code
176                class = "MpdfDS";
177                mpdf = {class="mpdf_offspring", ...};  // mpdf to simulate
178                --- optional ---
179                init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
180                init_values = [...];                   // vector of initial values corresponding to init_rv
181                \endcode
182
183                If init_rv is not given, init_values are set to zero.
184                */
185                void from_setting ( const Setting &set ) {
186                        impdf=UI::build<mpdf> ( set,"mpdf",UI::compulsory );
187                       
188                        Yrv = impdf->_rv();
189                        // get unique rvs form rvc
190                        RV rgrv0=impdf->_rvc().remove_time();
191                        // input is what in not in Yrv
192                        Urv=rgrv0.subt(Yrv); 
193                        set_drv(Yrv, Urv);
194                        // connect input and output to rvc
195                        ut2rgr.set_connection(impdf->_rvc(), Urv); 
196                        yt2rgr.set_connection(impdf->_rvc(), Yrv); 
197                       
198                        //set history - if given
199                        shared_ptr<RV> rv_ini=UI::build<RV>(set,"init_rv",UI::optional);
200                        if(rv_ini){ // check if
201                                vec val;
202                                UI::get(val, set, "init_values", UI::optional);
203                                if (val.length()!=rv_ini->_dsize()){
204                                        bdm_error("init_rv and init_values fields have incompatible sizes");
205                                } else {
206                                        ut2rgr.set_history(*rv_ini, val);
207                                        yt2rgr.set_history(*rv_ini, val);
208                                }
209                        }
210
211                        yt = zeros ( impdf->dimension() );
212                        rgr = zeros ( impdf->dimensionc() );
213                        ut = zeros(Urv._dsize());
214
215                        ytsize=yt.length();
216                        utsize=ut.length();
217                        dtsize = ytsize+utsize;
218                        validate();
219                }
220                void validate() {
221                        //taken from sample() - shift of history is not done here
222                        ut2rgr.filldown ( ut,rgr );
223                        yt2rgr.filldown ( yt,rgr );
224                        yt=impdf->samplecond ( rgr );
225                }
226};
227UIREGISTER ( MpdfDS );
228
229/*! Pseudovirtual class for reading data from files
230
231*/
232class FileDS: public MemDS {
233
234        public:
235                void getdata ( vec &dt ) {
236                        dt = Data.get_col ( time );
237                }
238
239                void getdata ( vec &dt, const ivec &indices ) {
240                        vec tmp = Data.get_col ( time );
241                        dt = tmp ( indices );
242                }
243
244                //! returns number of data in the file;
245                int ndat() {
246                        return Data.cols();
247                }
248                //! no sense to log this type
249                void log_add ( logger &L ) {};
250                //! no sense to log this type
251                void logit ( logger &L ) {};
252};
253
254/*!
255* \brief Read Data Matrix from an IT file
256
257The 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$!
258
259*/
260class ITppFileDS: public FileDS {
261
262        public:
263                ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
264                        it_file it ( fname );
265                        it << Name ( varname );
266                        it >> Data;
267                        time = 0;
268                        //rowid and delays are ignored
269                };
270
271                ITppFileDS () : FileDS() {
272                };
273
274                void from_setting ( const Setting &set );
275
276                // TODO dodelat void to_setting( Setting &set ) const;
277
278};
279
280UIREGISTER ( ITppFileDS );
281SHAREDPTR ( ITppFileDS );
282
283/*!
284* \brief CSV file data storage
285The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
2861. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
2872. \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.
288
289*/
290class CsvFileDS: public FileDS {
291
292        public:
293                //! Constructor - create DS from a CSV file.
294                CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
295};
296
297
298
299/*!
300\brief Generator of ARX data
301
302*/
303class ArxDS : public DS {
304        protected:
305                //! Rv of the regressor
306                RV Rrv;
307                //! History, ordered as \f$[y_t, u_t, y_{t-1 }, u_{t-1}, \ldots]\f$
308                vec H;
309                //! (future) input
310                vec U;
311                //! temporary variable for regressor
312                vec rgr;
313                //! data link: H -> rgr
314                datalink rgrlnk;
315                //! model of Y - linear Gaussian
316                mlnorm<chmat> model;
317                //! options
318                bool opt_L_theta;
319                //! loggers
320                int L_theta;
321                int L_R;
322                int dt_size;
323        public:
324                void getdata ( vec &dt ) {
325                        dt = H;
326                }
327
328                void getdata ( vec &dt, const ivec &indices ) {
329                        dt = H ( indices );
330                }
331
332                void write ( vec &ut ) {
333                        U = ut;
334                }
335
336                void write ( vec &ut, const ivec &indices ) {
337                        bdm_assert_debug ( ut.length() == indices.length(), "ArxDS" );
338                        set_subvector ( U, indices, ut );
339                }
340
341                void step();
342
343                //!Default constructor
344                ArxDS ( ) {};
345                //! Set parameters of the internal model, H is maximum time delay
346                void set_parameters ( const mat &Th0, const vec mu0, const chmat &sqR0 ) {
347                        model.set_parameters ( Th0, mu0, sqR0 );
348                };
349                //! Set
350                void set_drv ( const RV &yrv, const RV &urv, const RV &rrv ) {
351                        Rrv = rrv;
352                        Urv = urv;
353                        dt_size = yrv._dsize() + urv._dsize();
354
355                        RV drv = concat ( yrv, urv );
356                        Drv = drv;
357                        int td = rrv.mint();
358                        H.set_size ( drv._dsize() * ( -td + 1 ) );
359                        U.set_size ( Urv._dsize() );
360                        for ( int i = -1; i >= td; i-- ) {
361                                drv.t_plus ( -1 );
362                                Drv.add ( drv ); //shift u1
363                        }
364                        rgrlnk.set_connection ( rrv, Drv );
365
366                        dtsize = Drv._dsize();
367                        utsize = Urv._dsize();
368                }
369                //! set options from a string
370                void set_options ( const string &s ) {
371                        opt_L_theta = ( s.find ( "L_theta" ) != string::npos );
372                };
373                virtual void log_add ( logger &L ) {
374                        //DS::log_add ( L ); too long!!
375                        L_dt = L.add ( Drv ( 0, dt_size ), "" );
376                        L_ut = L.add ( Urv, "" );
377
378                        const mat &A = model._A();
379                        const mat R = model._R();
380                        if ( opt_L_theta ) {
381                                L_theta = L.add ( RV ( "{th }", vec_1 ( A.rows() * A.cols() ) ), "t" );
382                        }
383                        if ( opt_L_theta ) {
384                                L_R = L.add ( RV ( "{R }", vec_1 ( R.rows() * R.cols() ) ), "r" );
385                        }
386                }
387                virtual void logit ( logger &L ) {
388                        //DS::logit ( L );
389                        L.logit ( L_dt, H.left ( dt_size ) );
390                        L.logit ( L_ut, U );
391
392                        const mat &A = model._A();
393                        const mat R = model._R();
394                        if ( opt_L_theta ) {
395                                L.logit ( L_theta, vec ( A._data(), A.rows() *A.cols() ) );
396                        };
397                        if ( opt_L_theta ) {
398                                L.logit ( L_R, vec ( R._data(), R.rows() *R.rows() ) );
399                        };
400                }
401
402                // TODO dokumentace - aktualizovat
403                /*! UI for ArxDS using factorized description!
404
405                The ArxDS is constructed from a structure with fields:
406                \code
407                system = {
408                        type = "ArxDS";
409                        // description of y variables
410                        y = {type="rv"; names=["y", "u"];};
411                        // description of u variable
412                        u = {type="rv"; names=[];}
413                        // description of regressor
414                        rgr = {type="rv";
415                                names = ["y","y","y","u"];
416                                times = [-1, -2, -3, -1];
417                        }
418
419                        // theta
420                        theta = [0.8, -0.3, 0.4, 1.0,
421                                         0.0, 0.0, 0.0, 0.0];
422                        // offset (optional)
423                        offset = [0.0, 0.0];
424                        //variance
425                        r = [0.1, 0.0,
426                                 0.0, 1.0];
427                        //options: L_theta = log value of theta,
428                        opt = "L_theta";
429                };
430                \endcode
431
432                Result is ARX data source offering with full history as Drv.
433                */
434                void from_setting ( const Setting &set );
435
436                // TODO dodelat void to_setting( Setting &set ) const;
437};
438
439UIREGISTER ( ArxDS );
440SHAREDPTR ( ArxDS );
441
442class stateDS : public DS {
443        private:
444                //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
445                shared_ptr<mpdf> IM;
446
447                //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
448                shared_ptr<mpdf> OM;
449
450        protected:
451                //! result storage
452                vec dt;
453                //! state storage
454                vec xt;
455                //! input storage
456                vec ut;
457                //! Logger
458                int L_xt;
459
460        public:
461                void getdata ( vec &dt0 ) {
462                        dt0 = dt;
463                }
464
465                void getdata ( vec &dt0, const ivec &indices ) {
466                        dt0 = dt ( indices );
467                }
468
469                stateDS ( const shared_ptr<mpdf> &IM0, const shared_ptr<mpdf> &OM0, int usize ) : IM ( IM0 ), OM ( OM0 ),
470                                dt ( OM0->dimension() ), xt ( IM0->dimension() ),
471                                ut ( usize ), L_xt ( 0 ) { }
472
473                stateDS() : L_xt ( 0 ) { }
474
475                virtual void step() {
476                        xt = IM->samplecond ( concat ( xt, ut ) );
477                        dt = OM->samplecond ( concat ( xt, ut ) );
478                }
479
480                virtual void log_add ( logger &L ) {
481                        DS::log_add ( L );
482                        L_xt = L.add ( IM->_rv(), "true" );
483                }
484                virtual void logit ( logger &L ) {
485                        DS::logit ( L );
486                        L.logit ( L_xt, xt );
487                }
488
489                /*! UI for stateDS
490
491                The DS is constructed from a structure with fields:
492                \code
493                system = {
494                        type = "stateDS";
495                        //Internal model
496                        IM = { type = "mpdf"; //<-- valid offspring! e.g. "mlnorm"
497                                rv = { //description of x_t
498                                        names=["name1",...];
499                                        sizes=[2,1]; // optional default=[1,1...];
500                                        times=[0,0]; // optional default=[0,0...];
501                                        }
502                                rvu= { //description of  u_t
503                                        //optional default=empty
504                                        }
505
506                                // remaining fields depending on the chosen type
507                                };
508                        //Observation model
509                        OM = { type = "mpdf-offspring";
510                                rv = {}; //description of d_t
511                                rvu = {type="internal", path="system.IM.rvu"}; //description of u_t
512
513                                //remaining fields
514                        }
515                };
516                \endcode
517                */
518                void from_setting ( const Setting &set );
519
520                // TODO dodelat void to_setting( Setting &set ) const;
521
522};
523
524UIREGISTER ( stateDS );
525SHAREDPTR ( stateDS );
526
527}; //namespace
528
529#endif // DS_H
Note: See TracBrowser for help on using the browser.