Index: library/bdm/base/bdmbase.h
===================================================================
--- library/bdm/base/bdmbase.h (revision 477)
+++ library/bdm/base/bdmbase.h (revision 487)
@@ -399,5 +399,4 @@
 //! Conditional probability density, e.g. modeling some dependencies.
 //TODO Samplecond can be generalized
-
 class mpdf : public root {
 protected:
@@ -406,8 +405,12 @@
 	//! random variable in condition
 	RV rvc;
-
 private:
-	//! pointer to internal epdf
-	shared_ptr<epdf> shep;
+	//! internal epdf, used only as cache to avoid virtual calls of \c _rv() and \c _dimension()
+	epdf* ep;
+	
+protected:
+	void set_ep(epdf &iepdf) {
+		ep = &iepdf;
+	}
 
 public:
@@ -415,7 +418,7 @@
 	//! @{
 
-	mpdf() : dimc ( 0 ), rvc() { }
-
-	mpdf ( const mpdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), shep ( m.shep ) { }
+	mpdf() : dimc ( 0 ), rvc(), ep(NULL) { }
+
+	mpdf ( const mpdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), ep ( m.ep ) { }
 	//!@}
 
@@ -424,22 +427,18 @@
 
 	//! Returns a sample from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv
-	virtual vec samplecond ( const vec &cond );
+	virtual vec samplecond ( const vec &cond ){it_error("Not implemented");return vec(0);};
 
 	//! Returns \param N samples from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv
-	virtual mat samplecond_m ( const vec &cond, int N );
-
-	//! Update \c ep so that it represents this mpdf conditioned on \c rvc = cond
-	virtual void condition ( const vec &cond ) {
-		it_error ( "Not implemented" );
-	};
+	virtual mat samplecond_m ( const vec &cond, int N ){it_error("Not implemented");return mat();}
+
 
 	//! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
-	virtual double evallogcond ( const vec &dt, const vec &cond );
+	virtual double evallogcond ( const vec &dt, const vec &cond ){it_error("Not implemented");return 0.0;}
 
 	//! Matrix version of evallogcond
-	virtual vec evallogcond_m ( const mat &Dt, const vec &cond );
+	virtual vec evallogcond_m ( const mat &Dt, const vec &cond ){it_error("Not implemented");return vec(0);}
 
 	//! Array<vec> version of evallogcond
-	virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond );
+	virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ){it_error("Not implemented");return vec(0);}
 
 	//! \name Access to attributes
@@ -447,5 +446,5 @@
 
 	RV _rv() {
-		return shep->_rv();
+		return ep->_rv();
 	}
 	RV _rvc() {
@@ -454,5 +453,5 @@
 	}
 	int dimension() {
-		return shep->dimension();
+		return ep->dimension();
 	}
 	int dimensionc() {
@@ -460,15 +459,8 @@
 	}
 
-	epdf *e() {
-		return shep.get();
-	}
-
-	void set_ep ( shared_ptr<epdf> ep ) {
-		shep = ep;
-	}
-
 	//! Load from structure with elements:
 	//!  \code
-	//! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable
+	//! { class = "mpdf_offspring",
+	//!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable
 	//!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition
 	//!   // elements of offsprings
@@ -485,10 +477,37 @@
 	}
 	void set_rv ( const RV &rv0 ) {
-		shep->set_rv ( rv0 );
+		ep->set_rv ( rv0 );
 	}
 	bool isnamed() {
-		return ( shep->isnamed() ) && ( dimc == rvc._dsize() );
-	}
-	//!@}
+		return ( ep->isnamed() ) && ( dimc == rvc._dsize() );
+	}
+	//!@}
+};
+
+template <class EPDF>
+class mpdf_internal: public mpdf{
+	protected :
+		EPDF iepdf;
+	public:
+		//! constructor
+		mpdf_internal(): mpdf(),iepdf(){set_ep(iepdf);}
+		//! Update \c iepdf so that it represents this mpdf conditioned on \c rvc = cond
+		//! This function provides convenient reimplementation in offsprings
+			virtual void condition ( const vec &cond ) {
+				it_error ( "Not implemented" );
+			};
+		//!access function to iepdf
+		EPDF& e(){return iepdf;}
+			
+		//! Reimplements samplecond using \c condition()
+		vec samplecond ( const vec &cond );
+		//! Reimplements evallogcond using \c condition()
+		double evallogcond ( const vec &val, const vec &cond );
+		//! Efficient version of evallogcond for matrices 
+		virtual vec evallogcond_m ( const mat &Dt, const vec &cond );
+		//! Efficient version of evallogcond for Array<vec>
+		virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond );
+		//! Efficient version of samplecond 
+		virtual mat samplecond_m ( const vec &cond, int N );
 };
 
@@ -686,4 +705,6 @@
 */
 class mepdf : public mpdf {
+
+shared_ptr<epdf> ipdf;
 public:
 	//!Default constructor
@@ -691,5 +712,6 @@
 
 	mepdf ( shared_ptr<epdf> em ) {
-		set_ep ( em );
+		ipdf = em;
+		set_ep(*ipdf.get());
 		dimc = 0;
 	}
@@ -701,5 +723,5 @@
 	//!  \code
 	//! { class = "mepdf",
-	//!   epdfs = {class="epdfs",...}
+	//!   epdf = {class="epdf_offspring",...}
 	//! }
 	//! \endcode
