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

Revision 1121, 10.3 kB (checked in by smidl, 14 years ago)

Preparation for ARX with linear forgetting

  • 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 moidel with parameters in LS form
212class ARXls : public BMEF{
213        egw_ls<ldmat> est;
214       
215        const egw_ls<ldmat>& posterior() {return est;};
216       
217        void bayes(const vec &dt, const vec &psi){
218        }
219};
220
221/*! \brief ARX model conditined by knowledge of the forgetting factor
222\f[ f(    heta| d_1 \ldots d_t , \phi_t) \f]
223
224The symbol \f$ \phi \f$ is assumed to be the last of the conditioning variables.
225*/
226class ARXfrg : public ARX {
227public:
228    ARXfrg() : ARX() {};
229    //! copy constructor
230    ARXfrg ( const ARXfrg &A0 ) : ARX ( A0 ) {};
231    virtual ARXfrg* _copy() const {
232        ARXfrg *A = new ARXfrg ( *this );
233        return A;
234    }
235
236    void bayes ( const vec &val, const vec &cond ) {
237        bdm_assert_debug(cond.size()>rgrlen, "ARXfrg: Insufficient conditioning, frg not given.");
238        frg = cond ( rgrlen); // the first part after rgrlen
239        ARX::bayes ( val, cond.left(rgrlen) );
240    }
241    void validate() {
242        ARX::validate();
243        rvc.add ( RV ( "{phi }", vec_1 ( 1 ) ) );
244        dimc += 1;
245    }
246};
247UIREGISTER ( ARXfrg );
248
249
250/*! \brief ARX with partial forgetting
251
252Implements 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>.
253
254Note, that the weights have the same order as hypotheses in partial forgetting, and follow this scheme:
255\li 0 means that the parameter doesn't change,
256\li 1 means that the parameter varies.
257
258The combinations of parameters are described binary:
259\f{bmatrix}[
260  0 & 0 & 0 & \ldots \\
261  1 & 0 & 0 & \ldots \\
262  0 & 1 & 0 & \ldots \\
263  1 & 1 & 0 & \ldots \\
264  \vdots & \vdots & \vdots & \vdots
265\f{bmatrix}]
266Notice, 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.
267
268See ARX class for more information about ARX.
269*/
270class ARXpartialforg : public ARX {
271public:
272    ARXpartialforg() : ARX(1.0) {};
273    //! copy constructor
274    ARXpartialforg ( const ARXpartialforg &A0 ) : ARX ( A0 ) {};
275    virtual ARXpartialforg* _copy() const {
276        ARXpartialforg *A = new ARXpartialforg ( *this );
277        return A;
278    }
279
280    void bayes ( const vec &val, const vec &cond );
281
282    void validate() {
283        ARX::validate();
284        int philen = 1 << (est._V().cols() - 1);
285        rvc.add ( RV ( "{phi }", vec_1(philen) ) ); // pocet 2^parametru
286        dimc += philen;
287    }
288};
289UIREGISTER ( ARXpartialforg );
290
291
292////////////////////
293template<class sq_T>
294shared_ptr< mlnorm<sq_T> > ARX::ml_predictor ( ) const {
295    shared_ptr< mlnorm<sq_T> > tmp = new mlnorm<sq_T> ( );
296    tmp->set_rv ( yrv );
297    tmp->set_rvc ( _rvc() );
298
299    ml_predictor_update ( *tmp );
300    tmp->validate();
301    return tmp;
302}
303
304template<class sq_T>
305void ARX::ml_predictor_update ( mlnorm<sq_T> &pred ) const {
306    mat mu ( dimy, posterior()._V().rows() - dimy );
307    mat R ( dimy, dimy );
308
309    est.mean_mat ( mu, R ); //mu =
310    mu = mu.T();
311    //correction for student-t  -- TODO check if correct!!
312
313    if ( have_constant ) { // constant term
314        //Assume the constant term is the last one:
315        pred.set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), sq_T ( R ) );
316    } else {
317        pred.set_parameters ( mu, zeros ( dimy ), sq_T ( R ) );
318    }
319}
320
321};
322#endif // AR_H
323
Note: See TracBrowser for help on using the browser.