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

Revision 737, 10.1 kB (checked in by mido, 15 years ago)

ASTYLER RUN OVER THE WHOLE LIBRARY, JUPEE

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