|  | 51 | }; | 
                          |  | 52 |  | 
                          |  | 53 | void egiwmix::set_parameters ( const vec &w0, const Array<egiw*> &Coms0, bool copy ) { | 
                          |  | 54 | w = w0/sum ( w0 ); | 
                          |  | 55 | dim = Coms0(0)->dimension(); | 
                          |  | 56 | int i; | 
                          |  | 57 | for ( i=0;i<w.length();i++ ) { | 
                          |  | 58 | it_assert_debug ( dim== ( Coms0 ( i )->dimension() ),"Component sizes do not match!" ); | 
                          |  | 59 | } | 
                          |  | 60 | if ( copy ) { | 
                          |  | 61 | Coms.set_length(Coms0.length()); | 
                          |  | 62 | for ( i=0;i<w.length();i++ ) {it_error("Not imp..."); | 
                          |  | 63 | *Coms ( i ) =*Coms0 ( i );} | 
                          |  | 64 | destroyComs=true; | 
                          |  | 65 | } | 
                          |  | 66 | else { | 
                          |  | 67 | Coms = Coms0; | 
                          |  | 68 | destroyComs=false; | 
                          |  | 69 | } | 
                          |  | 70 | } | 
                          |  | 71 |  | 
                          |  | 72 | vec egiwmix::sample() const { | 
                          |  | 73 | //Sample which component | 
                          |  | 74 | vec cumDist = cumsum ( w ); | 
                          |  | 75 | double u0; | 
                          |  | 76 | #pragma omp critical | 
                          |  | 77 | u0 = UniRNG.sample(); | 
                          |  | 78 |  | 
                          |  | 79 | int i=0; | 
                          |  | 80 | while ( ( cumDist ( i ) <u0 ) && ( i< ( w.length()-1 ) ) ) {i++;} | 
                          |  | 81 |  | 
                          |  | 82 | return Coms ( i )->sample(); | 
                          |  | 83 | } | 
                          |  | 84 |  | 
                          |  | 85 | vec egiwmix::mean() const { | 
                          |  | 86 | int i; vec mu = zeros ( dim ); | 
                          |  | 87 | for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); } | 
                          |  | 88 | return mu; | 
                          |  | 89 | } | 
                          |  | 90 |  | 
                          |  | 91 | vec egiwmix::variance() const { | 
                          |  | 92 | // non-central moment | 
                          |  | 93 | vec mom2 = zeros ( dim ); | 
                          |  | 94 | for ( int i = 0;i < w.length();i++ ) { | 
                          |  | 95 | // pow is overloaded, we have to use another approach | 
                          |  | 96 | mom2 += w ( i ) * (Coms(i)->variance() + elem_mult ( Coms(i)->mean(), Coms(i)->mean() )); | 
                          |  | 97 | } | 
                          |  | 98 | // central moment | 
                          |  | 99 | // pow is overloaded, we have to use another approach | 
                          |  | 100 | return mom2 - elem_mult( mean(), mean() ); | 
                          |  | 101 | } | 
                          |  | 102 |  | 
                          |  | 103 | emix* egiwmix::marginal(const RV &rv) const{ | 
                          |  | 104 | it_assert_debug(isnamed(), "rvs are not assigned"); | 
                          |  | 105 |  | 
                          |  | 106 | Array<epdf*> Cn(Coms.length()); | 
                          |  | 107 | for(int i=0;i<Coms.length();i++){Cn(i)=Coms(i)->marginal(rv);} | 
                          |  | 108 | emix* tmp = new emix(); | 
                          |  | 109 | tmp->set_parameters(w,Cn,false); | 
                          |  | 110 | tmp->ownComs(); | 
                          |  | 111 | return tmp; | 
                          |  | 112 | } | 
                          |  | 113 |  | 
                          |  | 114 | egiw*   egiwmix::approx() { | 
                          |  | 115 | // NB: dimx == 1 !!! | 
                          |  | 116 | // The following code might look a bit spaghetti-like, | 
                          |  | 117 | // consult Dedecius, K. et al.: Partial forgetting in AR models. | 
                          |  | 118 |  | 
                          |  | 119 | double sumVecCommon;                            // common part for many terms in eq. | 
                          |  | 120 | int len = w.length();                           // no. of mix components | 
                          |  | 121 | int dimLS = Coms(1)->_V()._D().length() - 1;    // dim of LS | 
                          |  | 122 | vec vecNu(len);                                 // vector of dfms of components | 
                          |  | 123 | vec vecD(len);                                  // vector of LS reminders of comps. | 
                          |  | 124 | vec vecCommon(len);                             // vector of common parts | 
                          |  | 125 | mat matVecsTheta;                               // matrix which rows are theta vects. | 
                          |  | 126 |  | 
                          |  | 127 | // fill in the vectors vecNu, vecD and matVecsTheta | 
                          |  | 128 | for ( int i=0; i<len; i++ ) { | 
                          |  | 129 | vecNu.shift_left( Coms(i)->_nu() ); | 
                          |  | 130 | vecD.shift_left( Coms(i)->_V()._D()(0) ); | 
                          |  | 131 | matVecsTheta.append_row( Coms(i)->est_theta()  ); | 
                          |  | 132 | } | 
                          |  | 133 |  | 
                          |  | 134 | // calculate the common parts and their sum | 
                          |  | 135 | vecCommon = elem_mult ( w, elem_div(vecNu, vecD) ); | 
                          |  | 136 | sumVecCommon = sum(vecCommon); | 
                          |  | 137 |  | 
                          |  | 138 | // LS estimator of theta | 
                          |  | 139 | vec aprEstTheta(dimLS);  aprEstTheta.zeros(); | 
                          |  | 140 | for ( int i=0; i<len; i++ ) { | 
                          |  | 141 | aprEstTheta +=  matVecsTheta.get_row( i ) * vecCommon ( i ); | 
                          |  | 142 | } | 
                          |  | 143 | aprEstTheta /= sumVecCommon; | 
                          |  | 144 |  | 
                          |  | 145 |  | 
                          |  | 146 | // LS estimator of dfm | 
                          |  | 147 | double aprNu; | 
                          |  | 148 | double A = log( sumVecCommon );         // Term 'A' in equation | 
                          |  | 149 |  | 
                          |  | 150 | for ( int i=0; i<len; i++ ) { | 
                          |  | 151 | A += w(i) * ( log( vecD(i) ) - psi( 0.5 * vecNu(i) ) ); | 
                          |  | 152 | } | 
                          |  | 153 |  | 
                          |  | 154 | aprNu = ( 1 + sqrt(1 + 2 * (A - LOG2)/3 ) ) / ( 2 * (A - LOG2) ); | 
                          |  | 155 |  | 
                          |  | 156 |  | 
                          |  | 157 | // LS reminder (term D(0,0) in C-syntax) | 
                          |  | 158 | double aprD = aprNu / sumVecCommon; | 
                          |  | 159 |  | 
                          |  | 160 | // Aproximation of cov | 
                          |  | 161 | // the following code is very numerically sensitive, thus | 
                          |  | 162 | // we have to eliminate decompositions etc. as much as possible | 
                          |  | 163 | mat aprC = zeros(dimLS, dimLS); | 
                          |  | 164 | for ( int i=0; i<len; i++ ) { | 
                          |  | 165 | aprC += Coms(i)->est_theta_cov().to_mat() * w(i); | 
                          |  | 166 | vec tmp = ( matVecsTheta.get_row(i) - aprEstTheta ); | 
                          |  | 167 | aprC += vecCommon(i) * outer_product( tmp, tmp); | 
                          |  | 168 | } | 
                          |  | 169 |  | 
                          |  | 170 | // Construct GiW pdf :: BEGIN | 
                          |  | 171 | ldmat aprCinv ( inv(aprC) ); | 
                          |  | 172 | vec D = concat( aprD, aprCinv._D() ); | 
                          |  | 173 | mat L = eye(len+1); | 
                          |  | 174 | L.set_submatrix(1,0, aprCinv._L() * aprEstTheta); | 
                          |  | 175 | L.set_submatrix(1,1, aprCinv._L()); | 
                          |  | 176 | ldmat aprLD (L, D); | 
                          |  | 177 |  | 
                          |  | 178 | egiw* aprgiw = new egiw(1, aprLD, aprNu); | 
                          |  | 179 | return aprgiw; |