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

Revision 598, 10.6 kB (checked in by smidl, 15 years ago)

new buffered datalink ( #32 ) and new datasources - all with minor trivial tests

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