Index: /library/bdm/estim/particles.h
===================================================================
--- /library/bdm/estim/particles.h (revision 964)
+++ /library/bdm/estim/particles.h (revision 971)
@@ -21,5 +21,5 @@
 	
 //! class used in PF
-class MarginalizedParticle : public BM{
+class MarginalizedParticleBase : public BM{
 	protected:
 	//! discrte particle
@@ -27,21 +27,11 @@
 	//! internal Bayes Model
 	shared_ptr<BM> bm; 
-	//! pdf with for transitional par
-	shared_ptr<pdf> par; // pdf for non-linear part
-	//! link from this to bm
-	shared_ptr<datalink_part> cond2bm;
-	//! link from cond to par
-	shared_ptr<datalink_part> cond2par;
-	//! link from emp 2 par
-	shared_ptr<datalink_part> emp2bm;
-	//! link from emp 2 par
-	shared_ptr<datalink_part> emp2par;
-	
-	//! custom posterior - product
+	
+	//! custom posterior - product of empirical and exact part
 	class eprod_2:public eprod_base {
 		protected:
-		MarginalizedParticle &mp;
+		MarginalizedParticleBase &mp;
 		public:
-		eprod_2(MarginalizedParticle &m):mp(m){}
+		eprod_2(MarginalizedParticleBase &m):mp(m){}
 		const epdf* factor(int i) const {return (i==0) ? &mp.bm->posterior() : &mp.est_emp;}
 		const int no_factors() const {return 2;}
@@ -49,26 +39,12 @@
 	
 	public:
-		MarginalizedParticle():est(*this){};
-		MarginalizedParticle(const MarginalizedParticle &m2):est(*this){
+		MarginalizedParticleBase():est(*this){};
+		MarginalizedParticleBase(const MarginalizedParticleBase &m2):est(*this){
 			bm = m2.bm->_copy();
 			est_emp = m2.est_emp;
-			par = m2.par;
 			validate();
 		};
-		BM* _copy() const{return new MarginalizedParticle(*this);};
-		void bayes(const vec &dt, const vec &cond){
-			vec par_cond(par->dimensionc());
-			cond2par->filldown(cond,par_cond); // copy ut
-			emp2par->filldown(est_emp._point(),par_cond); // copy xt-1
-			
-			//sample new particle
-			est_emp.set_point(par->samplecond(par_cond));
-			//if (evalll)
-			vec bm_cond(bm->dimensionc());
-			cond2bm->filldown(cond, bm_cond);// set e.g. ut
-			emp2bm->filldown(est_emp._point(), bm_cond);// set e.g. ut
-			bm->bayes(dt, bm_cond);
-			ll=bm->_ll();
-		}
+		void bayes(const vec &dt, const vec &cond) NOT_IMPLEMENTED_VOID;
+		
 		const eprod_2& posterior() const {return est;}
 	
@@ -84,22 +60,60 @@
 			}
 		}
-
+		void from_setting(const Setting &set){
+			BM::from_setting ( set ); 
+			bm = UI::build<BM> ( set, "bm", UI::compulsory );
+		}
+		void validate() {
+			BM::validate();
+			bdm_assert(bm,"Internal BM is not given");
+		}
+};
+
+class MarginalizedParticle : public MarginalizedParticleBase{
+	protected:
+		//! pdf with for transitional par
+		shared_ptr<pdf> par; // pdf for non-linear part
+		//! link from this to bm
+		shared_ptr<datalink_part> cond2bm;
+		//! link from cond to par
+		shared_ptr<datalink_part> cond2par;
+		//! link from emp 2 par
+		shared_ptr<datalink_part> emp2bm;
+		//! link from emp 2 par
+		shared_ptr<datalink_part> emp2par;
+		
+	public:
+		BM* _copy() const{return new MarginalizedParticle(*this);};
+		void bayes(const vec &dt, const vec &cond){
+			vec par_cond(par->dimensionc());
+			cond2par->filldown(cond,par_cond); // copy ut
+			emp2par->filldown(est_emp._point(),par_cond); // copy xt-1
+			
+			//sample new particle
+			est_emp.set_point(par->samplecond(par_cond));
+			//if (evalll)
+			vec bm_cond(bm->dimensionc());
+			cond2bm->filldown(cond, bm_cond);// set e.g. ut
+			emp2bm->filldown(est_emp._point(), bm_cond);// set e.g. ut
+			bm->bayes(dt, bm_cond);
+			ll=bm->_ll();
+		}
+				
 		/*! parse structure
 		\code
-		class = "BootstrapParticle";
+		class = "MarginalizedParticle";
 		parameter_pdf = {class = 'epdf_offspring', ...};
-		observation_pdf = {class = 'epdf_offspring',...};
+		bm = {class = 'bm_offspring',...};
 		\endcode
 		If rvs are set, then it checks for compatibility.
 		*/
 		void from_setting(const Setting &set){
-			BM::from_setting ( set );
+			MarginalizedParticleBase::from_setting ( set );
 			par = UI::build<pdf> ( set, "parameter_pdf", UI::compulsory );
-			bm = UI::build<BM> ( set, "bm", UI::compulsory );
-		}
-		
-		void to_setting(const Setting &set){
-			if (BM::log_level[logfull]){
-			}
+		}
+		
+		void to_setting(Setting &set){
+			MarginalizedParticleBase::to_setting(set);
+			UI::save(par,set,"parameter_pdf");
 		}
 		void validate(){
@@ -112,5 +126,5 @@
 			set_rv( concat(bm->_rv(), par->_rv()));
 			set_dim( par->dimension()+bm->dimension());
-
+			
 			rvc = par->_rvc();
 			rvc.add(bm->_rvc());
@@ -444,207 +458,93 @@
 UIREGISTER ( PF );
 
-/*!
-\brief Marginalized Particle filter
-
-A composition of particle filter with exact (or almost exact) bayesian models (BMs).
-The Bayesian models provide marginalized predictive density. Internaly this is achieved by virtual class MPFpdf.
+/*! Marginalized particle for state-space models with unknown parameters of residues distribution
+
+\f[
+\begin{eqnarray}
+x_t = g(x_{t-1}) + v_t,\\
+z_t = h(x_{t-1}) + w_t,\\
+\end{eqnarray}
+\f]
+
+This particle is a only a shell creating the residues calling internal estimator of their parameters. The internal estimator can be of any compatible type, e.g. ARX for Gaussian residues with unknown mean and variance.
+
 */
-
-// class MPF : public BM  {
-// 	//! Introduces new option 
-// 	//! \li means - meaning TODO
-// 	LOG_LEVEL(MPF,means);
-// protected:
-// 	//! particle filter on non-linear variable
-// 	shared_ptr<PF> pf;
-// 	//! Array of Bayesian models
-// 	Array<BM*> BMs;
-// 
-// 	//! internal class for pdf providing composition of eEmp with external components
-// 
-// 	class mpfepdf : public epdf  {
-// 		//! pointer to particle filter
-// 		shared_ptr<PF> &pf;
-// 		//! pointer to Array of BMs
-// 		Array<BM*> &BMs;
-// 	public:
-// 		//! constructor
-// 		mpfepdf ( shared_ptr<PF> &pf0, Array<BM*> &BMs0 ) : epdf(), pf ( pf0 ), BMs ( BMs0 ) { };
-// 		//! a variant of set parameters - this time, parameters are read from BMs and pf
-// 		void read_parameters() {
-// 			rv = concat ( pf->posterior()._rv(), BMs ( 0 )->posterior()._rv() );
-// 			dim = pf->posterior().dimension() + BMs ( 0 )->posterior().dimension();
-// 			bdm_assert_debug ( dim == rv._dsize(), "Wrong name " );
-// 		}
-// 		vec mean() const;
-// 
-// 		vec variance() const;
-// 
-// 		void qbounds ( vec &lb, vec &ub, double perc = 0.95 ) const;
-// 
-// 		vec sample() const NOT_IMPLEMENTED(0);
-// 
-// 		double evallog ( const vec &val ) const NOT_IMPLEMENTED(0);		
-// 	};
-// 
-// 	//! Density joining PF.est with conditional parts
-// 	mpfepdf jest;
-// 
-// 	//! datalink from global yt and cond (Up) to BMs yt and cond (Down)
-// 	datalink_m2m this2bm;
-// 	//! datalink from global yt and cond (Up) to PFs yt and cond (Down)
-// 	datalink_m2m this2pf;
-// 	//!datalink from PF part to BM
-// 	datalink_part pf2bm;
-// 
-// public:
-// 	//! Default constructor.
-// 	MPF () :  jest ( pf, BMs ) {};
-// 	//! set all parameters at once
-// 	void set_pf ( shared_ptr<pdf> par0, int n0, RESAMPLING_METHOD rm = SYSTEMATIC ) {
-// 		if (!pf) pf=new PF;
-// 		pf->set_model ( par0, par0 ); // <=== nasty!!!
-// 		pf->set_parameters ( n0, rm );
-// 		pf->set_rv(par0->_rv());
-// 		BMs.set_length ( n0 );
-// 	}
-// 	//! set a prototype of BM, copy it to as many times as there is particles in pf
-// 	void set_BM ( const BM &BMcond0 ) {
-// 
-// 		int n = pf->__w().length();
-// 		BMs.set_length ( n );
-// 		// copy
-// 		//BMcond0 .condition ( pf->posterior()._sample ( 0 ) );
-// 		for ( int i = 0; i < n; i++ ) {
-// 			BMs ( i ) = (BM*) BMcond0._copy();
-// 		}
-// 	};
-// 
-// 	void bayes ( const vec &yt, const vec &cond );
-// 
-// 	const epdf& posterior() const {
-// 		return jest;
-// 	}
-// 
-// 	//!Access function
-// 	const BM* _BM ( int i ) {
-// 		return BMs ( i );
-// 	}
-// 	PF& _pf() {return *pf;}
-// 
-// 
-// 	virtual double logpred ( const vec &yt ) const NOT_IMPLEMENTED(0); 
-// 		
-// 	virtual epdf* epredictor() const NOT_IMPLEMENTED(NULL); 
-// 	
-// 	virtual pdf* predictor() const NOT_IMPLEMENTED(NULL); 
-// 
-// 
-// 	/*! configuration structure for basic PF
-// 	\code
-// 	BM              = BM_class;           // Bayesian filtr for analytical part of the model
-// 	parameter_pdf   = pdf_class;         // transitional pdf for non-parametric part of the model
-// 	prior           = epdf_class;         // prior probability density
-// 	--- optional ---
-// 	n               = 10;                 // number of particles
-// 	resmethod       = 'systematic', or 'multinomial', or 'stratified'
-// 										  // resampling method
-// 	\endcode
-// 	*/
-// 	void from_setting ( const Setting &set ) {
-// 		BM::from_setting( set );
-// 
-// 		shared_ptr<pdf> par = UI::build<pdf> ( set, "parameter_pdf", UI::compulsory );
-// 
-// 		pf = new PF;
-// 		// prior must be set before BM
-// 		pf->prior_from_set ( set );
-// 		pf->resmethod_from_set ( set );
-// 		pf->set_model ( par, par ); // too hackish!
-// 
-// 		shared_ptr<BM> BM0 = UI::build<BM> ( set, "BM", UI::compulsory );
-// 		set_BM ( *BM0 );
-// 
-// 		//set drv
-// 		//??set_yrv(concat(BM0->_yrv(),u) );
-// 		set_yrv ( BM0->_yrv() );
-// 		rvc = BM0->_rvc().subt ( par->_rv() );
-// 		//find potential input - what remains in rvc when we subtract rv
-// 		RV u = par->_rvc().subt ( par->_rv().copy_t ( -1 ) );
-// 		rvc.add ( u );
-// 		dimc = rvc._dsize();
-// 		validate();
-// 	}
-// 
-// 	void validate() {
-// 		BM::validate();
-// 		try {
-// 			pf->validate();
-// 		} catch ( std::exception ) {
-// 			throw UIException ( "Error in PF part of MPF:" );
-// 		}
-// 		jest.read_parameters();
-// 		this2bm.set_connection ( BMs ( 0 )->_yrv(), BMs ( 0 )->_rvc(), yrv, rvc );
-// 		this2pf.set_connection ( pf->_yrv(), pf->_rvc(), yrv, rvc );
-// 		pf2bm.set_connection ( BMs ( 0 )->_rvc(), pf->posterior()._rv() );
-// 	}
-// };
-// UIREGISTER ( MPF );
-
-/*! ARXg for estimation of state-space variances
-*/
-// class MPF_ARXg :public BM{
-// 	protected:
-// 	shared_ptr<PF> pf;
-// 	//! pointer to Array of BMs
-// 	Array<ARX*> BMso;
-// 	//! pointer to Array of BMs
-// 	Array<ARX*> BMsp;
-// 	//!parameter evolution
-// 	shared_ptr<fnc> g;
-// 	//!observation function
-// 	shared_ptr<fnc> h;
-// 	
-// 	public:
-// 		void bayes(const vec &yt, const vec &cond );
-// 		void from_setting(const Setting &set) ;
-// 		void validate() {
-// 			bdm_assert(g->dimensionc()==g->dimension(),"not supported yet");
-// 			bdm_assert(h->dimensionc()==g->dimension(),"not supported yet");			
-// 		}
-// 
-// 		double logpred(const vec &cond) const NOT_IMPLEMENTED(0.0);
-// 		epdf* epredictor() const NOT_IMPLEMENTED(NULL);
-// 		pdf* predictor() const NOT_IMPLEMENTED(NULL);
-// 		const epdf& posterior() const {return pf->posterior();};
-// 		
-// 		void log_register( logger &L, const string &prefix ){
-// 			BM::log_register(L,prefix);
-// 			registered_logger->ids.set_size ( 3 );
-// 			registered_logger->ids(1)= L.add_vector(RV("Q",dimension()*dimension()), prefix+L.prefix_sep()+"Q");
-// 			registered_logger->ids(2)= L.add_vector(RV("R",dimensiony()*dimensiony()), prefix+L.prefix_sep()+"R");
-// 			
-// 		};
-// 		void log_write() const {
-// 			BM::log_write();
-// 			mat mQ=zeros(dimension(),dimension());
-// 			mat pom=zeros(dimension(),dimension());
-// 			mat mR=zeros(dimensiony(),dimensiony());
-// 			mat pom2=zeros(dimensiony(),dimensiony());
-// 			mat dum;
-// 			const vec w=pf->posterior()._w();
-// 			for (int i=0; i<w.length(); i++){
-// 				BMsp(i)->posterior().mean_mat(dum,pom);
-// 				mQ += w(i) * pom;
-// 				BMso(i)->posterior().mean_mat(dum,pom2);
-// 				mR += w(i) * pom2;
-// 				
-// 			}
-// 			registered_logger->L.log_vector ( registered_logger->ids ( 1 ), cvectorize(mQ) );
-// 			registered_logger->L.log_vector ( registered_logger->ids ( 2 ), cvectorize(mR) );
-// 			
-// 		}
-// };
-// UIREGISTER(MPF_ARXg);
+class NoiseParticle : public MarginalizedParticleBase{
+	protected:
+		//! function transforming xt, ut -> x_t+1
+		shared_ptr<fnc> g; // pdf for non-linear part
+		//! function transforming xt,ut -> yt
+		shared_ptr<fnc> h; // pdf for non-linear part
+
+		RV rvv;
+		
+		RV rvx;
+		RV rvxc;
+		RV rvyc;
+		
+		//!link from condition to f
+		datalink_part cond2g;
+		//!link from condition to h
+		datalink_part cond2h;
+		//!link from xt to f
+		datalink_part x2g;
+		//!link from xt to h
+		datalink_part x2h;
+		
+	public:
+		BM* _copy() const{return new NoiseParticle();};
+		void bayes(const vec &dt, const vec &cond){
+			epdf* pred_vw=bm->epredictor();
+			shared_ptr<epdf> pred_v = pred_vw->marginal(rvv);
+			
+			vec vt=pred_v->sample();
+			
+			//new sample
+			vec &xtm=est_emp.point;
+			vec g_args(g->dimensionc());
+			x2g.filldown(xtm,g_args);
+			cond2g.filldown(cond,g_args);
+			vec xt = g->eval(g_args) + vt;
+			
+			// residue of observation
+			vec h_args(h->dimensionc());
+			x2h.filldown(xt,h_args);
+			cond2h.filldown(cond,h_args);
+			vec wt = dt-h->eval(h_args);
+			// the vector [v_t,w_t] is now complete
+			bm->bayes(concat(vt,wt));
+			ll=bm->_ll();
+		}
+		void from_setting(const Setting &set){
+			MarginalizedParticleBase::from_setting(set); //reads bm, yrv,rvc, bm_rv, etc...
+				
+			UI::get(g,set,"g",UI::compulsory);
+			UI::get(h,set,"h",UI::compulsory);
+			RV rvx;
+			UI::get(rvx,set,"rvx",UI::compulsory);
+			est_emp.set_rv(rvx);
+			
+			RV rvxc;
+			UI::get(rvxc,set,"rvxc",UI::compulsory);
+			RV rvyc;
+			UI::get(rvyc,set,"rvyc",UI::compulsory);
+		}
+		void validate(){
+			MarginalizedParticleBase::validate();
+			//check dimensions
+			rvc = rvxc;
+			rvc.add( rvyc);
+			rvc.subt(rvx);
+		
+			//establish datalinks
+			x2g.set_connection(rvxc, rvx.copy_t(-1));
+			cond2g.set_connection(rvxc, rvc);
+			
+			x2h.set_connection(rvyc, rvx);
+			cond2h.set_connection(rvyc, rvc);
+		}
+};
+UIREGISTER(NoiseParticle);
+
 
 
Index: /library/bdm/base/bdmbase.h
===================================================================
--- /library/bdm/base/bdmbase.h (revision 962)
+++ /library/bdm/base/bdmbase.h (revision 971)
@@ -1245,4 +1245,6 @@
 	bool evalll;
 
+	//! Initial prior (if given)
+	shared_ptr<epdf> prior0;
 public:
 	//! \name Constructors
@@ -1370,4 +1372,6 @@
 		set_rv ( r );
 
+		prior0=UI::build<epdf>(set,"prior",UI::optional);
+		
 		UI::get ( log_level, set, "log_level", UI::optional );
 	}
@@ -1388,4 +1392,6 @@
 			const_cast<epdf&> ( posterior() ).log_level[epdf::logmean] = true;;
 		}
+		if (prior0)
+			set_prior(prior0.get());
 	}
 };
