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

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

validate() finally included into UI::build mechanism and removed from some from_setting methods,
from that point StateDS test does not pass, I do not understand why

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