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

Revision 604, 10.8 kB (checked in by smidl, 15 years ago)

change of syntax of RV

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