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

Revision 1064, 9.8 kB (checked in by mido, 14 years ago)

astyle applied all over the library

  • 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 = \theta_1 \psi_1 + \theta_2 + \psi_2 +\ldots + \theta_n \psi_n + r e_t
30\f]
31where unknown parameters \c rv are \f$[\theta 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        \todo 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    /*! UI for ARX estimator
135
136    \code
137    class = 'ARX';
138    yrv   = RV({names_of_dt} )                 // description of output variables
139    rgr   = RV({names_of_regressors}, [-1,-2]} // description of regressor variables
140    constant = 1;                              // 0/1 switch if the constant term is modelled or not
141
142    --- optional ---
143    prior = {class='egiw',...};                // Prior density, when given default is used instead
144    alternative = {class='egiw',...};          // Alternative density in stabilized estimation, when not given prior is used
145
146    frg = 1.0;                                 // forgetting, default frg=1.0
147
148    rv  = RV({names_of_parameters}}            // description of parametetr names
149                                                                                   // default: [""]
150    \endcode
151    */
152    void from_setting ( const Setting &set );
153
154    void validate() {
155        BMEF::validate();
156        est.validate();
157
158        // When statistics is defined, it has priority
159        if(posterior()._dimx()>0) {//statistics is assigned
160            dimy = posterior()._dimx();
161            rgrlen=posterior()._V().rows() - dimy - int ( have_constant == true );
162            dimc = rgrlen;
163        } else { // statistics is not assigned - build it from dimy and rgrlen
164            bdm_assert(dimy>0,"No way to validate egiw: empty statistics and empty dimy");
165            est.set_parameters(dimy, zeros(dimy+rgrlen+int(have_constant==true)));
166            set_prior_default(est);
167        }
168        if (alter_est.dimension()==0) alter_est=est;
169
170        dyad = ones ( est._V().rows() );
171    }
172    //! function sets prior and alternative density
173    void set_prior ( const epdf *prior );
174    //! build default prior and alternative when all values are set
175    void set_prior_default ( egiw &prior ) {
176        //assume
177        vec dV0 ( prior._V().rows() );
178        dV0.set_subvector ( 0, prior._dimx() - 1, 1.0 );
179        if (dV0.length()>prior._dimx())
180            dV0.set_subvector ( prior._dimx(), dV0.length() - 1, 1e-5 );
181
182        prior.set_parameters ( prior._dimx(), ldmat ( dV0 ) );
183        prior.validate();
184    }
185
186    void to_setting ( Setting &set ) const
187    {
188        BMEF::to_setting( set ); // takes care of rv, yrv, rvc
189        UI::save(rgr, set, "rgr");
190        int constant = have_constant ? 1 : 0;
191        UI::save(constant, set, "constant");
192        UI::save(&alter_est, set, "alternative");
193        UI::save(&posterior(), set, "posterior");
194
195    }
196    //! access function
197    RV & _rgr() {
198        return rgr;
199    }
200    bool _have_constant() {
201        return have_constant;
202    }
203    int _rgrlen() {
204        return rgrlen;
205    }
206};
207UIREGISTER ( ARX );
208SHAREDPTR ( ARX );
209
210/*! ARX model conditined by knowledge of the forgetting factor
211\f[ f(\theta| d_1 \ldots d_t , \phi_t) \f]
212
213The symbol \f$ \phi \f$ is assumed to be the last of the conditioning variables.
214*/
215class ARXfrg : public ARX {
216public:
217    ARXfrg() : ARX() {};
218    //! copy constructor
219    ARXfrg ( const ARXfrg &A0 ) : ARX ( A0 ) {};
220    virtual ARXfrg* _copy() const {
221        ARXfrg *A = new ARXfrg ( *this );
222        return A;
223    }
224
225    void bayes ( const vec &val, const vec &cond ) {
226        bdm_assert_debug(cond.size()>rgrlen, "ARXfrg: Insufficient conditioning, frg not given.");
227        frg = cond ( rgrlen); // the first part after rgrlen
228        ARX::bayes ( val, cond.left(rgrlen) );
229    }
230    void validate() {
231        ARX::validate();
232        rvc.add ( RV ( "{phi }", vec_1 ( 1 ) ) );
233        dimc += 1;
234    }
235};
236UIREGISTER ( ARXfrg );
237
238
239/*! \brief ARX with partial forgetting
240
241Implements 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>.
242
243Note, that the weights have the same order as hypotheses in partial forgetting, and follow this scheme:
244\li 0 means that the parameter doesn't change,
245\li 1 means that the parameter varies.
246
247The combinations of parameters are described binary:
248\f{bmatrix}[
249  0 & 0 & 0 & \ldots \\
250  1 & 0 & 0 & \ldots \\
251  0 & 1 & 0 & \ldots \\
252  1 & 1 & 0 & \ldots \\
253  \vdots & \vdots & \vdots & \vdots
254\f{bmatrix}]
255Notice, 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.
256
257See ARX class for more information about ARX.
258*/
259class ARXpartialforg : public ARX {
260public:
261    ARXpartialforg() : ARX(1.0) {};
262    //! copy constructor
263    ARXpartialforg ( const ARXpartialforg &A0 ) : ARX ( A0 ) {};
264    virtual ARXpartialforg* _copy() const {
265        ARXpartialforg *A = new ARXpartialforg ( *this );
266        return A;
267    }
268
269    void bayes ( const vec &val, const vec &cond );
270
271    void validate() {
272        ARX::validate();
273        int philen = 1 << (est._V().cols() - 1);
274        rvc.add ( RV ( "{phi }", vec_1(philen) ) ); // pocet 2^parametru
275        dimc += philen;
276    }
277};
278UIREGISTER ( ARXpartialforg );
279
280
281////////////////////
282template<class sq_T>
283shared_ptr< mlnorm<sq_T> > ARX::ml_predictor ( ) const {
284    shared_ptr< mlnorm<sq_T> > tmp = new mlnorm<sq_T> ( );
285    tmp->set_rv ( yrv );
286    tmp->set_rvc ( _rvc() );
287
288    ml_predictor_update ( *tmp );
289    tmp->validate();
290    return tmp;
291}
292
293template<class sq_T>
294void ARX::ml_predictor_update ( mlnorm<sq_T> &pred ) const {
295    mat mu ( dimy, posterior()._V().rows() - dimy );
296    mat R ( dimy, dimy );
297
298    est.mean_mat ( mu, R ); //mu =
299    mu = mu.T();
300    //correction for student-t  -- TODO check if correct!!
301
302    if ( have_constant ) { // constant term
303        //Assume the constant term is the last one:
304        pred.set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), sq_T ( R ) );
305    } else {
306        pred.set_parameters ( mu, zeros ( dimy ), sq_T ( R ) );
307    }
308}
309
310};
311#endif // AR_H
312
Note: See TracBrowser for help on using the browser.