/*! \file \brief Probability distributions for discrete support densities \author Vaclav Smidl. ----------------------------------- BDM++ - C++ library for Bayesian Decision Making under Uncertainty Using IT++ for numerical operations ----------------------------------- */ #ifndef DISCR_H #define DISCR_H #include "../shared_ptr.h" #include "../base/bdmbase.h" #include "../math/chmat.h" namespace bdm { //! Rectangular support //! Support points are located inbetween ranges! For example: //! For ranges=[0,1] and gridsizes=[1] the support point is 0.5 class rectangular_support: public root { protected: //! Array of boundaries (2D vectors: [begining,end]) for each dimension Array ranges; //! Number of support points in each dimension ivec gridsizes; //! dimension int dim; //! Number of data points int Npoints; //! active vector for first_vec and next_vec vec actvec; //! indeces of active vector vec actvec_ind; //! length of steps in each dimension vec steps; public: //! default constructor rectangular_support() : dim(0), Npoints(0) { } //! set parameters void set_parameters(const Array &ranges0, const ivec &gridsize0){ ranges=ranges0; gridsizes=gridsize0; initialize(); } //! Internal functio to set temporaries correctly void initialize() { dim = ranges.length(); bdm_assert(gridsizes.length() == dim, "Incompatible dimensions of input"); Npoints = prod(gridsizes); bdm_assert(Npoints > 0, "Wrong input parameters"); //precompute steps steps.set_size(dim); for ( int j = 0; j < dim; j++ ) { steps ( j ) = ( ranges ( j ) ( 1 ) - ranges(j)(0) ) / gridsizes ( j ); } actvec.set_size(dim); actvec_ind.set_size(dim); } //! return vector at position given by vector of indeces vec get_vec(const ivec &inds){ vec v ( dim ); for ( int j = 0; j < dim; j++ ) { bdm_assert_debug(inds(j) < gridsizes(j), "Index out of bounds"); v ( j ) = ranges(j)(0) + (0.5+inds(j))*steps(j); } return v; } //! convert dimension indeces into linear index, the indexing is in the same way as in \c next_vec() long linear_index (const ivec inds){ long ind=0; bdm_assert_debug(inds.length() == dim, "Improper indices inds"); int dim_skips=1; // skips in active dimension, in the first dimension, the skips are 1 index per value for (int j=0; jranges(j)(1)) inds(j) = gridsizes(j)-1; else { inds(j) = ::round(val(j) - ranges(j)(0)/ steps(j)); } } } return inds; } //! Access function int points() const {return Npoints;} //! access function const vec& _steps() const {return steps;} void from_setting (const Setting &set) { UI::get (ranges , set, "ranges", UI::compulsory); UI::get (gridsizes, set, "gridsizes", UI::compulsory); initialize(); } }; UIREGISTER(rectangular_support); //! Discrete support with stored support points class discrete_support: public root{ protected: //! storage of support points Array Spoints; //! index in iterators int idx; public: //! Default constructor discrete_support() : Spoints(0), idx(0){} //! Access function int points() const {return Spoints.length();} //! set the first vector to corner and store result in actvec const vec& first_vec(){bdm_assert_debug(Spoints.length()>0,"Empty support");idx=0; return Spoints(idx);} //! set next vector after calling first_vec() const vec& next_vec(){bdm_assert_debug(Spoints.length()>idx-1,"Out of support points"); return Spoints(++idx);} /*! \code class = "discrete_support"; points = ( [1,2..], [2,2..], ...); // list of points === OR === epdf = {class="epdf_offspring",...}; // epdf rfom which to sample npoints = 100; // number of samples \endcode */ void from_setting (const Setting &set) { UI::get (Spoints, set, "points", UI::compulsory); if (points()<1){ int npoints; shared_ptr ep= UI::build(set, "epdf", UI::compulsory); if (!UI::get(npoints,set,"npoints",UI::optional)){npoints=100;} //sample Spoints.set_size(npoints); for(int i=0; isample();} } } //! access function Array & _Spoints() {return Spoints;} }; UIREGISTER(discrete_support); class grid_fnc: public fnc{ protected: rectangular_support sup; vec values; public: //! constructor function void set_support(rectangular_support &sup0){sup=sup0; values=zeros(sup.points());} //! constructor function fills values by calling function \c f , double f(vec&), given by a pointer void set_values(double (*evalptr)(const vec&)){ if (sup.points()>0){ values(0) = (*evalptr)(sup.first_vec()); for (int j=1; j