| 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 | }; |