| 24 | | //! Rectangular support |
| 25 | | //! Support points are located inbetween ranges! For example: |
| 26 | | //! For ranges=[0,1] and gridsizes=[1] the support point is 0.5 |
| 27 | | class rectangular_support: public root { |
| 28 | | protected: |
| 29 | | //! Array of boundaries (2D vectors: [begining,end]) for each dimension |
| 30 | | Array<vec> ranges; |
| 31 | | //! Number of support points in each dimension |
| 32 | | ivec gridsizes; |
| 33 | | //! dimension |
| 34 | | int dim; |
| 35 | | //! Number of data points |
| 36 | | int Npoints; |
| 37 | | //! active vector for first_vec and next_vec |
| 38 | | vec actvec; |
| 39 | | //! indeces of active vector |
| 40 | | vec actvec_ind; |
| 41 | | //! length of steps in each dimension |
| 42 | | vec steps; |
| 43 | | public: |
| 44 | | //! default constructor |
| 45 | | rectangular_support() : dim(0), Npoints(0) { |
| 46 | | } |
| 47 | | |
| 48 | | //! set parameters |
| 49 | | void set_parameters(const Array<vec> &ranges0, const ivec &gridsize0){ |
| 50 | | ranges=ranges0; |
| 51 | | gridsizes=gridsize0; |
| 52 | | initialize(); |
| 53 | | } |
| 54 | | //! Internal functio to set temporaries correctly |
| 55 | | void initialize() { |
| 56 | | dim = ranges.length(); |
| 57 | | bdm_assert(gridsizes.length() == dim, "Incompatible dimensions of input"); |
| 58 | | Npoints = prod(gridsizes); |
| 59 | | bdm_assert(Npoints > 0, "Wrong input parameters"); |
| 60 | | |
| 61 | | //precompute steps |
| 62 | | steps.set_size(dim); |
| 63 | | for ( int j = 0; j < dim; j++ ) { |
| 64 | | steps ( j ) = ( ranges ( j ) ( 1 ) - ranges(j)(0) ) / gridsizes ( j ); |
| 65 | | } |
| 66 | | actvec.set_size(dim); |
| 67 | | actvec_ind.set_size(dim); |
| 68 | | } |
| 69 | | //! return vector at position given by vector of indeces |
| 70 | | vec get_vec(const ivec &inds){ |
| 71 | | vec v ( dim ); |
| 72 | | for ( int j = 0; j < dim; j++ ) { |
| 73 | | bdm_assert_debug(inds(j) < gridsizes(j), "Index out of bounds"); |
| 74 | | v ( j ) = ranges(j)(0) + (0.5+inds(j))*steps(j); |
| 75 | | } |
| 76 | | return v; |
| 77 | | } |
| | 23 | //! Rectangular support |
| | 24 | //! Support points are located inbetween ranges! For example: |
| | 25 | //! For ranges=[0,1] and gridsizes=[1] the support point is 0.5 |
| | 26 | class rectangular_support: public root { |
| | 27 | protected: |
| | 28 | //! Array of boundaries (2D vectors: [begining,end]) for each dimension |
| | 29 | Array<vec> ranges; |
| | 30 | //! Number of support points in each dimension |
| | 31 | ivec gridsizes; |
| | 32 | //! dimension |
| | 33 | int dim; |
| | 34 | //! Number of data points |
| | 35 | int Npoints; |
| | 36 | //! active vector for first_vec and next_vec |
| | 37 | vec actvec; |
| | 38 | //! indeces of active vector |
| | 39 | vec actvec_ind; |
| | 40 | //! length of steps in each dimension |
| | 41 | vec steps; |
| | 42 | public: |
| | 43 | //! default constructor |
| | 44 | rectangular_support() : dim ( 0 ), Npoints ( 0 ) { |
| | 45 | } |
| 79 | | //! convert dimension indeces into linear index, the indexing is in the same way as in \c next_vec() |
| 80 | | long linear_index (const ivec inds){ |
| 81 | | long ind=0; |
| 82 | | bdm_assert_debug(inds.length() == dim, "Improper indices inds"); |
| 83 | | int dim_skips=1; // skips in active dimension, in the first dimension, the skips are 1 index per value |
| 84 | | |
| 85 | | for (int j=0; j<dim; j++){ |
| 86 | | ind += dim_skips*(inds(j)); // add shift in linear index caused by this dimension |
| 87 | | dim_skips*=gridsizes(j); // indeces in the next dimension are repeated with period gridsizes(j) times greater that in this dimesion |
| 88 | | } |
| 89 | | return ind; |
| 90 | | } |
| 91 | | //! set the first vector to corner and store result in actvec |
| 92 | | const vec& first_vec(){ |
| 93 | | for ( int j = 0; j < dim; j++ ) { |
| 94 | | actvec ( j ) = ranges(j)(0) + 0.5*steps(j); |
| 95 | | actvec_ind(j) = 0; |
| 96 | | } |
| 97 | | return actvec; |
| 98 | | } |
| 99 | | //! Get next active vector, call ONLY after first_vector()! |
| 100 | | const vec& next_vec() { |
| 101 | | // go through all dimensions |
| 102 | | int j=0; |
| 103 | | while (j<dim) { |
| 104 | | if ( actvec_ind ( j ) == gridsizes ( j ) - 1 ) { //j-th index is full |
| 105 | | actvec_ind ( j ) = 0; //shift back |
| 106 | | actvec ( j ) = ranges ( j ) ( 0 ) + 0.5*steps(j); |
| 107 | | j++; |
| 108 | | } else { |
| 109 | | actvec_ind ( j ) ++; |
| 110 | | actvec ( j ) += steps ( j ); |
| 111 | | break; |
| 112 | | } |
| 113 | | } |
| 114 | | return actvec; |
| 115 | | } |
| 116 | | |
| 117 | | ivec nearest_point(const vec &val){ |
| 118 | | ivec inds; |
| 119 | | inds.set_size(dim); |
| 120 | | for(int j=0; j<dim; j++){ |
| 121 | | if (val(j)<ranges(j)(0)) |
| 122 | | inds(j) = 0; |
| 123 | | else { |
| 124 | | if (val(j)>ranges(j)(1)) |
| 125 | | inds(j) = gridsizes(j)-1; |
| 126 | | else { |
| 127 | | inds(j) = ::round(val(j) - ranges(j)(0)/ steps(j)); |
| 128 | | } |
| 129 | | } |
| 130 | | } |
| 131 | | return inds; |
| 132 | | } |
| | 47 | //! set parameters |
| | 48 | void set_parameters ( const Array<vec> &ranges0, const ivec &gridsize0 ); |
| 134 | | //! Access function |
| 135 | | int points() const {return Npoints;} |
| 136 | | |
| 137 | | //! access function |
| 138 | | const vec& _steps() const {return steps;} |
| 139 | | |
| 140 | | void from_setting (const Setting &set) { |
| 141 | | UI::get (ranges , set, "ranges", UI::compulsory); |
| 142 | | UI::get (gridsizes, set, "gridsizes", UI::compulsory); |
| 143 | | initialize(); |
| 144 | | } |
| 145 | | }; |
| 146 | | UIREGISTER(rectangular_support); |
| 147 | | |
| 148 | | //! Discrete support with stored support points |
| 149 | | class discrete_support: public root{ |
| 150 | | protected: |
| 151 | | //! storage of support points |
| 152 | | Array<vec> Spoints; |
| 153 | | //! index in iterators |
| 154 | | int idx; |
| 155 | | public: |
| 156 | | //! Default constructor |
| 157 | | discrete_support() : Spoints(0), idx(0){} |
| 158 | | //! Access function |
| 159 | | int points() const {return Spoints.length();} |
| 160 | | //! set the first vector to corner and store result in actvec |
| 161 | | const vec& first_vec(){bdm_assert_debug(Spoints.length()>0,"Empty support");idx=0; return Spoints(idx);} |
| 162 | | //! set next vector after calling first_vec() |
| 163 | | const vec& next_vec(){bdm_assert_debug(Spoints.length()>idx-1,"Out of support points"); return Spoints(++idx);} |
| 164 | | |
| 165 | | /*! |
| 166 | | \code |
| 167 | | class = "discrete_support"; |
| 168 | | points = ( [1,2..], [2,2..], ...); // list of points |
| 169 | | === OR === |
| 170 | | epdf = {class="epdf_offspring",...}; // epdf rfom which to sample |
| 171 | | npoints = 100; // number of samples |
| 172 | | \endcode |
| 173 | | */ |
| 174 | | void from_setting (const Setting &set) { |
| 175 | | UI::get (Spoints, set, "points", UI::compulsory); |
| 176 | | if (points()<1){ |
| 177 | | int npoints; |
| 178 | | shared_ptr<epdf> ep= UI::build<epdf>(set, "epdf", UI::compulsory); |
| 179 | | if (!UI::get(npoints,set,"npoints",UI::optional)){npoints=100;} |
| 180 | | |
| 181 | | //sample |
| 182 | | Spoints.set_size(npoints); |
| 183 | | for(int i=0; i<points(); i++){Spoints(i)=ep->sample();} |
| 184 | | } |
| 185 | | } |
| 186 | | //! access function |
| 187 | | Array<vec> & _Spoints() {return Spoints;} |
| 188 | | }; |
| 189 | | UIREGISTER(discrete_support); |
| 190 | | |
| 191 | | class grid_fnc: public fnc{ |
| 192 | | protected: |
| 193 | | rectangular_support sup; |
| 194 | | vec values; |
| 195 | | public: |
| 196 | | //! constructor function |
| 197 | | void set_support(rectangular_support &sup0){sup=sup0; values=zeros(sup.points());} |
| 198 | | //! constructor function fills values by calling function \c f , double f(vec&), given by a pointer |
| 199 | | void set_values(double (*evalptr)(const vec&)){ |
| 200 | | if (sup.points()>0){ |
| 201 | | values(0) = (*evalptr)(sup.first_vec()); |
| 202 | | for (int j=1; j<sup.points(); j++){ |
| 203 | | values(j)=(*evalptr)(sup.next_vec()); |
| 204 | | } |
| 205 | | } |
| 206 | | } |
| 207 | | //! get value nearest to the given point |
| 208 | | double nearest_val(const vec &val){return values( sup.linear_index(sup.nearest_point(val)));} |
| 209 | | |
| 210 | | vec eval(const vec &val){return vec_1(nearest_val(val));} |
| 211 | | }; |
| 212 | | UIREGISTER(grid_fnc); |
| | 50 | //! Internal functio to set temporaries correctly |
| | 51 | void initialize(); |
| 214 | | //! Piecewise constant pdf on rectangular support |
| 215 | | //! Each point on the grid represents a centroid around which the density is constant. |
| 216 | | //! This is a trivial point-mass density where all points have the same mass. |
| 217 | | class egrid: public epdf{ |
| 218 | | protected: |
| 219 | | rectangular_support sup; |
| 220 | | vec values; |
| 221 | | public: |
| 222 | | //! we assume that evallog is not called too often otherwise we should cache log(values) |
| 223 | | double evallog(const vec &val){return log(values( sup.linear_index(sup.nearest_point(val))));} |
| 224 | | |
| 225 | | }; |
| | 53 | //! return vector at position given by vector of indeces |
| | 54 | vec get_vec ( const ivec &inds ); |
| | 55 | |
| | 56 | //! convert dimension indeces into linear index, the indexing is in the same way as in \c next_vec() |
| | 57 | long linear_index ( const ivec inds ); |
| | 58 | |
| | 59 | //! set the first vector to corner and store result in actvec |
| | 60 | const vec& first_vec(); |
| | 61 | |
| | 62 | //! Get next active vector, call ONLY after first_vector()! |
| | 63 | const vec& next_vec(); |
| | 64 | |
| | 65 | //! \todo to je asi navic .. v predkovi! |
| | 66 | ivec nearest_point ( const vec &val ); |
| | 67 | |
| | 68 | //! Access function |
| | 69 | int points() const { |
| | 70 | return Npoints; |
| | 71 | } |
| | 72 | |
| | 73 | //! access function |
| | 74 | //! \todo opet pouze do potomka.. |
| | 75 | const vec& _steps() const { |
| | 76 | return steps; |
| | 77 | } |
| | 78 | |
| | 79 | void from_setting ( const Setting &set ); |
| | 80 | }; |
| | 81 | UIREGISTER ( rectangular_support ); |
| | 82 | |
| | 83 | //! Discrete support with stored support points |
| | 84 | class discrete_support: public root { |
| | 85 | protected: |
| | 86 | //! storage of support points |
| | 87 | Array<vec> Spoints; |
| | 88 | //! index in iterators |
| | 89 | int idx; |
| | 90 | public: |
| | 91 | //! Default constructor |
| | 92 | discrete_support() : Spoints ( 0 ), idx ( 0 ) {} |
| | 93 | //! Access function |
| | 94 | int points() const { |
| | 95 | return Spoints.length(); |
| | 96 | } |
| | 97 | //! set the first vector to corner and store result in actvec |
| | 98 | const vec& first_vec() { |
| | 99 | bdm_assert_debug ( Spoints.length() > 0, "Empty support" ); |
| | 100 | idx = 0; |
| | 101 | return Spoints ( idx ); |
| | 102 | } |
| | 103 | //! set next vector after calling first_vec() |
| | 104 | const vec& next_vec() { |
| | 105 | bdm_assert_debug ( Spoints.length() > idx - 1, "Out of support points" ); |
| | 106 | return Spoints ( ++idx ); |
| | 107 | } |
| | 108 | |
| | 109 | /*! |
| | 110 | \code |
| | 111 | class = "discrete_support"; |
| | 112 | points = ( [1,2..], [2,2..], ...); // list of points |
| | 113 | === OR === |
| | 114 | epdf = {class="epdf_offspring",...}; // epdf rfom which to sample |
| | 115 | npoints = 100; // number of samples |
| | 116 | \endcode |
| | 117 | */ |
| | 118 | void from_setting ( const Setting &set ); |
| | 119 | |
| | 120 | //! access function |
| | 121 | Array<vec> & _Spoints() { |
| | 122 | return Spoints; |
| | 123 | } |
| | 124 | }; |
| | 125 | UIREGISTER ( discrete_support ); |
| | 126 | |
| | 127 | class grid_fnc: public fnc { |
| | 128 | protected: |
| | 129 | rectangular_support sup; |
| | 130 | vec values; |
| | 131 | public: |
| | 132 | //! constructor function |
| | 133 | void set_support ( rectangular_support &sup0 ) { |
| | 134 | sup = sup0; |
| | 135 | values = zeros ( sup.points() ); |
| | 136 | } |
| | 137 | //! constructor function fills values by calling function \c f , double f(vec&), given by a pointer |
| | 138 | void set_values ( double ( *evalptr ) ( const vec& ) ); |
| | 139 | |
| | 140 | //! get value nearest to the given point |
| | 141 | double nearest_val ( const vec &val ) { |
| | 142 | return values ( sup.linear_index ( sup.nearest_point ( val ) ) ); |
| | 143 | } |
| | 144 | |
| | 145 | vec eval ( const vec &val ) { |
| | 146 | return vec_1 ( nearest_val ( val ) ); |
| | 147 | } |
| | 148 | }; |
| | 149 | UIREGISTER ( grid_fnc ); |
| | 150 | |
| | 151 | //! Piecewise constant pdf on rectangular support |
| | 152 | //! Each point on the grid represents a centroid around which the density is constant. |
| | 153 | //! This is a trivial point-mass density where all points have the same mass. |
| | 154 | class egrid: public epdf { |
| | 155 | protected: |
| | 156 | rectangular_support sup; |
| | 157 | vec values; |
| | 158 | public: |
| | 159 | //! we assume that evallog is not called too often otherwise we should cache log(values) |
| | 160 | double evallog ( const vec &val ) { |
| | 161 | return log ( values ( sup.linear_index ( sup.nearest_point ( val ) ) ) ); |
| | 162 | } |
| | 163 | |
| | 164 | }; |