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

Revision 1131, 10.4 kB (checked in by smidl, 14 years ago)

egiw LS

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