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

Revision 611, 12.3 kB (checked in by smidl, 15 years ago)

new logger - stdlog - designed for easy debuggint in command line

  • 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 =  iepdf->sample();
131                        dtsize=dt.length();
132                        set_drv(iepdf->_rv(),RV());
133                        utsize =0;
134                }
135};
136UIREGISTER ( EpdfDS );
137
138/*!  \brief Simulate data from conditional density
139Still having only one density but allowing conditioning on either input or delayed values.
140*/
141class MpdfDS :public DS {
142        protected:
143                //! internal pointer to epdf from which we samplecond
144                shared_ptr<mpdf> impdf;
145                //! internal storage of data sample
146                vec yt;
147                //! input vector
148                vec ut;
149                //! datalink between ut and regressor
150                datalink_buffered ut2rgr;
151                //! datalink between yt and regressor
152                datalink_buffered yt2rgr;
153                //! numeric values of regressor
154                vec rgr;
155               
156        public:
157                void step() {
158                        yt2rgr.step(yt); // y is now history
159                        ut2rgr.filldown ( ut,rgr );
160                        yt2rgr.filldown ( yt,rgr );
161                        yt=impdf->samplecond ( rgr );
162                        ut2rgr.step(ut); //u is now history
163                }
164                void getdata ( vec &dt_out ) {
165                        bdm_assert_debug(dt_out.length()>=utsize+ytsize,"Short output vector");
166                        dt_out.set_subvector(0, yt);
167                        dt_out.set_subvector(ytsize, ut);
168                }
169                void write(const vec &ut0){ut=ut0;}
170
171                /*!
172                \code
173                class = "MpdfDS";
174                mpdf = {class="mpdf_offspring", ...}// mpdf to simulate
175                \endcode
176
177                */
178                void from_setting ( const Setting &set ) {
179                        impdf=UI::build<mpdf> ( set,"mpdf",UI::compulsory );
180                       
181                        Yrv = impdf->_rv();
182                        // get unique rvs form rvc
183                        RV rgrv0=impdf->_rvc().remove_time();
184                        // input is what in not in Yrv
185                        Urv=rgrv0.subt(Yrv); 
186                        set_drv(Yrv, Urv);
187                        // connect input and output to rvc
188                        ut2rgr.set_connection(impdf->_rvc(), Urv); 
189                        yt2rgr.set_connection(impdf->_rvc(), Yrv); 
190
191                        yt = zeros ( impdf->dimension() );
192                        rgr = zeros ( impdf->dimensionc() );
193                        ut = zeros(Urv._dsize());
194
195                        ytsize=yt.length();
196                        utsize=ut.length();
197                        dtsize = ytsize+utsize;
198                }
199};
200UIREGISTER ( MpdfDS );
201
202/*! Pseudovirtual class for reading data from files
203
204*/
205class FileDS: public MemDS {
206
207        public:
208                void getdata ( vec &dt ) {
209                        dt = Data.get_col ( time );
210                }
211
212                void getdata ( vec &dt, const ivec &indices ) {
213                        vec tmp = Data.get_col ( time );
214                        dt = tmp ( indices );
215                }
216
217                //! returns number of data in the file;
218                int ndat() {
219                        return Data.cols();
220                }
221                //! no sense to log this type
222                void log_add ( logger &L ) {};
223                //! no sense to log this type
224                void logit ( logger &L ) {};
225};
226
227/*!
228* \brief Read Data Matrix from an IT file
229
230The 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$!
231
232*/
233class ITppFileDS: public FileDS {
234
235        public:
236                ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
237                        it_file it ( fname );
238                        it << Name ( varname );
239                        it >> Data;
240                        time = 0;
241                        //rowid and delays are ignored
242                };
243
244                ITppFileDS () : FileDS() {
245                };
246
247                void from_setting ( const Setting &set );
248
249                // TODO dodelat void to_setting( Setting &set ) const;
250
251};
252
253UIREGISTER ( ITppFileDS );
254SHAREDPTR ( ITppFileDS );
255
256/*!
257* \brief CSV file data storage
258The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
2591. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
2602. \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.
261
262*/
263class CsvFileDS: public FileDS {
264
265        public:
266                //! Constructor - create DS from a CSV file.
267                CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
268};
269
270
271
272/*!
273\brief Generator of ARX data
274
275*/
276class ArxDS : public DS {
277        protected:
278                //! Rv of the regressor
279                RV Rrv;
280                //! History, ordered as \f$[y_t, u_t, y_{t-1 }, u_{t-1}, \ldots]\f$
281                vec H;
282                //! (future) input
283                vec U;
284                //! temporary variable for regressor
285                vec rgr;
286                //! data link: H -> rgr
287                datalink rgrlnk;
288                //! model of Y - linear Gaussian
289                mlnorm<chmat> model;
290                //! options
291                bool opt_L_theta;
292                //! loggers
293                int L_theta;
294                int L_R;
295                int dt_size;
296        public:
297                void getdata ( vec &dt ) {
298                        dt = H;
299                }
300
301                void getdata ( vec &dt, const ivec &indices ) {
302                        dt = H ( indices );
303                }
304
305                void write ( vec &ut ) {
306                        U = ut;
307                }
308
309                void write ( vec &ut, const ivec &indices ) {
310                        bdm_assert_debug ( ut.length() == indices.length(), "ArxDS" );
311                        set_subvector ( U, indices, ut );
312                }
313
314                void step();
315
316                //!Default constructor
317                ArxDS ( ) {};
318                //! Set parameters of the internal model, H is maximum time delay
319                void set_parameters ( const mat &Th0, const vec mu0, const chmat &sqR0 ) {
320                        model.set_parameters ( Th0, mu0, sqR0 );
321                };
322                //! Set
323                void set_drv ( const RV &yrv, const RV &urv, const RV &rrv ) {
324                        Rrv = rrv;
325                        Urv = urv;
326                        dt_size = yrv._dsize() + urv._dsize();
327
328                        RV drv = concat ( yrv, urv );
329                        Drv = drv;
330                        int td = rrv.mint();
331                        H.set_size ( drv._dsize() * ( -td + 1 ) );
332                        U.set_size ( Urv._dsize() );
333                        for ( int i = -1; i >= td; i-- ) {
334                                drv.t_plus ( -1 );
335                                Drv.add ( drv ); //shift u1
336                        }
337                        rgrlnk.set_connection ( rrv, Drv );
338
339                        dtsize = Drv._dsize();
340                        utsize = Urv._dsize();
341                }
342                //! set options from a string
343                void set_options ( const string &s ) {
344                        opt_L_theta = ( s.find ( "L_theta" ) != string::npos );
345                };
346                virtual void log_add ( logger &L ) {
347                        //DS::log_add ( L ); too long!!
348                        L_dt = L.add ( Drv ( 0, dt_size ), "" );
349                        L_ut = L.add ( Urv, "" );
350
351                        const mat &A = model._A();
352                        const mat R = model._R();
353                        if ( opt_L_theta ) {
354                                L_theta = L.add ( RV ( "{th }", vec_1 ( A.rows() * A.cols() ) ), "t" );
355                        }
356                        if ( opt_L_theta ) {
357                                L_R = L.add ( RV ( "{R }", vec_1 ( R.rows() * R.cols() ) ), "r" );
358                        }
359                }
360                virtual void logit ( logger &L ) {
361                        //DS::logit ( L );
362                        L.logit ( L_dt, H.left ( dt_size ) );
363                        L.logit ( L_ut, U );
364
365                        const mat &A = model._A();
366                        const mat R = model._R();
367                        if ( opt_L_theta ) {
368                                L.logit ( L_theta, vec ( A._data(), A.rows() *A.cols() ) );
369                        };
370                        if ( opt_L_theta ) {
371                                L.logit ( L_R, vec ( R._data(), R.rows() *R.rows() ) );
372                        };
373                }
374
375                // TODO dokumentace - aktualizovat
376                /*! UI for ArxDS using factorized description!
377
378                The ArxDS is constructed from a structure with fields:
379                \code
380                system = {
381                        type = "ArxDS";
382                        // description of y variables
383                        y = {type="rv"; names=["y", "u"];};
384                        // description of u variable
385                        u = {type="rv"; names=[];}
386                        // description of regressor
387                        rgr = {type="rv";
388                                names = ["y","y","y","u"];
389                                times = [-1, -2, -3, -1];
390                        }
391
392                        // theta
393                        theta = [0.8, -0.3, 0.4, 1.0,
394                                         0.0, 0.0, 0.0, 0.0];
395                        // offset (optional)
396                        offset = [0.0, 0.0];
397                        //variance
398                        r = [0.1, 0.0,
399                                 0.0, 1.0];
400                        //options: L_theta = log value of theta,
401                        opt = "L_theta";
402                };
403                \endcode
404
405                Result is ARX data source offering with full history as Drv.
406                */
407                void from_setting ( const Setting &set );
408
409                // TODO dodelat void to_setting( Setting &set ) const;
410};
411
412UIREGISTER ( ArxDS );
413SHAREDPTR ( ArxDS );
414
415class stateDS : public DS {
416        private:
417                //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
418                shared_ptr<mpdf> IM;
419
420                //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
421                shared_ptr<mpdf> OM;
422
423        protected:
424                //! result storage
425                vec dt;
426                //! state storage
427                vec xt;
428                //! input storage
429                vec ut;
430                //! Logger
431                int L_xt;
432
433        public:
434                void getdata ( vec &dt0 ) {
435                        dt0 = dt;
436                }
437
438                void getdata ( vec &dt0, const ivec &indices ) {
439                        dt0 = dt ( indices );
440                }
441
442                stateDS ( const shared_ptr<mpdf> &IM0, const shared_ptr<mpdf> &OM0, int usize ) : IM ( IM0 ), OM ( OM0 ),
443                                dt ( OM0->dimension() ), xt ( IM0->dimension() ),
444                                ut ( usize ), L_xt ( 0 ) { }
445
446                stateDS() : L_xt ( 0 ) { }
447
448                virtual void step() {
449                        xt = IM->samplecond ( concat ( xt, ut ) );
450                        dt = OM->samplecond ( concat ( xt, ut ) );
451                }
452
453                virtual void log_add ( logger &L ) {
454                        DS::log_add ( L );
455                        L_xt = L.add ( IM->_rv(), "true" );
456                }
457                virtual void logit ( logger &L ) {
458                        DS::logit ( L );
459                        L.logit ( L_xt, xt );
460                }
461
462                /*! UI for stateDS
463
464                The DS is constructed from a structure with fields:
465                \code
466                system = {
467                        type = "stateDS";
468                        //Internal model
469                        IM = { type = "mpdf"; //<-- valid offspring! e.g. "mlnorm"
470                                rv = { //description of x_t
471                                        names=["name1",...];
472                                        sizes=[2,1]; // optional default=[1,1...];
473                                        times=[0,0]; // optional default=[0,0...];
474                                        }
475                                rvu= { //description of  u_t
476                                        //optional default=empty
477                                        }
478
479                                // remaining fields depending on the chosen type
480                                };
481                        //Observation model
482                        OM = { type = "mpdf-offspring";
483                                rv = {}; //description of d_t
484                                rvu = {type="internal", path="system.IM.rvu"}; //description of u_t
485
486                                //remaining fields
487                        }
488                };
489                \endcode
490                */
491                void from_setting ( const Setting &set );
492
493                // TODO dodelat void to_setting( Setting &set ) const;
494
495};
496
497UIREGISTER ( stateDS );
498SHAREDPTR ( stateDS );
499
500}; //namespace
501
502#endif // DS_H
Note: See TracBrowser for help on using the browser.