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

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

samplepred for ARX

  • Property svn:eol-style set to native
Line 
1#include "arx.h"
2namespace bdm {
3
4void ARX::bayes_weighted ( const vec &yt, const vec &cond, const double w ) {
5    bdm_assert_debug ( yt.length() == dimy, "BM::bayes yt is of size "+num2str(yt.length())+" expected dimension is "+num2str(dimy) );
6    bdm_assert_debug ( cond.length() == rgrlen , "BM::bayes cond is of size "+num2str(cond.length())+" expected dimension is "+num2str(rgrlen) );
7
8    BMEF::bayes_weighted(yt,cond,w); //potential discount scheduling
9    double lnc;
10    //cache
11    ldmat &V = est._V();
12    double &nu = est._nu();
13
14    dyad.set_subvector ( 0, yt );
15    if (cond.length()>0)
16        dyad.set_subvector ( dimy, cond );
17    // possible "1" is there from the beginning
18
19    if ( frg < 1.0 ) {
20        est.pow ( frg ); // multiply V and nu
21
22
23        //stabilize
24        ldmat V0 = alter_est._V(); //$ copy
25        double &nu0 = alter_est._nu();
26
27        V0 *= ( 1 - frg );
28        V += V0; //stabilization
29        nu += ( 1 - frg ) * nu0;
30
31        // recompute loglikelihood of new "prior"
32        if ( evalll ) {
33            last_lognc = est.lognc();
34        }
35    }
36    V.opupdt ( dyad, w );
37    nu += w;
38
39    // log(sqrt(2*pi)) = 0.91893853320467
40    if ( evalll ) {
41        lnc = est.lognc();
42        ll = lnc - last_lognc - 0.91893853320467;
43        last_lognc = lnc;
44    }
45}
46
47double ARX::logpred ( const vec &yt, const vec &cond ) const {
48    egiw pred ( est );
49    ldmat &V = pred._V();
50    double &nu = pred._nu();
51
52    double lll;
53    vec dyad_p = dyad;
54    dyad_p.set_subvector ( 0, yt );
55    dyad_p.set_subvector(dimy,cond);
56
57    if ( frg < 1.0 ) {
58        pred.pow ( frg );
59        lll = pred.lognc();
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        }
66
67    V.opupdt ( dyad_p, 1.0 );
68    nu += 1.0;
69    // log(sqrt(2*pi)) = 0.91893853320467
70    return pred.lognc() - lll - 0.91893853320467;
71}
72
73vec ARX::samplepred(const vec &cond) const{
74        mat M;
75        chmat R;
76        est.sample_mat(M,R);
77       
78        vec tmp;
79        if (dimc>0){
80                if (have_constant){
81                        tmp = M*concat(cond,1.0);
82                } else {
83                        tmp = M*cond;
84                }
85        } else {
86                tmp = zeros(dimy);
87        }
88        tmp += R._Ch().T()*randn(dimy);
89        return tmp;
90}
91
92void ARX::flatten ( const BMEF* B , double weight =1.0) {
93    const ARX* A = dynamic_cast<const ARX*> ( B );
94    // nu should be equal to B.nu
95    est.pow ( A->posterior()._nu() / posterior()._nu() *weight);
96    if ( evalll ) {
97        last_lognc = est.lognc();
98    }
99}
100
101ARX* ARX::_copy ( ) const {
102    ARX* Tmp = new ARX ( *this );
103    return Tmp;
104}
105
106void ARX::set_statistics ( const BMEF* B0 ) {
107    const ARX* A0 = dynamic_cast<const ARX*> ( B0 );
108
109    bdm_assert_debug ( dimension() == A0->dimension(), "Statistics of different dimensions" );
110    set_statistics ( A0->dimensiony(), A0->posterior()._V(), A0->posterior()._nu() );
111}
112
113enorm<ldmat>* ARX::epredictor ( const vec &cond ) const {
114    bdm_assert_debug ( cond.length() == rgrlen , "ARX::epredictor cond is of size "+num2str(cond.length())+" expected dimension is "+num2str(rgrlen) );
115
116    mat mu ( dimy, posterior()._V().rows() - dimy );
117    mat R ( dimy, dimy );
118
119    vec ext_rgr;
120    if (have_constant) {
121        ext_rgr = concat(cond,vec_1(1.0));
122    } else {
123        ext_rgr = cond;
124    }
125
126    enorm<ldmat>* tmp;
127    tmp = new enorm<ldmat> ( );
128    //TODO: too hackish
129    if ( yrv._dsize() > 0 ) {
130    }
131
132    est.mean_mat ( mu, R ); //mu =
133    //correction for student-t  -- TODO check if correct!!
134    R*=posterior()._nu()/(posterior()._nu()-2);
135    if (mu.cols()>0) {// nonempty egiw
136        mat p_mu = mu.T() * ext_rgr;    //the result is one column
137        tmp->set_parameters ( p_mu.get_col ( 0 ), ldmat ( R ) );
138    } else {
139        tmp->set_parameters ( zeros( R.rows() ), ldmat ( R ) );
140    }
141    if (dimy==yrv._dsize())
142        tmp->set_rv(yrv);
143    return tmp;
144}
145
146mlstudent* ARX::predictor_student ( ) const {
147    const ldmat &V = posterior()._V();
148
149    mat mu ( dimy, V.rows() - dimy );
150    mat R ( dimy, dimy );
151    mlstudent* tmp;
152    tmp = new mlstudent ( );
153
154    est.mean_mat ( mu, R ); //
155    mu = mu.T();
156
157    int end = V._L().rows() - 1;
158    ldmat Lam ( V._L() ( dimy, end, dimy, end ), V._D() ( dimy, end ) );  //exp val of R
159
160
161    if ( have_constant ) { // no constant term
162        //Assume the constant term is the last one:
163        if ( mu.cols() > 1 ) {
164            tmp->set_parameters ( mu.get_cols ( 0, mu.cols() - 2 ), mu.get_col ( mu.cols() - 1 ), ldmat ( R ), Lam );
165        } else {
166            tmp->set_parameters ( mat ( dimy, dimc ), mu.get_col ( mu.cols() - 1 ), ldmat ( R ), Lam );
167        }
168    } else {
169        // no constant term
170        tmp->set_parameters ( mu, zeros ( dimy ), ldmat ( R ), Lam );
171    }
172    return tmp;
173}
174
175
176
177/*! \brief Return the best structure
178@param Eg a copy of GiW density that is being examined
179@param Eg0 a copy of prior GiW density before estimation
180@param Egll likelihood of the current Eg
181@param indices current indices
182\return best likelihood in the structure below the given one
183*/
184double egiw_bestbelow ( egiw Eg, egiw Eg0, double Egll, ivec &indices ) { //parameter Eg is a copy!
185    ldmat Vo = Eg._V(); //copy
186    ldmat Vo0 = Eg._V(); //copy
187    ldmat& Vp = Eg._V(); // pointer into Eg
188    ldmat& Vp0 = Eg._V(); // pointer into Eg
189    int end = Vp.rows() - 1;
190    int i;
191    mat Li;
192    mat Li0;
193    double maxll = Egll;
194    double tmpll = Egll;
195    double belll = Egll;
196
197    ivec tmpindices;
198    ivec maxindices = indices;
199
200
201    cout << "bb:(" << indices << ") ll=" << Egll << endl;
202
203    //try to remove only one rv
204    for ( i = 0; i < end; i++ ) {
205        //copy original
206        Li = Vo._L();
207        Li0 = Vo0._L();
208        //remove stuff
209        Li.del_col ( i + 1 );
210        Li0.del_col ( i + 1 );
211        Vp.ldform ( Li, Vo._D() );
212        Vp0.ldform ( Li0, Vo0._D() );
213        tmpll = Eg.lognc() - Eg0.lognc(); // likelihood is difference of norm. coefs.
214
215        cout << "i=(" << i << ") ll=" << tmpll << endl;
216
217        //
218        if ( tmpll > Egll ) { //increase of the likelihood
219            tmpindices = indices;
220            tmpindices.del ( i );
221            //search for a better match in this substructure
222            belll = egiw_bestbelow ( Eg, Eg0, tmpll, tmpindices );
223            if ( belll > maxll ) { //better match found
224                maxll = belll;
225                maxindices = tmpindices;
226            }
227        }
228    }
229    indices = maxindices;
230    return maxll;
231}
232
233ivec ARX::structure_est ( const egiw &est0 ) {
234    ivec ind = linspace ( 1, est.dimension() - 1 );
235    egiw_bestbelow ( est, est0, est.lognc() - est0.lognc(), ind );
236    return ind;
237}
238
239
240
241ivec ARX::structure_est_LT ( const egiw &est0 ) {
242    //some stuff with beliefs etc.
243    ivec belief = vec_1 ( 2 );        // default belief
244    int nbest = 1;           // nbest: how many regressors are returned
245    int nrep = 5;         // nrep: number of random repetions of structure estimation
246    double lambda   = 0.9;
247    int k = 2;
248
249    Array<str_aux> o2;
250
251    ivec ind = bdm::straux1(est._V(),est._nu(), est0._V(), est0._nu(), belief, nbest, nrep, lambda, k, o2);
252
253    return ind;
254}
255
256void ARX::from_setting ( const Setting &set ) {
257    BMEF::from_setting(set);
258
259    UI::get (rgr, set, "rgr", UI::compulsory );
260
261    dimy = yrv._dsize();
262    bdm_assert(dimy>0,"ARX::yrv should not be empty");
263    rgrlen = rgr._dsize();
264
265    int constant;
266    if ( !UI::get ( constant, set, "constant", UI::optional ) ) {
267        have_constant = true;
268    } else {
269        have_constant = constant > 0;
270    }
271    dimc = rgrlen;
272    rvc = rgr;
273
274    //init
275    shared_ptr<egiw> pri = UI::build<egiw> ( set, "prior", UI::optional );
276    if (pri) {
277        set_prior(pri.get());
278    } else {
279        shared_ptr<egiw> post = UI::build<egiw> ( set, "posterior", UI::optional );
280        set_prior(post.get());
281    }
282
283
284    shared_ptr<egiw> alt = UI::build<egiw> ( set, "alternative", UI::optional );
285    if ( alt ) {
286        bdm_assert ( alt->_dimx() == dimy, "alternative is not compatible" );
287        bdm_assert ( alt->_V().rows() == dimy + rgrlen + int(have_constant==true), "alternative is not compatible" );
288        alter_est.set_parameters ( alt->_dimx(), alt->_V(), alt->_nu() );
289        alter_est.validate();
290    }
291    // frg handled by BMEF
292
293}
294
295void ARX::set_prior(const epdf *pri) {
296    const egiw * eg=dynamic_cast<const egiw*>(pri);
297    if ( eg ) {
298        bdm_assert ( eg->_dimx() == dimy, "prior is not compatible" );
299        bdm_assert ( eg->_V().rows() == dimy + rgrlen + int(have_constant==true), "prior is not compatible" );
300        est.set_parameters ( eg->_dimx(), eg->_V(), eg->_nu() );
301        est.validate();
302    } else {
303        est.set_parameters ( dimy, zeros ( dimy + rgrlen +int(have_constant==true)) );
304        set_prior_default ( est );
305    }
306    //check alternative
307    if (alter_est.dimension()!=dimension()) {
308        alter_est = est;
309    }
310}
311
312void ARXpartialforg::bayes ( const vec &val, const vec &cond ) {
313#define LOG2  0.69314718055995
314    vec frg = cond.right(cond.length() - rgrlen);
315    vec cond_rgr = cond.left(rgrlen);       // regression vector
316
317    int dimV = est._V().cols();
318    int nparams = dimV - 1;                 // number of parameters
319    int nalternatives = 1 << nparams;    // number of alternatives
320
321    // Permutation matrix
322    mat perm_matrix = ones(nalternatives, nparams);
323    int i, j, period, idx_from, idx_to, start, end;
324    for(i = 0; i < nparams; i++) {
325        idx_from = 1 << i;
326        period   = ( idx_from << 1 );
327        idx_to   = period - 1;
328        j = 0;
329        start = idx_from;
330        end = idx_to;
331        while ( start < nalternatives ) {
332            perm_matrix.set_submatrix(start, end, i, i, 0);
333            j++;
334            start = idx_from + period * j;
335            end = idx_to + period * j;
336        }
337    }
338
339    // Array of egiws for approximation
340    Array<egiw*> egiw_array(nalternatives + 1);
341    // No. of conditioning rows in LD
342    int nalternatives_cond, position;
343
344    for(int i = 0; i < nalternatives; i++) {
345        // vector defining alternatives
346        vec vec_alt = perm_matrix.get_row(i);
347
348        // full alternative or filtered
349        if( sum(vec_alt) == vec_alt.length() )  {
350            egiw_array(i) = &alter_est;
351            continue;
352        } else if( sum(vec_alt) == 0 ) {
353            egiw_array(i) = &est;
354            continue;
355        }
356
357        nalternatives_cond = (int) sum(vec_alt) + 1;
358        ivec vec_perm(0);                   // permutation vector
359
360        for(int j = 0; j < nparams; j++) {
361            position = dimV - j - 2;
362            if ( vec_alt(position) == 0 ) {
363                vec_perm.ins(j, position + 1);
364            }
365            else {
366                vec_perm.ins(0, position + 1);
367            }
368        }
369        vec_perm.ins(0, 0);
370
371        ldmat filt (est._V(), vec_perm);
372        ldmat alt (alter_est._V(), vec_perm);
373
374        mat tmpL(dimV, dimV);
375        tmpL.set_rows( 0, alt._L().get_rows(0, nalternatives_cond - 1) );
376        tmpL.set_rows( nalternatives_cond, filt._L().get_rows(nalternatives_cond, nparams) );
377
378        vec tmpD(dimV);
379        tmpD.set_subvector( 0, alt._D()(0, nalternatives_cond - 1) );
380        tmpD.set_subvector( nalternatives_cond, filt._D()(nalternatives_cond, nparams) );
381
382        ldmat tmpLD (tmpL, tmpD);
383
384        vec_perm = sort_index(vec_perm);
385        ldmat newLD (tmpLD, vec_perm);
386
387        egiw_array(i) = new egiw(1, newLD, alter_est._nu());
388    }
389
390    // Approximation
391    double sumVecCommon;                // frequently used term
392    vec vecNu(nalternatives);           // vector of nus of components
393    vec vecD(nalternatives);            // vector of LS reminders
394    vec vecCommon(nalternatives);       // vector of common parts
395    mat matVecsTheta;                           // matrix whose rows are theta vects.
396
397    for (i = 0; i < nalternatives; i++) {
398        vecNu.shift_left( egiw_array(i)->_nu() );
399        vecD.shift_left( egiw_array(i)->_V()._D()(0) );
400        matVecsTheta.append_row( egiw_array(i)->est_theta()  );
401    }
402
403    vecCommon = elem_mult ( frg, elem_div(vecNu, vecD) );
404    sumVecCommon = sum(vecCommon);
405
406    // approximation of est. regr. coefficients
407    vec aprEstTheta(nparams);
408    aprEstTheta.zeros();
409    for (i = 0; i < nalternatives; i++) {
410        aprEstTheta +=  matVecsTheta.get_row(i) * vecCommon(i);
411    }
412    aprEstTheta /= sumVecCommon;
413
414    // approximation of degr. of freedom
415    double aprNu;
416    double A = log( sumVecCommon );             // Term 'A' in equation
417    for ( int i = 0; i < nalternatives; i++ ) {
418        A += frg(i) * ( log( vecD(i) ) - psi( 0.5 * vecNu(i) ) );
419    }
420    aprNu = ( 1 + sqrt(1 + 4 * (A - LOG2)/3 ) ) / ( 2 * (A - LOG2) );
421
422    // approximation of LS reminder D(0,0)
423    double aprD = aprNu / sumVecCommon;
424
425    // Aproximation of covariance of LS est.
426    mat aprC = zeros(nparams, nparams);
427    for ( int i = 0; i < nalternatives; i++ ) {
428        aprC += egiw_array(i)->est_theta_cov().to_mat() * frg(i);
429        vec tmp = ( matVecsTheta.get_row(i) - aprEstTheta );
430        aprC += vecCommon(i) * outer_product( tmp, tmp);
431    }
432
433    // Construct GiW pdf
434    ldmat aprCinv ( inv(aprC) );
435    vec D = concat( aprD, aprCinv._D() );
436    mat L = eye(dimV);
437    L.set_submatrix(1, 0, aprCinv._L() * aprEstTheta);
438    L.set_submatrix(1, 1, aprCinv._L());
439    ldmat aprLD (L, D);
440    est = egiw(1, aprLD, aprNu);
441
442    if ( evalll ) {
443        last_lognc = est.lognc();
444    }
445
446    // update
447    ARX::bayes ( val, cond_rgr );
448}
449
450}
Note: See TracBrowser for help on using the browser.