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

Revision 1036, 9.0 kB (checked in by dedecius, 14 years ago)

slightly improved documentation of ARXpartialforg

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