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

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

Making tutorial/userguide example work again (changes of mpdf and bayes)

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