Index: /applications/bdmtoolbox/sandbox/mpf_arx_3.m
===================================================================
--- /applications/bdmtoolbox/sandbox/mpf_arx_3.m (revision 811)
+++ /applications/bdmtoolbox/sandbox/mpf_arx_3.m (revision 971)
@@ -1,2 +1,3 @@
+clear all;
 x = RV('x',2);
 y = RV('y',2);
@@ -6,4 +7,8 @@
 g.dimc = 2;
 g.function = 'test_function';
+
+g.class = 'linfn';
+g.A     = eye(2);
+g.B     = [1;0];
 
 h.class = 'linfn';
@@ -33,30 +38,29 @@
 %%%%% Estimator
 A.class = 'ARX';
-A.rv = y;
+A.yrv = RV('vw',4);
 A.rgr = RV({});
-A.rv_param = RV('R',4);
-A.dimx=2;
+A.dimx=4;
 A.constant = 0;
 A.frg=0.99;
 
-A2=A;
-A2.rv_param = RV('Q',4);
-A2.rv=x;
+M.class = 'NoiseParticle';
+M.g = g;
+M.h = h;
+M.rvx = x;
+M.rvxc = RVtimes(x,-1);
+M.rvyc = x;
+M.bm = A;
 
-E.class = 'MPF_ARXg';
-E.g = g;
-E.h = h;
-E.rvc = x;
-E.arxo = A;
-E.arxp = A2;
-E.prior.class = 'enorm<ldmat>';
-E.prior.mu = [0.2;0.3];
-E.prior.R = 0.1*eye(2);
-E.n = 100;
-E.res_threshold = 1.0;
+PF.class='PF';
+PF.particle = M;
+PF.n = 100;
+PF.res_threshold = 1.0;
+PF.prior.class = 'enorm<ldmat>';
+PF.prior.mu = [0.2;0.3];
+PF.prior.R = 0.1*eye(2);
 
 
 exper.ndat = 2000;
-M = estimator(DS,{E},exper);
+O = estimator(DS,{PF},exper);
 %%%%%% ARX estimator conditioned on frg
 
