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

Revision 1176, 10.5 kB (checked in by smidl, 14 years ago)

student epredictor in ARX

  • 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        vec samplepred (  const vec &cond ) const;
92        void flatten ( const BMEF* B , double weight );
93    //! Conditioned version of the predictor
94    enorm<ldmat>* epredictor ( const vec &rgr ) const;
95        estudent<ldmat>* epredictor_student ( const vec &rgr ) const;
96        //! conditional version of the predictor
97    template<class sq_T>
98    shared_ptr<mlnorm<sq_T> > ml_predictor() const;
99    //! fast version of predicto
100    template<class sq_T>
101    void ml_predictor_update ( mlnorm<sq_T> &pred ) const;
102    mlstudent* predictor() const;
103    //! Brute force structure estimation.\return indices of accepted regressors.
104    ivec structure_est ( const egiw &Eg0 );
105    //! Smarter structure estimation by Ludvik Tesar.\return indices of accepted regressors.
106    ivec structure_est_LT ( const egiw &Eg0 );
107    //! reduce structure to the given ivec of matrix V
108    void reduce_structure(ivec &inds_in_V) {
109        ldmat V = posterior()._V();
110        if (max(inds_in_V)>=V.rows()) {
111            bdm_error("Incompatible structure");
112        }
113
114        ldmat newV(V,inds_in_V);
115        est.set_parameters(dimy,newV, posterior()._nu());
116
117        if (have_constant) {
118            ivec rgr_elem= find(inds_in_V<(V.rows()-1)); // < -- find non-constant
119            rgr = rgr.subselect(rgr_elem);
120            rgrlen = rgr_elem.length();
121        } else {
122            rgr = rgr.subselect(inds_in_V);
123        }
124        validate();
125    }
126    //!@}
127
128    //!\name Access attributes
129    //!@{
130    //! return correctly typed posterior (covariant return)
131    const egiw& posterior() const {
132        return est;
133    }
134    //!@}
135
136    /*! Create object from the following structure
137
138    \code
139    class = 'ARX';
140    rgr = RV({'names',...},[sizes,...],[times,...]);   % description of regressor variables
141    --- optional fields ---   
142    prior = configuration of bdm::egiw;                % any offspring of eqiw for prior density, bdm::egiw::from_setting
143    alternative = configuration of bdm::egiw;          % any offspring of eqiw for alternative density in stabilized estimation of prior density   
144    constant = [];                                     % 0/1 switch if the constant term is modelled or not
145    --- inherited fields ---
146    bdm::BMEF::from_setting
147    \endcode
148    If the optional fields are not given, they will be filled as follows:
149    \code
150    prior = posterior;                                % when prior is not given the posterior is used (TODO it is unclear)
151    alternative = prior;                              % when alternative is not given the prior is used
152    constant = 1;                                     % constant term is modelled on default
153    \endcode
154    */
155    void from_setting ( const Setting &set );
156
157    void validate() {
158        BMEF::validate();
159        est.validate();
160
161        // When statistics is defined, it has priority
162        if(posterior()._dimx()>0) {//statistics is assigned
163            dimy = posterior()._dimx();
164            rgrlen=posterior()._V().rows() - dimy - int ( have_constant == true );
165            dimc = rgrlen;
166        } else { // statistics is not assigned - build it from dimy and rgrlen
167            bdm_assert(dimy>0,"No way to validate egiw: empty statistics and empty dimy");
168            est.set_parameters(dimy, zeros(dimy+rgrlen+int(have_constant==true)));
169            set_prior_default(est);
170        }
171        if (alter_est.dimension()==0) alter_est=est;
172
173        dyad = ones ( est._V().rows() );
174    }
175    //! function sets prior and alternative density
176    void set_prior ( const epdf *prior );
177    //! build default prior and alternative when all values are set
178    void set_prior_default ( egiw &prior ) {
179        //assume
180        vec dV0 ( prior._V().rows() );
181        dV0.set_subvector ( 0, prior._dimx() - 1, 1.0 );
182        if (dV0.length()>prior._dimx())
183            dV0.set_subvector ( prior._dimx(), dV0.length() - 1, 1e-5 );
184
185        prior.set_parameters ( prior._dimx(), ldmat ( dV0 ) );
186        prior.validate();
187    }
188
189    void to_setting ( Setting &set ) const
190    {
191        BMEF::to_setting( set ); // takes care of rv, yrv, rvc
192        UI::save(rgr, set, "rgr");
193        int constant = have_constant ? 1 : 0;
194        UI::save(constant, set, "constant");
195        UI::save(&alter_est, set, "alternative");
196        UI::save(&posterior(), set, "posterior");
197
198    }
199    //! access function
200    RV & _rgr() {
201        return rgr;
202    }
203    bool _have_constant() {
204        return have_constant;
205    }
206    int _rgrlen() {
207        return rgrlen;
208    }
209};
210UIREGISTER ( ARX );
211SHAREDPTR ( ARX );
212
213//! \brief ARX moidel with parameters in LS form
214class ARXls : public BMEF{
215  public:
216        egw_ls<ldmat> est;
217       
218        egw_ls<ldmat> alternative;
219       
220        const egw_ls<ldmat>& posterior() {return est;};
221       
222        void bayes(const vec &dt, const vec &psi){
223          ldmat &Pbeta = est.P;
224          ldmat &Palpha = alternative.P;
225         
226         
227        }
228};
229
230/*! \brief ARX model conditined by knowledge of the forgetting factor
231\f[ f(    heta| d_1 \ldots d_t , \phi_t) \f]
232
233The symbol \f$ \phi \f$ is assumed to be the last of the conditioning variables.
234*/
235class ARXfrg : public ARX {
236public:
237    ARXfrg() : ARX() {};
238    //! copy constructor
239    ARXfrg ( const ARXfrg &A0 ) : ARX ( A0 ) {};
240    virtual ARXfrg* _copy() const {
241        ARXfrg *A = new ARXfrg ( *this );
242        return A;
243    }
244
245    void bayes ( const vec &val, const vec &cond ) {
246        bdm_assert_debug(cond.size()>rgrlen, "ARXfrg: Insufficient conditioning, frg not given.");
247        frg = cond ( rgrlen); // the first part after rgrlen
248        ARX::bayes ( val, cond.left(rgrlen) );
249    }
250    void validate() {
251        ARX::validate();
252        rvc.add ( RV ( "{phi }", vec_1 ( 1 ) ) );
253        dimc += 1;
254    }
255};
256UIREGISTER ( ARXfrg );
257
258
259/*! \brief ARX with partial forgetting
260
261Implements 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>.
262
263Note, that the weights have the same order as hypotheses in partial forgetting, and follow this scheme:
264\li 0 means that the parameter doesn't change,
265\li 1 means that the parameter varies.
266
267The combinations of parameters are described binary:
268\f{bmatrix}[
269  0 & 0 & 0 & \ldots \\
270  1 & 0 & 0 & \ldots \\
271  0 & 1 & 0 & \ldots \\
272  1 & 1 & 0 & \ldots \\
273  \vdots & \vdots & \vdots & \vdots
274\f{bmatrix}]
275Notice, 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.
276
277See ARX class for more information about ARX.
278*/
279class ARXpartialforg : public ARX {
280public:
281    ARXpartialforg() : ARX(1.0) {};
282    //! copy constructor
283    ARXpartialforg ( const ARXpartialforg &A0 ) : ARX ( A0 ) {};
284    virtual ARXpartialforg* _copy() const {
285        ARXpartialforg *A = new ARXpartialforg ( *this );
286        return A;
287    }
288
289    void bayes ( const vec &val, const vec &cond );
290
291    void validate() {
292        ARX::validate();
293        int philen = 1 << (est._V().cols() - 1);
294        rvc.add ( RV ( "{phi }", vec_1(philen) ) ); // pocet 2^parametru
295        dimc += philen;
296    }
297};
298UIREGISTER ( ARXpartialforg );
299
300
301////////////////////
302template<class sq_T>
303shared_ptr< mlnorm<sq_T> > ARX::ml_predictor ( ) const {
304    shared_ptr< mlnorm<sq_T> > tmp = new mlnorm<sq_T> ( );
305    tmp->set_rv ( yrv );
306    tmp->set_rvc ( _rvc() );
307
308    ml_predictor_update ( *tmp );
309    tmp->validate();
310    return tmp;
311}
312
313template<class sq_T>
314void ARX::ml_predictor_update ( mlnorm<sq_T> &pred ) const {
315    mat mu ( dimy, posterior()._V().rows() - dimy );
316    mat R ( dimy, dimy );
317
318    est.mean_mat ( mu, R ); //mu =
319    mu = mu.T();
320    //correction for student-t  -- TODO check if correct!!
321
322    if ( have_constant ) { // constant term
323        //Assume the constant term is the last one:
324        pred.set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), sq_T ( R ) );
325    } else {
326        pred.set_parameters ( mu, zeros ( dimy ), sq_T ( R ) );
327    }
328}
329
330};
331#endif // AR_H
332
Note: See TracBrowser for help on using the browser.