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

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

abstract methods restored wherever they are meaningful
macros NOT_IMPLEMENTED and NOT_IMPLEMENTED_VOID defined to make sources shorter
emix::set_parameters and mmix::set_parameters removed, corresponding acces methods created and the corresponding validate methods improved appropriately
some compilator warnings were avoided
and also a few other things cleaned up

  • 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.
26
27The data can be loaded from a file.
28*/
29class MemDS : public DS {
30protected:
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
38public:
39        int max_length() {
40                return Data.cols();
41        }
42        void getdata ( vec &dt ) const;
43        void getdata ( vec &dt, const ivec &indeces );
44        void set_drv ( const RV &drv, const  RV &urv );
45
46        void write ( const vec &ut ) {
47                bdm_error ( "MemDS::write is not supported" );
48        }
49
50        void write ( const vec &ut, const ivec &indices ) {
51                bdm_error ( "MemDS::write is not supported" );
52        }
53
54        void step();
55        //!Default constructor
56        MemDS () {};
57        //! Convenience constructor
58        MemDS ( mat &Dat, ivec &rowid0 );
59        /*! Create object from the following structure
60        \code
61        { class = "MemDS";
62           Data = (...);            // Data matrix or data vector
63           --- optional ---
64           drv = {class="RV"; ...} // Identification how rows of the matrix Data will be known to others
65           time = 0;               // Index of the first column to user_info,
66           rowid = [1,2,3...];     // ids of rows to be used
67        }
68        \endcode
69
70        If the optional fields are not given, they will be filled as follows:
71        \code
72        rowid= [0, 1, 2, ...number_of_rows_of_Data];
73        drv = {names=("ch0", "ch1", "ch2", ..."number_of_rows_of_Data");
74              sizes=( 1    1    1 ...);
75                  times=( 0    0    0 ...);
76                  };
77        time = 0;
78        \endcode
79        If \c rowid is given, \c drv will be named after indeces in rowids.
80
81        Hence the data provided by method \c getdata() will be full column of matrix Data starting from the first record.
82        */
83        void from_setting ( const Setting &set ) {
84                UI::get ( Data, set, "Data", UI::compulsory );
85                if ( !UI::get ( time, set, "time", UI::optional ) ) {
86                        time = 0;
87                }
88                if ( !UI::get ( rowid, set, "rowid", UI::optional ) ) {
89                        rowid = linspace ( 0, Data.rows() - 1 );
90                }
91                shared_ptr<RV> r = UI::build<RV> ( set, "drv", UI::optional );
92                if ( !r ) {
93                        r = new RV();
94                        for ( int i = 0; i < rowid.length(); i++ ) {
95                                r->add ( RV ( "ch" + num2str ( rowid ( i ) ), 1, 0 ) );
96                        }
97                }
98                set_drv ( *r, RV() ); //empty urv
99                dtsize = r->_dsize();
100                ytsize = dtsize;
101                utsize = 0;
102        }
103};
104UIREGISTER ( MemDS );
105
106/*!  \brief Simulate data from a static pdf (epdf)
107
108Trivial 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.
109*/
110
111class EpdfDS: public DS {
112protected:
113        //! internal pointer to epdf from which we samplecond
114        shared_ptr<epdf> iepdf;
115        //! internal storage of data sample
116        vec dt;
117public:
118        void step() {
119                dt = iepdf->sample();
120        }
121        void getdata ( vec &dt_out ) const {
122                dt_out = dt;
123        }
124        void getdata ( vec &dt_out, const ivec &ids ) {
125                dt_out = dt ( ids );
126        }
127        const RV& _drv() const {
128                return iepdf->_rv();
129        }
130
131        //! Accepts action variable and schedule it for application.   
132        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
133               
134        //! Accepts action variables at specific indeces
135        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
136
137        /*!
138        \code
139        class = "EpdfDS";
140        epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
141        \endcode
142
143        */
144        void from_setting ( const Setting &set ) {
145                iepdf = UI::build<epdf> ( set, "epdf", UI::compulsory );
146                bdm_assert ( iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly" );
147                dt =  zeros ( iepdf->dimension() );
148                dtsize = dt.length();
149                ytsize = dt.length();
150                set_drv ( iepdf->_rv(), RV() );
151                utsize = 0;
152                validate();
153        }
154        void validate() {
155                dt = iepdf->sample();
156        }
157};
158UIREGISTER ( EpdfDS );
159
160/*!  \brief Simulate data from conditional density
161Still having only one density but allowing conditioning on either input or delayed values.
162*/
163class PdfDS : public DS {
164protected:
165        //! internal pointer to epdf from which we samplecond
166        shared_ptr<pdf> ipdf;
167        //! internal storage of data sample
168        vec yt;
169        //! input vector
170        vec ut;
171        //! datalink between ut and regressor
172        datalink_buffered ut2rgr;
173        //! datalink between yt and regressor
174        datalink_buffered yt2rgr;
175        //! numeric values of regressor
176        vec rgr;
177
178public:
179        void step();
180
181        void getdata ( vec &dt_out ) const;
182
183        void write ( const vec &ut0 ) {
184                ut = ut0;
185        }
186        void write ( const vec &ut0, const ivec &ind ) {
187                set_subvector ( ut, ind, ut0 );
188        }
189
190
191        //! Returns data records at indeces.
192        virtual void getdata ( vec &dt, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
193
194
195        /*!
196        \code
197        class = "PdfDS";
198        pdf = {class="pdf_offspring", ...};  // pdf to simulate
199        --- optional ---
200        init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
201        init_values = [...];                   // vector of initial values corresponding to init_rv
202        \endcode
203
204        If init_rv is not given, init_values are set to zero.
205        */
206        void from_setting ( const Setting &set ) {
207                ipdf = UI::build<pdf> ( set, "pdf", UI::compulsory );
208
209                Yrv = ipdf->_rv();
210                // get unique rvs form rvc
211                RV rgrv0 = ipdf->_rvc().remove_time();
212                // input is what in not in Yrv
213                Urv = rgrv0.subt ( Yrv );
214                set_drv ( Yrv, Urv );
215                // connect input and output to rvc
216                ut2rgr.set_connection ( ipdf->_rvc(), Urv );
217                yt2rgr.set_connection ( ipdf->_rvc(), Yrv );
218
219                //set history - if given
220                shared_ptr<RV> rv_ini = UI::build<RV> ( set, "init_rv", UI::optional );
221                if ( rv_ini ) { // check if
222                        vec val;
223                        UI::get ( val, set, "init_values", UI::optional );
224                        if ( val.length() != rv_ini->_dsize() ) {
225                                bdm_error ( "init_rv and init_values fields have incompatible sizes" );
226                        } else {
227                                ut2rgr.set_history ( *rv_ini, val );
228                                yt2rgr.set_history ( *rv_ini, val );
229                        }
230                }
231
232                yt = zeros ( ipdf->dimension() );
233                rgr = zeros ( ipdf->dimensionc() );
234                ut = zeros ( Urv._dsize() );
235
236                ytsize = yt.length();
237                utsize = ut.length();
238                dtsize = ytsize + utsize;
239                validate();
240        }
241        void validate() {
242                //taken from sample() - shift of history is not done here
243                ut2rgr.filldown ( ut, rgr );
244                yt2rgr.filldown ( yt, rgr );
245                yt = ipdf->samplecond ( rgr );
246        }
247};
248UIREGISTER ( PdfDS );
249
250/*! Pseudovirtual class for reading data from files
251
252*/
253class FileDS: public MemDS {
254
255public:
256        void getdata ( vec &dt ) {
257                dt = Data.get_col ( time );
258        }
259
260        void getdata ( vec &dt, const ivec &indices ) {
261                vec tmp = Data.get_col ( time );
262                dt = tmp ( indices );
263        }
264
265        //! returns number of data in the file;
266        int ndat() {
267                return Data.cols();
268        }
269        //! no sense to log this type
270        void log_register ( logger &L, const string &prefix ) {};
271        //! no sense to log this type
272        void log_write ( ) const {};
273};
274
275/*!
276* \brief Read Data Matrix from an IT file
277
278The 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$!
279
280*/
281class ITppFileDS: public FileDS {
282
283public:
284        //! Convenience constructor
285        ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
286                it_file it ( fname );
287                it << Name ( varname );
288                it >> Data;
289                time = 0;
290                //rowid and delays are ignored
291        };
292
293        ITppFileDS () : FileDS() {
294        };
295
296        void from_setting ( const Setting &set );
297
298        // TODO dodelat void to_setting( Setting &set ) const;
299
300};
301
302UIREGISTER ( ITppFileDS );
303SHAREDPTR ( ITppFileDS );
304
305/*!
306* \brief CSV file data storage
307The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
3081. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
3092. \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.
310
311*/
312class CsvFileDS: public FileDS {
313
314public:
315        //! Constructor - create DS from a CSV file.
316        CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
317};
318
319
320
321// ARXDs - DELETED
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.