root/library/bdm/estim/arx.h @ 1077

Revision 1077, 10.1 kB (checked in by mido, 14 years ago)

another update of doc - all bayesian models until bdm::MultiModel? finished
also MixEF::MixEF_options renamed just to MixEF::Options

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Bayesian Filtering for generalized autoregressive (ARX) model
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 AR_H
14#define AR_H
15
16#include "../math/functions.h"
17#include "../stat/exp_family.h"
18#include "../base/user_info.h"
19//#include "../estim/kalman.h"
20#include "arx_straux.h"
21
22namespace bdm {
23
24/*!
25* \brief Linear Autoregressive model with Gaussian noise
26
27Regression of the following kind:
28\f[
29y_t =     heta_1 \psi_1 +     heta_2 + \psi_2 +\ldots +     heta_n \psi_n + r e_t
30\f]
31where unknown parameters \c rv are \f$[    heta r]\f$, regression vector \f$\psi=\psi(y_{1:t},u_{1:t})\f$ is a known function of past outputs and exogeneous variables \f$u_t\f$. Distrubances \f$e_t\f$ are supposed to be normally distributed:
32\f[
33e_t \sim \mathcal{N}(0,1).
34\f]
35
36See \ref tut_arx for mathematical treatment.
37
38The easiest way how to use the class is:
39\include arx_simple.cpp
40
41            odo sort out constant terms - bayes should accept vec without additional 1s
42*/
43class ARX: public BMEF {
44protected:
45    //! switch if constant is modelled or not
46    bool have_constant;
47    //! vector of dyadic update
48    vec dyad;
49    //! RV of regressor
50    RV rgr;
51    //! length of the regressor (without optional constant)
52    int rgrlen;
53    //! posterior density
54    egiw est;
55    //! Alternative estimate of parameters, used in stabilized forgetting, see [Kulhavy]
56    egiw alter_est;
57public:
58    //! \name Constructors
59    //!@{
60    ARX ( const double frg0 = 1.0 ) : BMEF ( frg0 ),  have_constant ( true ), dyad(), rgrlen(),est(), alter_est() {};
61    ARX ( const ARX &A0 ) : BMEF ( A0 ),  have_constant ( A0.have_constant ), dyad ( A0.dyad ),rgrlen(A0.rgrlen), est ( A0.est ), alter_est ( A0.alter_est ) { };
62
63    ARX* _copy() const;
64
65    void set_frg ( double frg0 ) {
66        frg = frg0;
67    }
68    void set_constant ( bool const0 ) {
69        have_constant = const0;
70    }
71    void set_statistics ( int dimy0, const ldmat V0, double nu0 = -1.0 ) {
72        est.set_parameters ( dimy0, V0, nu0 );
73        est.validate();
74        last_lognc = est.lognc();
75        dimy = dimy0;
76    }
77    //!@}
78
79    //! Set sufficient statistics
80    void set_statistics ( const BMEF* BM0 );
81
82    //!\name Mathematical operations
83    //!@{
84
85    //! Weighted Bayes \f$ dt = [y_t psi_t] \f$.
86    void bayes_weighted ( const vec &yt, const vec &cond = empty_vec, const double w = 1.0 );
87    void bayes ( const vec &yt, const vec &cond = empty_vec ) {
88        bayes_weighted ( yt, cond, 1.0 );
89    };
90    double logpred ( const vec &yt, const vec &cond ) const;
91    void flatten ( const BMEF* B , double weight );
92    //! Conditioned version of the predictor
93    enorm<ldmat>* epredictor ( const vec &rgr ) const;
94    //! conditional version of the predictor
95    template<class sq_T>
96    shared_ptr<mlnorm<sq_T> > ml_predictor() const;
97    //! fast version of predicto
98    template<class sq_T>
99    void ml_predictor_update ( mlnorm<sq_T> &pred ) const;
100    mlstudent* predictor_student() const;
101    //! Brute force structure estimation.\return indices of accepted regressors.
102    ivec structure_est ( const egiw &Eg0 );
103    //! Smarter structure estimation by Ludvik Tesar.\return indices of accepted regressors.
104    ivec structure_est_LT ( const egiw &Eg0 );
105    //! reduce structure to the given ivec of matrix V
106    void reduce_structure(ivec &inds_in_V) {
107        ldmat V = posterior()._V();
108        if (max(inds_in_V)>=V.rows()) {
109            bdm_error("Incompatible structure");
110        }
111
112        ldmat newV(V,inds_in_V);
113        est.set_parameters(dimy,newV, posterior()._nu());
114
115        if (have_constant) {
116            ivec rgr_elem= find(inds_in_V<(V.rows()-1)); // < -- find non-constant
117            rgr = rgr.subselect(rgr_elem);
118            rgrlen = rgr_elem.length();
119        } else {
120            rgr = rgr.subselect(inds_in_V);
121        }
122        validate();
123    }
124    //!@}
125
126    //!\name Access attributes
127    //!@{
128    //! return correctly typed posterior (covariant return)
129    const egiw& posterior() const {
130        return est;
131    }
132    //!@}
133
134    /*! Create object from the following structure
135
136    \code
137    class = 'ARX';
138    rgr = RV({'names',...},[sizes,...],[times,...]);   % description of regressor variables
139    --- optional fields ---   
140    prior = configuration of bdm::egiw;                % any offspring of eqiw for prior density, bdm::egiw::from_setting
141    alternative = configuration of bdm::egiw;          % any offspring of eqiw for alternative density in stabilized estimation of prior density   
142    constant = [];                                     % 0/1 switch if the constant term is modelled or not
143    --- inherited fields ---
144    bdm::BMEF::from_setting
145    \endcode
146    If the optional fields are not given, they will be filled as follows:
147    \code
148    prior = posterior;                                % when prior is not given the posterior is used (TODO it is unclear)
149    alternative = prior;                              % when alternative is not given the prior is used
150    constant = 1;                                     % constant term is modelled on default
151    \endcode
152    */
153    void from_setting ( const Setting &set );
154
155    void validate() {
156        BMEF::validate();
157        est.validate();
158
159        // When statistics is defined, it has priority
160        if(posterior()._dimx()>0) {//statistics is assigned
161            dimy = posterior()._dimx();
162            rgrlen=posterior()._V().rows() - dimy - int ( have_constant == true );
163            dimc = rgrlen;
164        } else { // statistics is not assigned - build it from dimy and rgrlen
165            bdm_assert(dimy>0,"No way to validate egiw: empty statistics and empty dimy");
166            est.set_parameters(dimy, zeros(dimy+rgrlen+int(have_constant==true)));
167            set_prior_default(est);
168        }
169        if (alter_est.dimension()==0) alter_est=est;
170
171        dyad = ones ( est._V().rows() );
172    }
173    //! function sets prior and alternative density
174    void set_prior ( const epdf *prior );
175    //! build default prior and alternative when all values are set
176    void set_prior_default ( egiw &prior ) {
177        //assume
178        vec dV0 ( prior._V().rows() );
179        dV0.set_subvector ( 0, prior._dimx() - 1, 1.0 );
180        if (dV0.length()>prior._dimx())
181            dV0.set_subvector ( prior._dimx(), dV0.length() - 1, 1e-5 );
182
183        prior.set_parameters ( prior._dimx(), ldmat ( dV0 ) );
184        prior.validate();
185    }
186
187    void to_setting ( Setting &set ) const
188    {
189        BMEF::to_setting( set ); // takes care of rv, yrv, rvc
190        UI::save(rgr, set, "rgr");
191        int constant = have_constant ? 1 : 0;
192        UI::save(constant, set, "constant");
193        UI::save(&alter_est, set, "alternative");
194        UI::save(&posterior(), set, "posterior");
195
196    }
197    //! access function
198    RV & _rgr() {
199        return rgr;
200    }
201    bool _have_constant() {
202        return have_constant;
203    }
204    int _rgrlen() {
205        return rgrlen;
206    }
207};
208UIREGISTER ( ARX );
209SHAREDPTR ( ARX );
210
211/*! \brief ARX model conditined by knowledge of the forgetting factor
212\f[ f(    heta| d_1 \ldots d_t , \phi_t) \f]
213
214The symbol \f$ \phi \f$ is assumed to be the last of the conditioning variables.
215*/
216class ARXfrg : public ARX {
217public:
218    ARXfrg() : ARX() {};
219    //! copy constructor
220    ARXfrg ( const ARXfrg &A0 ) : ARX ( A0 ) {};
221    virtual ARXfrg* _copy() const {
222        ARXfrg *A = new ARXfrg ( *this );
223        return A;
224    }
225
226    void bayes ( const vec &val, const vec &cond ) {
227        bdm_assert_debug(cond.size()>rgrlen, "ARXfrg: Insufficient conditioning, frg not given.");
228        frg = cond ( rgrlen); // the first part after rgrlen
229        ARX::bayes ( val, cond.left(rgrlen) );
230    }
231    void validate() {
232        ARX::validate();
233        rvc.add ( RV ( "{phi }", vec_1 ( 1 ) ) );
234        dimc += 1;
235    }
236};
237UIREGISTER ( ARXfrg );
238
239
240/*! \brief ARX with partial forgetting
241
242Implements partial forgetting when <tt>bayes(const vec &yt, const vec &cond=empty_vec)</tt> is called, where \c cond is a vector <em>(regressor', forg.factor')</em>.
243
244Note, that the weights have the same order as hypotheses in partial forgetting, and follow this scheme:
245\li 0 means that the parameter doesn't change,
246\li 1 means that the parameter varies.
247
248The combinations of parameters are described binary:
249\f{bmatrix}[
250  0 & 0 & 0 & \ldots \\
251  1 & 0 & 0 & \ldots \\
252  0 & 1 & 0 & \ldots \\
253  1 & 1 & 0 & \ldots \\
254  \vdots & \vdots & \vdots & \vdots
255\f{bmatrix}]
256Notice, that each n-th column has altering n-tuples of 1's and 0's, n = 0,...,number of params. Hence, the first forg. factor relates to the situation when no parameter changes, the second one when the first parameter changes etc.
257
258See ARX class for more information about ARX.
259*/
260class ARXpartialforg : public ARX {
261public:
262    ARXpartialforg() : ARX(1.0) {};
263    //! copy constructor
264    ARXpartialforg ( const ARXpartialforg &A0 ) : ARX ( A0 ) {};
265    virtual ARXpartialforg* _copy() const {
266        ARXpartialforg *A = new ARXpartialforg ( *this );
267        return A;
268    }
269
270    void bayes ( const vec &val, const vec &cond );
271
272    void validate() {
273        ARX::validate();
274        int philen = 1 << (est._V().cols() - 1);
275        rvc.add ( RV ( "{phi }", vec_1(philen) ) ); // pocet 2^parametru
276        dimc += philen;
277    }
278};
279UIREGISTER ( ARXpartialforg );
280
281
282////////////////////
283template<class sq_T>
284shared_ptr< mlnorm<sq_T> > ARX::ml_predictor ( ) const {
285    shared_ptr< mlnorm<sq_T> > tmp = new mlnorm<sq_T> ( );
286    tmp->set_rv ( yrv );
287    tmp->set_rvc ( _rvc() );
288
289    ml_predictor_update ( *tmp );
290    tmp->validate();
291    return tmp;
292}
293
294template<class sq_T>
295void ARX::ml_predictor_update ( mlnorm<sq_T> &pred ) const {
296    mat mu ( dimy, posterior()._V().rows() - dimy );
297    mat R ( dimy, dimy );
298
299    est.mean_mat ( mu, R ); //mu =
300    mu = mu.T();
301    //correction for student-t  -- TODO check if correct!!
302
303    if ( have_constant ) { // constant term
304        //Assume the constant term is the last one:
305        pred.set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), sq_T ( R ) );
306    } else {
307        pred.set_parameters ( mu, zeros ( dimy ), sq_T ( R ) );
308    }
309}
310
311};
312#endif // AR_H
313
Note: See TracBrowser for help on using the browser.