root/library/bdm/estim/arx.cpp @ 1003

Revision 1003, 7.5 kB (checked in by smidl, 14 years ago)

corrections in ARX

  • Property svn:eol-style set to native
RevLine 
[97]1#include "arx.h"
[270]2namespace bdm {
[13]3
[700]4void ARX::bayes_weighted ( const vec &yt, const vec &cond, const double w ) {
[990]5        bdm_assert_debug ( yt.length() == dimy, "ARX::bayes yt is of size "+num2str(yt.length())+" expected dimension is "+num2str(dimy) );
6        bdm_assert_debug ( cond.length() == rgrlen , "ARX::bayes cond is of size "+num2str(cond.length())+" expected dimension is "+num2str(rgrlen) );
[996]7       
8        BMEF::bayes_weighted(yt,cond,w); //potential discount scheduling
9       
[97]10        double lnc;
[679]11        //cache
[737]12        ldmat &V = est._V();
13        double &nu = est._nu();
[679]14
[737]15        dyad.set_subvector ( 0, yt );
[741]16        if (cond.length()>0)
17                dyad.set_subvector ( dimy, cond );
[679]18        // possible "1" is there from the beginning
[737]19
[477]20        if ( frg < 1.0 ) {
[665]21                est.pow ( frg ); // multiply V and nu
[679]22
[737]23
[639]24                //stabilize
[737]25                ldmat V0 = alter_est._V(); //$ copy
26                double &nu0 = alter_est._nu();
27
28                V0 *= ( 1 - frg );
[639]29                V += V0; //stabilization
[737]30                nu += ( 1 - frg ) * nu0;
31
[665]32                // recompute loglikelihood of new "prior"
[170]33                if ( evalll ) {
[162]34                        last_lognc = est.lognc();
35                }
36        }
[679]37        V.opupdt ( dyad, w );
[477]38        nu += w;
[97]39
[204]40        // log(sqrt(2*pi)) = 0.91893853320467
[97]41        if ( evalll ) {
42                lnc = est.lognc();
[204]43                ll = lnc - last_lognc - 0.91893853320467;
[97]44                last_lognc = lnc;
45        }
46}
47
[679]48double ARX::logpred ( const vec &yt ) const {
[170]49        egiw pred ( est );
[477]50        ldmat &V = pred._V();
51        double &nu = pred._nu();
[170]52
53        double lll;
[679]54        vec dyad_p = dyad;
[737]55        dyad_p.set_subvector ( 0, yt );
[170]56
[477]57        if ( frg < 1.0 ) {
[170]58                pred.pow ( frg );
59                lll = pred.lognc();
[477]60        } else//should be save: last_lognc is changed only by bayes;
61                if ( evalll ) {
62                        lll = last_lognc;
63                } else {
64                        lll = pred.lognc();
65                }
[170]66
[679]67        V.opupdt ( dyad_p, 1.0 );
[477]68        nu += 1.0;
[201]69        // log(sqrt(2*pi)) = 0.91893853320467
[477]70        return pred.lognc() - lll - 0.91893853320467;
[170]71}
72
[738]73void ARX::flatten ( const BMEF* B ) {
74        const ARX* A = dynamic_cast<const ARX*> ( B );
75        // nu should be equal to B.nu
76        est.pow ( A->posterior()._nu() / posterior()._nu() );
77        if ( evalll ) {
78                last_lognc = est.lognc();
79        }
80}
81
[766]82ARX* ARX::_copy ( ) const {
[477]83        ARX* Tmp = new ARX ( *this );
[170]84        return Tmp;
85}
86
87void ARX::set_statistics ( const BMEF* B0 ) {
[477]88        const ARX* A0 = dynamic_cast<const ARX*> ( B0 );
[170]89
[679]90        bdm_assert_debug ( dimension() == A0->dimension(), "Statistics of different dimensions" );
91        set_statistics ( A0->dimensiony(), A0->posterior()._V(), A0->posterior()._nu() );
[170]92}
[180]93
[1003]94enorm<ldmat>* ARX::epredictor ( const vec &cond ) const {
95        bdm_assert_debug ( cond.length() == rgrlen , "ARX::epredictor cond is of size "+num2str(cond.length())+" expected dimension is "+num2str(rgrlen) );
96       
[679]97        mat mu ( dimy, posterior()._V().rows() - dimy );
98        mat R ( dimy, dimy );
[270]99
[1003]100        vec ext_rgr;
101        if (have_constant){
102                ext_rgr = concat(cond,vec_1(1.0));
103        } else {
104                ext_rgr = cond;
105        }
106       
[198]107        enorm<ldmat>* tmp;
[477]108        tmp = new enorm<ldmat> ( );
[270]109        //TODO: too hackish
[679]110        if ( yrv._dsize() > 0 ) {
[270]111        }
[198]112
[477]113        est.mean_mat ( mu, R ); //mu =
[198]114        //correction for student-t  -- TODO check if correct!!
115        //R*=nu/(nu-2);
[973]116        if (mu.cols()>0) {// nonempty egiw
[1003]117                mat p_mu = mu.T() * ext_rgr;    //the result is one column
[973]118                tmp->set_parameters ( p_mu.get_col ( 0 ), ldmat ( R ) );
119        } else {
120                tmp->set_parameters ( zeros( R.rows() ), ldmat ( R ) );
121        }
122        if (dimy==yrv._dsize())
123                tmp->set_rv(yrv);
[198]124        return tmp;
125}
126
[270]127mlstudent* ARX::predictor_student ( ) const {
[679]128        const ldmat &V = posterior()._V();
[737]129
[679]130        mat mu ( dimy, V.rows() - dimy );
131        mat R ( dimy, dimy );
[198]132        mlstudent* tmp;
[477]133        tmp = new mlstudent ( );
[198]134
[477]135        est.mean_mat ( mu, R ); //
[198]136        mu = mu.T();
[270]137
[477]138        int end = V._L().rows() - 1;
[679]139        ldmat Lam ( V._L() ( dimy, end, dimy, end ), V._D() ( dimy, end ) );  //exp val of R
[198]140
141
[737]142        if ( have_constant ) { // no constant term
[198]143                //Assume the constant term is the last one:
[477]144                if ( mu.cols() > 1 ) {
145                        tmp->set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), ldmat ( R ), Lam );
146                } else {
[679]147                        tmp->set_parameters ( mat ( dimy, dimc ), mu.get_col ( mu.cols() - 1 ), ldmat ( R ), Lam );
[270]148                }
[625]149        } else {
150                // no constant term
[679]151                tmp->set_parameters ( mu, zeros ( dimy ), ldmat ( R ), Lam );
[198]152        }
[180]153        return tmp;
154}
155
[585]156
157
[97]158/*! \brief Return the best structure
159@param Eg a copy of GiW density that is being examined
160@param Eg0 a copy of prior GiW density before estimation
161@param Egll likelihood of the current Eg
[896]162@param indices current indices
[97]163\return best likelihood in the structure below the given one
164*/
[896]165double egiw_bestbelow ( egiw Eg, egiw Eg0, double Egll, ivec &indices ) { //parameter Eg is a copy!
[97]166        ldmat Vo = Eg._V(); //copy
167        ldmat Vo0 = Eg._V(); //copy
168        ldmat& Vp = Eg._V(); // pointer into Eg
169        ldmat& Vp0 = Eg._V(); // pointer into Eg
[477]170        int end = Vp.rows() - 1;
[97]171        int i;
172        mat Li;
173        mat Li0;
[477]174        double maxll = Egll;
175        double tmpll = Egll;
176        double belll = Egll;
[97]177
[896]178        ivec tmpindices;
179        ivec maxindices = indices;
[97]180
[115]181
[896]182        cout << "bb:(" << indices << ") ll=" << Egll << endl;
[115]183
[97]184        //try to remove only one rv
[477]185        for ( i = 0; i < end; i++ ) {
[97]186                //copy original
187                Li = Vo._L();
188                Li0 = Vo0._L();
189                //remove stuff
[477]190                Li.del_col ( i + 1 );
191                Li0.del_col ( i + 1 );
192                Vp.ldform ( Li, Vo._D() );
193                Vp0.ldform ( Li0, Vo0._D() );
194                tmpll = Eg.lognc() - Eg0.lognc(); // likelihood is difference of norm. coefs.
[115]195
[477]196                cout << "i=(" << i << ") ll=" << tmpll << endl;
[170]197
[97]198                //
199                if ( tmpll > Egll ) { //increase of the likelihood
[896]200                        tmpindices = indices;
201                        tmpindices.del ( i );
[97]202                        //search for a better match in this substructure
[896]203                        belll = egiw_bestbelow ( Eg, Eg0, tmpll, tmpindices );
[477]204                        if ( belll > maxll ) { //better match found
[97]205                                maxll = belll;
[896]206                                maxindices = tmpindices;
[97]207                        }
208                }
209        }
[896]210        indices = maxindices;
[97]211        return maxll;
212}
213
[1003]214ivec ARX::structure_est ( const egiw &est0 ) {
[477]215        ivec ind = linspace ( 1, est.dimension() - 1 );
216        egiw_bestbelow ( est, est0, est.lognc() - est0.lognc(), ind );
[97]217        return ind;
218}
[254]219
[577]220
221
[1003]222ivec ARX::structure_est_LT ( const egiw &est0 ) {
[577]223        //some stuff with beliefs etc.
[996]224        ivec belief = vec_1 ( 2 );        // default belief
225        int nbest = 1;           // nbest: how many regressors are returned
226        int nrep = 5;         // nrep: number of random repetions of structure estimation
227        double lambda   = 0.9;
228        int k = 2;
229       
230        Array<str_aux> o2;
231       
232        ivec ind = bdm::straux1(est._V(),est._nu(), est0._V(), est0._nu(), belief, nbest, nrep, lambda, k, o2);
233       
234        return ind;
[577]235}
236
[477]237void ARX::from_setting ( const Setting &set ) {
[802]238        BMEF::from_setting(set);
[883]239       
[979]240        UI::get (rgr, set, "rgr", UI::compulsory );
[964]241       
242        dimy = yrv._dsize();
243        bdm_assert(dimy>0,"ARX::yrv should not be empty");
[979]244        rgrlen = rgr._dsize();
[737]245
[631]246        int constant;
[737]247        if ( !UI::get ( constant, set, "constant", UI::optional ) ) {
248                have_constant = true;
[631]249        } else {
[737]250                have_constant = constant > 0;
[625]251        }
[964]252        dimc = rgrlen;
[979]253        rvc = rgr;
[585]254
[357]255        //init
[737]256        shared_ptr<egiw> pri = UI::build<egiw> ( set, "prior", UI::optional );
[1003]257        if (pri){
[990]258                set_prior(pri.get());
[1003]259        } else {
260                shared_ptr<egiw> post = UI::build<egiw> ( set, "posterior", UI::optional );
261                set_prior(post.get());
262        }
263               
[990]264       
[737]265        shared_ptr<egiw> alt = UI::build<egiw> ( set, "alternative", UI::optional );
266        if ( alt ) {
267                bdm_assert ( alt->_dimx() == dimy, "alternative is not compatible" );
[990]268                bdm_assert ( alt->_V().rows() == dimy + rgrlen + int(have_constant==true), "alternative is not compatible" );
[737]269                alter_est.set_parameters ( alt->_dimx(), alt->_V(), alt->_nu() );
[878]270                alter_est.validate();
[973]271        } 
[796]272        // frg handled by BMEF
[357]273
[270]274}
[850]275
[973]276void ARX::set_prior(const epdf *pri){
277        const egiw * eg=dynamic_cast<const egiw*>(pri);
278        if ( eg ) {
279                bdm_assert ( eg->_dimx() == dimy, "prior is not compatible" );
[990]280                bdm_assert ( eg->_V().rows() == dimy + rgrlen + int(have_constant==true), "prior is not compatible" );
[973]281                est.set_parameters ( eg->_dimx(), eg->_V(), eg->_nu() );
282                est.validate();
283        } else {
[990]284                est.set_parameters ( dimy, zeros ( dimy + rgrlen +int(have_constant==true)) );
[973]285                set_prior_default ( est );
286        }
287        //check alternative
288        if (alter_est.dimension()!=dimension()){
289                alter_est = est;
290        }
[679]291}
[973]292}
Note: See TracBrowser for help on using the browser.