| | 103 | }; |
| | 104 | |
| | 105 | class emix; //forward |
| | 106 | |
| | 107 | /*! Base class (Interface) for mixtures |
| | 108 | */ |
| | 109 | class emix_base : public epdf { |
| | 110 | protected: |
| | 111 | //! reference to vector of weights |
| | 112 | vec &w; |
| | 113 | //! function returning ith component |
| | 114 | virtual const epdf * component(const int &i) const=0; |
| | 115 | |
| | 116 | virtual int no_coms() const=0; |
| | 117 | |
| | 118 | public: |
| | 119 | |
| | 120 | emix_base(vec &w0): w(w0){} |
| | 121 | |
| | 122 | void validate (); |
| | 123 | |
| | 124 | vec sample() const; |
| | 125 | |
| | 126 | vec mean() const; |
| | 127 | |
| | 128 | vec variance() const; |
| | 129 | |
| | 130 | double evallog ( const vec &val ) const; |
| | 131 | |
| | 132 | vec evallog_mat ( const mat &Val ) const; |
| | 133 | |
| | 134 | //! Auxiliary function that returns pdflog for each component |
| | 135 | mat evallog_coms ( const mat &Val ) const; |
| | 136 | |
| | 137 | shared_ptr<epdf> marginal ( const RV &rv ) const; |
| | 138 | //! Update already existing marginal density \c target |
| | 139 | void marginal ( const RV &rv, emix &target ) const; |
| | 140 | shared_ptr<pdf> condition ( const RV &rv ) const; |
| | 141 | |
| | 142 | //Access methods |
| | 143 | //! returns a reference to the internal weights. Use with Care! |
| | 144 | vec& _w() { |
| | 145 | return w; |
| | 146 | } |
| | 147 | |
| | 148 | const vec& _w() const { |
| | 149 | return w; |
| | 150 | } |
| | 151 | //!access |
| | 152 | const epdf* _com(int i) const {return component(i);} |
| | 153 | |
| 127 | | emix ( ) : epdf ( ) { } |
| 128 | | |
| 129 | | virtual void validate (); |
| 130 | | |
| 131 | | vec sample() const; |
| 132 | | |
| 133 | | vec mean() const; |
| 134 | | |
| 135 | | vec variance() const; |
| 136 | | |
| 137 | | double evallog ( const vec &val ) const; |
| 138 | | |
| 139 | | vec evallog_mat ( const mat &Val ) const; |
| 140 | | |
| 141 | | //! Auxiliary function that returns pdflog for each component |
| 142 | | mat evallog_coms ( const mat &Val ) const; |
| 143 | | |
| 144 | | shared_ptr<epdf> marginal ( const RV &rv ) const; |
| 145 | | //! Update already existing marginal density \c target |
| 146 | | void marginal ( const RV &rv, emix &target ) const; |
| 147 | | shared_ptr<pdf> condition ( const RV &rv ) const; |
| 148 | | |
| 149 | | //Access methods |
| 150 | | //! returns a reference to the internal weights. Use with Care! |
| 151 | | vec& _w() { |
| 152 | | return w; |
| 153 | | } |
| 154 | | |
| 155 | | /*! |
| 156 | | \brief returns a reference to the internal array of components. Use with Care! Set components \c Coms |
| 157 | | |
| 158 | | Shared pointers in Coms are kept inside this instance and |
| 159 | | shouldn't be modified after being passed to this method. |
| 160 | | */ |
| 161 | | Array<shared_ptr<epdf> >& _Coms ( ) { |
| 162 | | return Coms; |
| 163 | | } |
| 164 | | |
| 165 | | //! returns a reference to the internal components specified by index i. Use with Care! |
| 166 | | shared_ptr<epdf> _Coms ( int i ) { |
| 167 | | return Coms ( i ); |
| 168 | | } |
| 169 | | |
| 170 | | void set_rv ( const RV &rv ) { |
| 171 | | epdf::set_rv ( rv ); |
| 172 | | for ( int i = 0; i < Coms.length(); i++ ) { |
| 173 | | Coms ( i )->set_rv ( rv ); |
| 174 | | } |
| 175 | | } |
| | 176 | emix ( ) : emix_base ( weights) { } |
| | 177 | |
| | 178 | const epdf* component(const int &i) const {return Coms(i).get();} |
| | 179 | void validate(); |
| | 180 | |
| | 181 | |
| | 182 | int no_coms() const {return Coms.length(); } |
| 190 | | /*! |
| 191 | | * \brief Mixture of egiws |
| 192 | | |
| 193 | | */ |
| 194 | | class egiwmix : public egiw { |
| 195 | | protected: |
| 196 | | //! weights of the components |
| 197 | | vec w; |
| 198 | | //! Component (epdfs) |
| 199 | | Array<egiw*> Coms; |
| 200 | | //!Flag if owning Coms |
| 201 | | bool destroyComs; |
| 202 | | public: |
| 203 | | //!Default constructor |
| 204 | | egiwmix ( ) : egiw ( ) {}; |
| 205 | | |
| 206 | | //! Set weights \c w and components \c Coms |
| 207 | | //!By default Coms are copied inside. Parameter \c copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor. |
| 208 | | void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy = false ); |
| 209 | | |
| 210 | | //!return expected value |
| 211 | | void validate(); |
| 212 | | |
| 213 | | vec mean() const; |
| 214 | | |
| 215 | | //!return a sample from the density |
| 216 | | vec sample() const; |
| 217 | | |
| 218 | | //!return the expected variance |
| 219 | | vec variance() const; |
| 220 | | |
| 221 | | // TODO!!! Defined to follow ANSI and/or for future development |
| 222 | | void mean_mat ( mat &M, mat&R ) const {}; |
| 223 | | double evallog_nn ( const vec &val ) const { |
| 224 | | return 0; |
| 225 | | }; |
| 226 | | double lognc () const { |
| 227 | | return 0; |
| 228 | | } |
| 229 | | |
| 230 | | shared_ptr<epdf> marginal ( const RV &rv ) const; |
| 231 | | //! marginal density update |
| 232 | | void marginal ( const RV &rv, emix &target ) const; |
| 233 | | |
| 234 | | //Access methods |
| 235 | | //! returns a pointer to the internal mean value. Use with Care! |
| 236 | | vec& _w() { |
| 237 | | return w; |
| 238 | | } |
| 239 | | virtual ~egiwmix() { |
| 240 | | if ( destroyComs ) { |
| 241 | | for ( int i = 0; i < Coms.length(); i++ ) { |
| 242 | | delete Coms ( i ); |
| 243 | | } |
| 244 | | } |
| 245 | | } |
| 246 | | //! Auxiliary function for taking ownership of the Coms() |
| 247 | | void ownComs() { |
| 248 | | destroyComs = true; |
| 249 | | } |
| 250 | | |
| 251 | | //!access function |
| 252 | | egiw* _Coms ( int i ) { |
| 253 | | return Coms ( i ); |
| 254 | | } |
| 255 | | |
| 256 | | void set_rv ( const RV &rv ) { |
| 257 | | egiw::set_rv ( rv ); |
| 258 | | for ( int i = 0; i < Coms.length(); i++ ) { |
| 259 | | Coms ( i )->set_rv ( rv ); |
| 260 | | } |
| 261 | | } |
| 262 | | |
| 263 | | //! Approximation of a GiW mix by a single GiW pdf |
| 264 | | egiw* approx(); |
| 265 | | }; |
| 346 | | if ( named ) { |
| 347 | | for ( int i = 0; i < epdfs.length(); i++ ) { |
| 348 | | independent = rv.add ( epdfs ( i )->_rv() ); |
| 349 | | bdm_assert_debug ( independent, "eprod:: given components are not independent." ); |
| 350 | | } |
| 351 | | dim = rv._dsize(); |
| 352 | | |
| 353 | | } else { |
| 354 | | dim = 0; |
| 355 | | for ( int i = 0; i < epdfs.length(); i++ ) { |
| 356 | | dim += epdfs ( i )->dimension(); |
| 357 | | } |
| 358 | | } |
| | 305 | dim = 0; |
| | 306 | for ( int i = 0; i < no_factors(); i++ ) { |
| | 307 | independent = rv.add ( factor ( i )->_rv() ); |
| | 308 | dim += factor ( i )->dimension(); |
| | 309 | bdm_assert_debug ( independent, "eprod:: given components are not independent." ); |
| | 310 | }; |
| | 311 | |
| 375 | | |
| 376 | | |
| 377 | | vec mean() const; |
| 378 | | |
| 379 | | vec variance() const; |
| 380 | | |
| 381 | | vec sample() const; |
| 382 | | |
| 383 | | double evallog ( const vec &val ) const; |
| 384 | | |
| 385 | | //!access function |
| 386 | | const epdf* operator () ( int i ) const { |
| 387 | | bdm_assert_debug ( i < epdfs.length(), "wrong index" ); |
| 388 | | return epdfs ( i ); |
| 389 | | } |
| 390 | | |
| 391 | | //!Destructor |
| 392 | | ~eprod() { |
| 393 | | for ( int i = 0; i < epdfs.length(); i++ ) { |
| 394 | | delete dls ( i ); |
| 395 | | } |
| 396 | | } |
| 397 | | }; |
| 398 | | |
| | 328 | }; |
| | 329 | |
| | 330 | class eprod: public eprod_base{ |
| | 331 | protected: |
| | 332 | Array<shared_ptr<epdf> > factors; |
| | 333 | public: |
| | 334 | const epdf* factor(int i) const {return factors(i).get();} |
| | 335 | const int no_factors() const {return factors.length();} |
| | 336 | void set_parameters ( const Array<shared_ptr<epdf> > &epdfs0) { |
| | 337 | factors = epdfs0; |
| | 338 | } |
| | 339 | }; |
| | 340 | |
| | 341 | //! similar to eprod but used only internally -- factors are external pointers |
| | 342 | class eprod_internal: public eprod_base{ |
| | 343 | protected: |
| | 344 | Array<epdf* > factors; |
| | 345 | const epdf* factor(int i) const {return factors(i);} |
| | 346 | const int no_factors() const {return factors.length();} |
| | 347 | public: |
| | 348 | void set_parameters ( const Array<epdf *> &epdfs0) { |
| | 349 | factors = epdfs0; |
| | 350 | } |
| | 351 | }; |