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

Revision 738, 9.4 kB (checked in by mido, 15 years ago)

a few moves of code from h to cpp, however, only part of the whole library is done

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