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

Revision 697, 10.0 kB (checked in by smidl, 15 years ago)

fix of StateDS

  • 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 {
30        protected:
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
38        public:
39                int max_length() {return Data.cols();}
40                void getdata ( vec &dt ) const;
41                void getdata ( vec &dt, const ivec &indeces );
42                void set_drv (const RV &drv,const  RV &urv );
43
44                void write ( const vec &ut ) {
45                        bdm_error ( "MemDS::write is not supported" );
46                }
47
48                void write ( const vec &ut, const ivec &indices ) {
49                        bdm_error ( "MemDS::write is not supported" );
50                }
51
52                void step();
53                //!Default constructor
54                MemDS () {};
55                //! Convenience constructor
56                MemDS ( mat &Dat, ivec &rowid0);
57                /*! Create object from the following structure
58                \code
59                { class = "MemDS";
60                   Data = (...);            // Data matrix or data vector
61                   --- optional ---
62                   drv = {class="RV"; ...} // Identification how rows of the matrix Data will be known to others
63                   time = 0;               // Index of the first column to user_info,
64                   rowid = [1,2,3...];     // ids of rows to be used
65                }
66                \endcode
67               
68                If the optional fields are not given, they will be filled as follows:
69                \code
70                rowid= [0, 1, 2, ...number_of_rows_of_Data];
71                drv = {names=("ch0", "ch1", "ch2", ..."number_of_rows_of_Data");
72                      sizes=( 1    1    1 ...);
73                          times=( 0    0    0 ...);
74                          };
75                time = 0;
76                \endcode
77                If \c rowid is given, \c drv will be named after indeces in rowids.
78               
79                Hence the data provided by method \c getdata() will be full column of matrix Data starting from the first record.
80                */
81                void from_setting(const Setting &set){
82                        UI::get(Data, set, "Data", UI::compulsory);
83                        if(!UI::get(time, set,"time", UI::optional)) {time =0;}
84                        if(!UI::get(rowid, set, "rowid",UI::optional)) {rowid =linspace(0,Data.rows()-1);}
85                        shared_ptr<RV> r=UI::build<RV>(set,"drv",UI::optional);
86                        if (!r) {r=new RV();
87                                for (int i=0; i<rowid.length(); i++){ r->add(RV("ch"+num2str(rowid(i)), 1, 0));}
88                        }
89                        set_drv(*r,RV()); //empty urv
90                        dtsize=r->_dsize();
91                        ytsize = dtsize;
92                        utsize=0;
93                }
94};
95UIREGISTER(MemDS);
96
97/*!  \brief Simulate data from a static pdf (epdf)
98
99Trivial 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.
100*/
101
102class EpdfDS: public DS {
103        protected:
104                //! internal pointer to epdf from which we samplecond
105                shared_ptr<epdf> iepdf;
106                //! internal storage of data sample
107                vec dt;
108        public:
109                void step() {
110                        dt=iepdf->sample();
111                }
112                void getdata ( vec &dt_out ) const {
113                        dt_out = dt;
114                }
115                void getdata ( vec &dt_out, const ivec &ids ) {
116                        dt_out = dt ( ids );
117                }
118                const RV& _drv() const {
119                        return iepdf->_rv();
120                }
121
122                /*!
123                \code
124                class = "EpdfDS";
125                epdf = {class="epdf_offspring", ...}// uncondtitional density to sample from
126                \endcode
127
128                */
129                void from_setting ( const Setting &set ) {
130                        iepdf=UI::build<epdf> ( set,"epdf",UI::compulsory );
131                        bdm_assert(iepdf->isnamed(), "Input epdf must be named, check if RV is given correctly");
132                        dt =  zeros(iepdf->dimension());
133                        dtsize=dt.length();
134                        set_drv(iepdf->_rv(),RV());
135                        utsize =0;
136                        validate();
137                }
138                void validate() {
139                        dt = iepdf->sample();
140                }
141};
142UIREGISTER ( EpdfDS );
143
144/*!  \brief Simulate data from conditional density
145Still having only one density but allowing conditioning on either input or delayed values.
146*/
147class PdfDS :public DS {
148        protected:
149                //! internal pointer to epdf from which we samplecond
150                shared_ptr<pdf> ipdf;
151                //! internal storage of data sample
152                vec yt;
153                //! input vector
154                vec ut;
155                //! datalink between ut and regressor
156                datalink_buffered ut2rgr;
157                //! datalink between yt and regressor
158                datalink_buffered yt2rgr;
159                //! numeric values of regressor
160                vec rgr;
161               
162        public:
163                void step() {
164                        yt2rgr.step(yt); // y is now history
165                        ut2rgr.filldown ( ut,rgr );
166                        yt2rgr.filldown ( yt,rgr );
167                        yt=ipdf->samplecond ( rgr );
168                        ut2rgr.step(ut); //u is now history
169                }
170                void getdata ( vec &dt_out ) const {
171                        bdm_assert_debug(dt_out.length()>=utsize+ytsize,"Short output vector");
172                        dt_out.set_subvector(0, yt);
173                        dt_out.set_subvector(ytsize, ut);
174                }
175                void write(const vec &ut0){ut=ut0;}
176
177                /*!
178                \code
179                class = "PdfDS";
180                pdf = {class="pdf_offspring", ...};  // pdf to simulate
181                --- optional ---
182                init_rv = {class="RV",names=...};      // define what rv to initialize - typically delayed values!
183                init_values = [...];                   // vector of initial values corresponding to init_rv
184                \endcode
185
186                If init_rv is not given, init_values are set to zero.
187                */
188                void from_setting ( const Setting &set ) {
189                        ipdf=UI::build<pdf> ( set,"pdf",UI::compulsory );
190                       
191                        Yrv = ipdf->_rv();
192                        // get unique rvs form rvc
193                        RV rgrv0=ipdf->_rvc().remove_time();
194                        // input is what in not in Yrv
195                        Urv=rgrv0.subt(Yrv); 
196                        set_drv(Yrv, Urv);
197                        // connect input and output to rvc
198                        ut2rgr.set_connection(ipdf->_rvc(), Urv); 
199                        yt2rgr.set_connection(ipdf->_rvc(), Yrv); 
200                       
201                        //set history - if given
202                        shared_ptr<RV> rv_ini=UI::build<RV>(set,"init_rv",UI::optional);
203                        if(rv_ini){ // check if
204                                vec val;
205                                UI::get(val, set, "init_values", UI::optional);
206                                if (val.length()!=rv_ini->_dsize()){
207                                        bdm_error("init_rv and init_values fields have incompatible sizes");
208                                } else {
209                                        ut2rgr.set_history(*rv_ini, val);
210                                        yt2rgr.set_history(*rv_ini, val);
211                                }
212                        }
213
214                        yt = zeros ( ipdf->dimension() );
215                        rgr = zeros ( ipdf->dimensionc() );
216                        ut = zeros(Urv._dsize());
217
218                        ytsize=yt.length();
219                        utsize=ut.length();
220                        dtsize = ytsize+utsize;
221                        validate();
222                }
223                void validate() {
224                        //taken from sample() - shift of history is not done here
225                        ut2rgr.filldown ( ut,rgr );
226                        yt2rgr.filldown ( yt,rgr );
227                        yt=ipdf->samplecond ( rgr );
228                }
229};
230UIREGISTER ( PdfDS );
231
232/*! Pseudovirtual class for reading data from files
233
234*/
235class FileDS: public MemDS {
236
237        public:
238                void getdata ( vec &dt ) {
239                        dt = Data.get_col ( time );
240                }
241
242                void getdata ( vec &dt, const ivec &indices ) {
243                        vec tmp = Data.get_col ( time );
244                        dt = tmp ( indices );
245                }
246
247                //! returns number of data in the file;
248                int ndat() {
249                        return Data.cols();
250                }
251                //! no sense to log this type
252                void log_register(logger &L, const string &prefix){};
253                //! no sense to log this type
254                void log_write ( ) const {};
255};
256
257/*!
258* \brief Read Data Matrix from an IT file
259
260The 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$!
261
262*/
263class ITppFileDS: public FileDS {
264
265        public:
266                //! Convenience constructor
267                ITppFileDS ( const string &fname, const string &varname ) : FileDS() {
268                        it_file it ( fname );
269                        it << Name ( varname );
270                        it >> Data;
271                        time = 0;
272                        //rowid and delays are ignored
273                };
274
275                ITppFileDS () : FileDS() {
276                };
277
278                void from_setting ( const Setting &set );
279
280                // TODO dodelat void to_setting( Setting &set ) const;
281
282};
283
284UIREGISTER ( ITppFileDS );
285SHAREDPTR ( ITppFileDS );
286
287/*!
288* \brief CSV file data storage
289The constructor creates \c Data matrix from the records in a CSV file \c fname. The orientation can be of two types:
2901. \c BY_COL which is default - the data are stored in columns; one column per time \f$t\f$, one row per data item.
2912. \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.
292
293*/
294class CsvFileDS: public FileDS {
295
296        public:
297                //! Constructor - create DS from a CSV file.
298                CsvFileDS ( const string& fname, const string& orientation = "BY_COL" );
299};
300
301
302
303// ARXDs - DELETED
304
305//! State-space data source simulating two densities
306class StateDS : public DS {
307        protected:
308                //!conditional pdf of the state evolution \f$ f(x_t|x_{t-1}) \f$
309                shared_ptr<pdf> IM;
310
311                //!conditional pdf of the observations \f$ f(d_t|x_t) \f$
312                shared_ptr<pdf> OM;
313
314                //! result storage
315                vec dt;
316                //! state storage
317                vec xt;
318                //! input storage
319                vec ut;
320
321                //! datalink from ut to IM.rvc
322                datalink_part u2imc;
323                //! datalink from ut to OM.rvc
324                datalink_part u2omc;
325        public:
326                void getdata ( vec &dt0 ) const {
327                        dt0 = dt;
328                }
329                void write (const vec &ut0 ) {
330                        ut = ut0;
331                }
332               
333                void getdata ( vec &dt0, const ivec &indices ) {
334                        dt0 = dt ( indices );
335                }
336
337                virtual void step() {
338                        vec imc(IM->dimensionc());
339                        imc.set_subvector(0,xt);
340                        u2imc.filldown(ut,imc);
341                        xt = IM->samplecond ( imc );
342                       
343                        vec omc(OM->dimensionc());
344                        omc.set_subvector(0,xt);
345                        u2omc.filldown(ut,omc);
346                        vec yt;
347                        yt = OM->samplecond ( omc );
348                        //fill all data
349                        dt.set_subvector(0,yt);
350                        dt.set_subvector(yt.length(),xt);
351                        dt.set_subvector(ytsize,ut);
352                }
353
354                //! set parameters
355                void set_parameters(shared_ptr<pdf> IM0, shared_ptr<pdf> OM0){
356                        IM=IM0;
357                        OM = OM0;
358                }
359                void set_initx(const vec &x0){xt=x0;}
360
361                /*! UI for stateDS
362
363                The DS is constructed from a structure with fields:
364                \code
365                class = "stateDS";
366                //Internal model
367                IM = { type = "mpdf-offspring"; };
368                //Observation model
369                OM = { type = "mpdf-offspring"; }
370                //initial state
371                x0 = [...]; //vector of data
372                \endcode
373                Both models must have defined \c rv. and \c rvc
374                Random variables not found in any rv are considered to be inputs.
375                */
376                void from_setting ( const Setting &set );
377
378                // TODO dodelat void to_setting( Setting &set ) const;
379
380                void validate();
381};
382
383UIREGISTER ( StateDS );
384SHAREDPTR ( StateDS );
385
386}; //namespace
387
388#endif // DS_H
Note: See TracBrowser for help on using the browser.