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

Revision 609, 12.1 kB (checked in by smidl, 15 years ago)

remove "delays" from memory DS, check length of datasource

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