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

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

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