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

Revision 895, 9.8 kB (checked in by smidl, 14 years ago)

get rid of Yrv in DS

  • 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#include "../base/bdmbase.h"
17#include "../stat/exp_family.h"
18#include "../base/user_info.h"
19
20namespace bdm {
21/*!
22* \brief Memory storage of off-line data column-wise
23
24The 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.
25
26The data can be loaded from a file.
27*/
28class MemDS : public DS {
29protected:
30        //! internal matrix of data
31        mat Data;
32        //! active column in the Data matrix
33        int time;
34        //!  vector of rows that are presented in Dt
35        ivec rowid;
36
37public:
38        int max_length() {
39                return Data.cols();
40        }
41        void getdata ( vec &dt ) const;
42        void getdata ( vec &dt, const ivec &indeces );
43        void set_drv ( const RV &drv, const  RV &urv );
44
45        void write ( const vec &ut ) {
46                bdm_error ( "MemDS::write is not supported" );
47        }
48
49        void write ( const vec &ut, const ivec &indices ) {
50                bdm_error ( "MemDS::write is not supported" );
51        }
52
53        void step();
54        //!Default constructor
55        MemDS () {};
56        //! Convenience constructor
57        MemDS ( mat &Dat, ivec &rowid0 );
58        /*! Create object from the following structure
59        \code
60        { class = "MemDS";
61           Data = (...);            // Data matrix or data vector
62           --- optional ---
63           drv = {class="RV"; ...} // Identification how rows of the matrix Data will be known to others
64           time = 0;               // Index of the first column to user_info,
65           rowid = [1,2,3...];     // ids of rows to be used
66        }
67        \endcode
68
69        If the optional fields are not given, they will be filled as follows:
70        \code
71        rowid= [0, 1, 2, ...number_of_rows_of_Data];
72        drv = {names=("ch0", "ch1", "ch2", ..."number_of_rows_of_Data");
73              sizes=( 1    1    1 ...);
74                  times=( 0    0    0 ...);
75                  };
76        time = 0;
77        \endcode
78        If \c rowid is given, \c drv will be named after indeces in rowids.
79
80        Hence the data provided by method \c getdata() will be full column of matrix Data starting from the first record.
81        */
82        void from_setting ( const Setting &set ) {
83                UI::get ( Data, set, "Data", UI::compulsory );
84                if ( !UI::get ( time, set, "time", UI::optional ) ) {
85                        time = 0;
86                }
87                if ( !UI::get ( rowid, set, "rowid", UI::optional ) ) {
88                        rowid = linspace ( 0, Data.rows() - 1 );
89                }
90                shared_ptr<RV> r = UI::build<RV> ( set, "drv", UI::optional );
91                if ( !r ) {
92                        r = new RV();
93                        for ( int i = 0; i < rowid.length(); i++ ) {
94                                r->add ( RV ( "ch" + num2str ( rowid ( i ) ), 1, 0 ) );
95                        }
96                }
97                set_drv ( *r, RV() ); //empty urv
98                dtsize = r->_dsize();
99                utsize = 0;
100        }
101};
102UIREGISTER ( MemDS );
103
104/*! Pseudovirtual class for reading data from files
105
106*/
107class FileDS: public MemDS {
108
109public:
110        void getdata ( vec &dt ) {
111                dt = Data.get_col ( time );
112        }
113
114        void getdata ( vec &dt, const ivec &indices ) {
115                vec tmp = Data.get_col ( time );
116                dt = tmp ( indices );
117        }
118
119        //! returns number of data in the file;
120        int ndat() {
121                return Data.cols();
122        }
123        //! no sense to log this type
124        void log_register ( logger &L, const string &prefix ) {};
125        //! no sense to log this type
126        void log_write ( ) const {};
127};
128
129/*!
130* \brief Read Data Matrix from an IT file
131
132The 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$!
133
134*/
135class ITppFileDS: public FileDS {
136
137public:
138        //! Convenience constructor
139        ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
140                it_file it ( fname );
141                it << Name ( varname );
142                it >> Data;
143                time = 0;
144                //rowid and delays are ignored
145        };
146
147        ITppFileDS () : FileDS() {
148        };
149
150        void from_setting ( const Setting &set );
151
152        // TODO dodelat void to_setting( Setting &set ) const;
153
154};
155
156UIREGISTER ( ITppFileDS );
157SHAREDPTR ( ITppFileDS );
158
159/*!
160* \brief CSV file data storage
161The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
1621. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
1632. \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.
164
165*/
166class CsvFileDS: public FileDS {
167
168public:
169        //! Constructor - create DS from a CSV file.
170        CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
171};
172
173
174
175// ARXDs - DELETED
176
177/*!  \brief Simulate data from a static pdf (epdf)
178
179Trivial 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.
180*/
181
182class EpdfDS: public DS {
183protected:
184        //! internal pointer to epdf from which we samplecond
185        shared_ptr<epdf> iepdf;
186        //! internal storage of data sample
187        vec dt;
188public:
189        void step() {
190                dt = iepdf->sample();
191        }
192        void getdata ( vec &dt_out ) const {
193                dt_out = dt;
194        }
195        void getdata ( vec &dt_out, const ivec &ids ) {
196                dt_out = dt ( ids );
197        }
198        const RV& _drv() const {
199                return iepdf->_rv();
200        }
201
202        //! Accepts action variable and schedule it for application.
203        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
204
205        //! Accepts action variables at specific indeces
206        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
207
208        /*!
209        \code
210        class = "EpdfDS";
211        epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
212        \endcode
213
214        */
215        void from_setting ( const Setting &set ) {
216                iepdf = UI::build<epdf> ( set, "epdf", UI::compulsory );
217                bdm_assert ( iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly" );
218                dt =  zeros ( iepdf->dimension() );
219                dtsize = dt.length();
220                set_drv ( iepdf->_rv(), RV() );
221                utsize = 0;
222        }
223
224        void validate() {
225                DS::validate();
226
227                dt = iepdf->sample();
228        }
229};
230UIREGISTER ( EpdfDS );
231
232/*!  \brief Simulate data from conditional density
233Still having only one density but allowing conditioning on either input or delayed values.
234*/
235class PdfDS : public DS {
236protected:
237        //! internal pointer to epdf from which we samplecond
238        shared_ptr<pdf> ipdf;
239        //! internal storage of data sample
240        vec yt;
241        //! input vector
242        vec ut;
243        //! datalink between ut and regressor
244        datalink_buffered ut2rgr;
245        //! datalink between yt and regressor
246        datalink_buffered yt2rgr;
247        //! numeric values of regressor
248        vec rgr;
249
250public:
251        void step();
252
253        void getdata ( vec &dt_out ) const;
254
255        void write ( const vec &ut0 ) {
256                ut = ut0;
257        }
258        void write ( const vec &ut0, const ivec &ind ) {
259                set_subvector ( ut, ind, ut0 );
260        }
261
262
263        //! Returns data records at indeces.
264        virtual void getdata ( vec &dt, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
265
266
267        /*!
268        \code
269        class = "PdfDS";
270        pdf = {class="pdf_offspring", ...};  // pdf to simulate
271        --- optional ---
272        init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
273        init_values = [...];                   // vector of initial values corresponding to init_rv
274        \endcode
275
276        If init_rv is not given, init_values are set to zero.
277        */
278        void from_setting ( const Setting &set ) {
279                ipdf = UI::build<pdf> ( set, "pdf", UI::compulsory );
280
281                RV Yrv = ipdf->_rv();
282                // get unique rvs form rvc
283                RV rgrv0 = ipdf->_rvc().remove_time();
284                // input is what in not in Yrv
285                Urv = rgrv0.subt ( Yrv );
286                set_drv ( concat(Yrv,Urv), Urv );
287                // connect input and output to rvc
288                ut2rgr.set_connection ( ipdf->_rvc(), Urv );
289                yt2rgr.set_connection ( ipdf->_rvc(), Yrv );
290
291                //set history - if given
292                shared_ptr<RV> rv_ini = UI::build<RV> ( set, "init_rv", UI::optional );
293                if ( rv_ini ) { // check if
294                        vec val;
295                        UI::get ( val, set, "init_values", UI::optional );
296                        if ( val.length() != rv_ini->_dsize() ) {
297                                bdm_error ( "init_rv and init_values fields have incompatible sizes" );
298                        } else {
299                                ut2rgr.set_history ( *rv_ini, val );
300                                yt2rgr.set_history ( *rv_ini, val );
301                        }
302                }
303
304                yt = zeros ( ipdf->dimension() );
305                rgr = zeros ( ipdf->dimensionc() );
306                ut = zeros ( Urv._dsize() );
307
308                utsize = ut.length();
309                dtsize = yt.length() + utsize;
310        }
311
312        void validate() {
313                DS::validate();
314
315                //taken from sample() - shift of history is not done here
316                ut2rgr.filldown ( ut, rgr );
317                yt2rgr.filldown ( yt, rgr );
318                yt = ipdf->samplecond ( rgr );
319        }
320};
321UIREGISTER ( PdfDS );
322
323//! State-space data source simulating two densities
324class StateDS : public DS {
325protected:
326        //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
327        shared_ptr<pdf> IM;
328
329        //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
330        shared_ptr<pdf> OM;
331
332        //! result storage
333        vec dt;
334        //! state storage
335        vec xt;
336        //! input storage
337        vec ut;
338
339        //! datalink from ut to IM.rvc
340        datalink_part u2imc;
341        //! datalink from ut to OM.rvc
342        datalink_part u2omc;
343public:
344        void getdata ( vec &dt0 ) const {
345                dt0 = dt;
346        }
347        void write ( const vec &ut0 ) {
348                ut = ut0;
349        }
350
351        void getdata ( vec &dt0, const ivec &indices ) {
352                dt0 = dt ( indices );
353        }
354
355        virtual void step();
356
357        //! set parameters
358        void set_parameters ( shared_ptr<pdf> IM0, shared_ptr<pdf> OM0 ) {
359                IM = IM0;
360                OM = OM0;
361        }
362        void set_initx ( const vec &x0 ) {
363                xt = x0;
364        }
365
366        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
367
368        /*! UI for stateDS
369
370        The DS is constructed from a structure with fields:
371        \code
372        class = "stateDS";
373        //Internal model
374        IM = { type = "pdf-offspring"; };
375        //Observation model
376        OM = { type = "pdf-offspring"; }
377        //initial state
378        x0 = [...]; //vector of data
379        \endcode
380        Both models must have defined \c rv. and \c rvc
381        Random variables not found in any rv are considered to be inputs.
382        */
383        void from_setting ( const Setting &set );
384
385        // TODO dodelat void to_setting( Setting &set ) const;
386
387        void validate();
388};
389
390UIREGISTER ( StateDS );
391SHAREDPTR ( StateDS );
392
393}; //namespace
394
395#endif // DS_H
Note: See TracBrowser for help on using the browser.