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

Revision 892, 9.9 kB (checked in by mido, 14 years ago)

trivial commit - sources of datasources reformatted and astylled without changing any functionality

  • 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                ytsize = dtsize;
100                utsize = 0;
101        }
102};
103UIREGISTER ( MemDS );
104
105/*! Pseudovirtual class for reading data from files
106
107*/
108class FileDS: public MemDS {
109
110public:
111        void getdata ( vec &dt ) {
112                dt = Data.get_col ( time );
113        }
114
115        void getdata ( vec &dt, const ivec &indices ) {
116                vec tmp = Data.get_col ( time );
117                dt = tmp ( indices );
118        }
119
120        //! returns number of data in the file;
121        int ndat() {
122                return Data.cols();
123        }
124        //! no sense to log this type
125        void log_register ( logger &L, const string &prefix ) {};
126        //! no sense to log this type
127        void log_write ( ) const {};
128};
129
130/*!
131* \brief Read Data Matrix from an IT file
132
133The 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$!
134
135*/
136class ITppFileDS: public FileDS {
137
138public:
139        //! Convenience constructor
140        ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
141                it_file it ( fname );
142                it << Name ( varname );
143                it >> Data;
144                time = 0;
145                //rowid and delays are ignored
146        };
147
148        ITppFileDS () : FileDS() {
149        };
150
151        void from_setting ( const Setting &set );
152
153        // TODO dodelat void to_setting( Setting &set ) const;
154
155};
156
157UIREGISTER ( ITppFileDS );
158SHAREDPTR ( ITppFileDS );
159
160/*!
161* \brief CSV file data storage
162The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
1631. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
1642. \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.
165
166*/
167class CsvFileDS: public FileDS {
168
169public:
170        //! Constructor - create DS from a CSV file.
171        CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
172};
173
174
175
176// ARXDs - DELETED
177
178/*!  \brief Simulate data from a static pdf (epdf)
179
180Trivial 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.
181*/
182
183class EpdfDS: public DS {
184protected:
185        //! internal pointer to epdf from which we samplecond
186        shared_ptr<epdf> iepdf;
187        //! internal storage of data sample
188        vec dt;
189public:
190        void step() {
191                dt = iepdf->sample();
192        }
193        void getdata ( vec &dt_out ) const {
194                dt_out = dt;
195        }
196        void getdata ( vec &dt_out, const ivec &ids ) {
197                dt_out = dt ( ids );
198        }
199        const RV& _drv() const {
200                return iepdf->_rv();
201        }
202
203        //! Accepts action variable and schedule it for application.
204        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
205
206        //! Accepts action variables at specific indeces
207        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
208
209        /*!
210        \code
211        class = "EpdfDS";
212        epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
213        \endcode
214
215        */
216        void from_setting ( const Setting &set ) {
217                iepdf = UI::build<epdf> ( set, "epdf", UI::compulsory );
218                bdm_assert ( iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly" );
219                dt =  zeros ( iepdf->dimension() );
220                dtsize = dt.length();
221                ytsize = dt.length();
222                set_drv ( iepdf->_rv(), RV() );
223                utsize = 0;
224        }
225
226        void validate() {
227                DS::validate();
228
229                dt = iepdf->sample();
230        }
231};
232UIREGISTER ( EpdfDS );
233
234/*!  \brief Simulate data from conditional density
235Still having only one density but allowing conditioning on either input or delayed values.
236*/
237class PdfDS : public DS {
238protected:
239        //! internal pointer to epdf from which we samplecond
240        shared_ptr<pdf> ipdf;
241        //! internal storage of data sample
242        vec yt;
243        //! input vector
244        vec ut;
245        //! datalink between ut and regressor
246        datalink_buffered ut2rgr;
247        //! datalink between yt and regressor
248        datalink_buffered yt2rgr;
249        //! numeric values of regressor
250        vec rgr;
251
252public:
253        void step();
254
255        void getdata ( vec &dt_out ) const;
256
257        void write ( const vec &ut0 ) {
258                ut = ut0;
259        }
260        void write ( const vec &ut0, const ivec &ind ) {
261                set_subvector ( ut, ind, ut0 );
262        }
263
264
265        //! Returns data records at indeces.
266        virtual void getdata ( vec &dt, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
267
268
269        /*!
270        \code
271        class = "PdfDS";
272        pdf = {class="pdf_offspring", ...};  // pdf to simulate
273        --- optional ---
274        init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
275        init_values = [...];                   // vector of initial values corresponding to init_rv
276        \endcode
277
278        If init_rv is not given, init_values are set to zero.
279        */
280        void from_setting ( const Setting &set ) {
281                ipdf = UI::build<pdf> ( set, "pdf", UI::compulsory );
282
283                Yrv = ipdf->_rv();
284                // get unique rvs form rvc
285                RV rgrv0 = ipdf->_rvc().remove_time();
286                // input is what in not in Yrv
287                Urv = rgrv0.subt ( Yrv );
288                set_drv ( Yrv, Urv );
289                // connect input and output to rvc
290                ut2rgr.set_connection ( ipdf->_rvc(), Urv );
291                yt2rgr.set_connection ( ipdf->_rvc(), Yrv );
292
293                //set history - if given
294                shared_ptr<RV> rv_ini = UI::build<RV> ( set, "init_rv", UI::optional );
295                if ( rv_ini ) { // check if
296                        vec val;
297                        UI::get ( val, set, "init_values", UI::optional );
298                        if ( val.length() != rv_ini->_dsize() ) {
299                                bdm_error ( "init_rv and init_values fields have incompatible sizes" );
300                        } else {
301                                ut2rgr.set_history ( *rv_ini, val );
302                                yt2rgr.set_history ( *rv_ini, val );
303                        }
304                }
305
306                yt = zeros ( ipdf->dimension() );
307                rgr = zeros ( ipdf->dimensionc() );
308                ut = zeros ( Urv._dsize() );
309
310                ytsize = yt.length();
311                utsize = ut.length();
312                dtsize = ytsize + utsize;
313        }
314
315        void validate() {
316                DS::validate();
317
318                //taken from sample() - shift of history is not done here
319                ut2rgr.filldown ( ut, rgr );
320                yt2rgr.filldown ( yt, rgr );
321                yt = ipdf->samplecond ( rgr );
322        }
323};
324UIREGISTER ( PdfDS );
325
326//! State-space data source simulating two densities
327class StateDS : public DS {
328protected:
329        //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
330        shared_ptr<pdf> IM;
331
332        //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
333        shared_ptr<pdf> OM;
334
335        //! result storage
336        vec dt;
337        //! state storage
338        vec xt;
339        //! input storage
340        vec ut;
341
342        //! datalink from ut to IM.rvc
343        datalink_part u2imc;
344        //! datalink from ut to OM.rvc
345        datalink_part u2omc;
346public:
347        void getdata ( vec &dt0 ) const {
348                dt0 = dt;
349        }
350        void write ( const vec &ut0 ) {
351                ut = ut0;
352        }
353
354        void getdata ( vec &dt0, const ivec &indices ) {
355                dt0 = dt ( indices );
356        }
357
358        virtual void step();
359
360        //! set parameters
361        void set_parameters ( shared_ptr<pdf> IM0, shared_ptr<pdf> OM0 ) {
362                IM = IM0;
363                OM = OM0;
364        }
365        void set_initx ( const vec &x0 ) {
366                xt = x0;
367        }
368
369        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
370
371        /*! UI for stateDS
372
373        The DS is constructed from a structure with fields:
374        \code
375        class = "stateDS";
376        //Internal model
377        IM = { type = "pdf-offspring"; };
378        //Observation model
379        OM = { type = "pdf-offspring"; }
380        //initial state
381        x0 = [...]; //vector of data
382        \endcode
383        Both models must have defined \c rv. and \c rvc
384        Random variables not found in any rv are considered to be inputs.
385        */
386        void from_setting ( const Setting &set );
387
388        // TODO dodelat void to_setting( Setting &set ) const;
389
390        void validate();
391};
392
393UIREGISTER ( StateDS );
394SHAREDPTR ( StateDS );
395
396}; //namespace
397
398#endif // DS_H
Note: See TracBrowser for help on using the browser.