00001 #ifndef _ESTIMATION_HPP
00002 #define _ESTIMATION_HPP
00003
00004 #include <iostream>
00005 #include <iomanip>
00006 #include "query_point.hpp"
00007 #include "coloring_mcmc.hpp"
00008
00013 #define POINT_SET_ESTIMATE_HEADER "\
00014 #######################################################################\n\
00015 # \n\
00016 # This file represents estimates of the colors of points under an \n\
00017 # Arak process. The first line below consists of the number of samples\n\
00018 # used to compute the estimates (needed to merge estimates) and then \n\
00019 # the number of point estimates. Each line thereafter represents an \n\
00020 # point color estimate: the first two numbers are the X and Y \n\
00021 # coordinates of the point, and the third number is the estimated \n\
00022 # probability that the point is colored black. \n\
00023 # \n\
00024 #######################################################################\n"
00025
00026 #define GRID_ESTIMATE_HEADER "\
00027 #######################################################################\n\
00028 # \n\
00029 # This file represents estimates of the colors of a grid of points \n\
00030 # under an Arak process. The first line below consists of the number \n\
00031 # of samples used to compute the estimates (needed to merge estimates).\n\
00032 # The second line has the number of rows and columns in the grid. The \n\
00033 # third line gives the boundary of the grid. Then the estimates are \n\
00034 # written out as a matrix (one line per row) in reverse-row order (so \n\
00035 # the first element corresponds to the upper left corner of the grid. \n\
00036 # Each estimate is the probability the cell's center point is black. \n\
00037 # \n\
00038 #######################################################################\n"
00039
00040 namespace Arak {
00041
00045 class PointColorEstimator : public QueryPointListener {
00046
00047 friend class PointSetColorEstimator;
00048 friend class GridColorEstimator;
00049
00050 protected:
00051
00055 const ArakMarkovChain& chain;
00056
00060 const Geometry::Point point;
00061
00066 unsigned long int updated;
00067
00071 Color color;
00072
00076 unsigned long int numBlack;
00077
00081 unsigned long int numWhite;
00082
00090 void update(Color color, unsigned long int time) {
00091 assert(updated <= time);
00092
00093
00094 unsigned long int duration = time - updated;
00095 if (this->color == BLACK)
00096 numBlack += duration;
00097 else if (this->color == WHITE)
00098 numWhite += duration;
00099 this->color = color;
00100 updated = time;
00101 }
00102
00103 public:
00104
00113 PointColorEstimator(const ArakMarkovChain& chain,
00114 const Geometry::Point& point,
00115 Color color) :
00116 QueryPointListener(), chain(chain), point(point),
00117 updated(chain.getNumSamples()), color(color),
00118 numBlack(0), numWhite(0) { }
00119
00123 virtual ~PointColorEstimator() { }
00124
00131 virtual void recolor(Color color) {
00132 update(color, chain.getNumSamples());
00133 }
00134
00138 double estimate() const {
00139 unsigned long int time = chain.getNumSamples();
00140 unsigned long int curNumBlack =
00141 numBlack + ((color == BLACK) ? time - updated : 0);
00142 unsigned long int curNumWhite =
00143 numWhite + ((color == BLACK) ? 0 : time - updated);
00144 if ((curNumBlack == 0) && (curNumWhite == 0))
00145 return 0.5;
00146 else
00147 return (double(curNumBlack) /
00148 (double(curNumBlack) + double(curNumWhite)));
00149 }
00150
00151 };
00152
00157 class PointSetColorEstimator : public QueryPointListenerFactory {
00158
00159 protected:
00160
00164 const ArakMarkovChain& chain;
00165
00169 std::list<PointColorEstimator*> estimators;
00170
00175 QueryPointIndex* index;
00176
00177 public:
00178
00190 PointSetColorEstimator(ArakMarkovChain& chain,
00191 const Arak::Util::PropertyMap& props);
00192
00196 virtual ~PointSetColorEstimator() {
00197 while (!estimators.empty()) {
00198 PointColorEstimator* estimator = estimators.front();
00199 estimators.pop_front();
00200 delete estimator;
00201 }
00202
00203 delete index;
00204 }
00205
00209 virtual PointColorEstimator* create(const QueryPoint& p) {
00210 PointColorEstimator* estimator =
00211 new PointColorEstimator(chain, p, p.color());
00212 estimators.push_front(estimator);
00213 return estimator;
00214 }
00215
00225 virtual void visualize(CGAL::Qt_widget& widget) const;
00226
00235 template<typename charT, typename traits>
00236 void write(std::basic_ostream<charT,traits>& out) const {
00237
00238 out << POINT_SET_ESTIMATE_HEADER;
00239
00240 out << chain.getNumSamples() << " "
00241 << estimators.size() << std::endl;
00242
00243 out << std::scientific << std::setw(16) << std::setprecision(12);
00244 typedef std::list<PointColorEstimator*>::const_iterator Iterator;
00245 for (Iterator it = estimators.begin(); it != estimators.end(); it++) {
00246 const PointColorEstimator* estimator = *it;
00247 out << estimator->point << " " << estimator->estimate() << std::endl;
00248 }
00249 }
00250 };
00251
00261 inline CGAL::Qt_widget& operator<<(CGAL::Qt_widget& widget,
00262 PointSetColorEstimator& p) {
00263 p.visualize(widget);
00264 return widget;
00265 }
00266
00275 template<typename charT, typename traits>
00276 std::basic_ostream<charT,traits>&
00277 operator<<(std::basic_ostream<charT,traits>& out,
00278 const PointSetColorEstimator& p) {
00279 p.write(out);
00280 return out;
00281 }
00282
00286 class GridColorEstimator : public Coloring::Listener {
00287
00288 protected:
00289
00293 const ArakMarkovChain& chain;
00294
00298 std::list<PointColorEstimator*> estimators;
00299
00303 typedef Grid<PointColorEstimator*> EstimatorGrid;
00304
00309 EstimatorGrid* grid;
00310
00311 public:
00312
00324 GridColorEstimator(ArakMarkovChain& chain,
00325 const Arak::Util::PropertyMap& props);
00326
00330 virtual ~GridColorEstimator() {
00331 while (!estimators.empty()) {
00332 PointColorEstimator* estimator = estimators.front();
00333 estimators.pop_front();
00334 delete estimator;
00335 }
00336 delete grid;
00337 }
00338
00347 virtual void recolored(const Geometry::Point& a,
00348 const Geometry::Point& b,
00349 const Geometry::Point& c);
00350
00363 virtual void recolored(const Geometry::Point& a,
00364 const Geometry::Point& b,
00365 const Geometry::Point& c,
00366 const Geometry::Point& d) {
00367 recolored(a, b, c);
00368 recolored(a, d, c);
00369 }
00370
00380 virtual void visualize(CGAL::Qt_widget& widget) const;
00381
00394 template<typename charT, typename traits>
00395 void write(std::basic_ostream<charT,traits>& out) const {
00396
00397 out << GRID_ESTIMATE_HEADER;
00398
00399 out << chain.getNumSamples() << std::endl;
00400
00401 out << grid->numRows() << " " << grid->numCols() << std::endl;
00402
00403 out << grid->boundary() << std::endl;
00404
00405 out << std::scientific << std::setw(16) << std::setprecision(12);
00406 for (int i = grid->numRows() - 1; i >= 0; i--) {
00407 for (int j = 0; j < grid->numCols(); j++) {
00408 const EstimatorGrid::Cell& cell = grid->getCell(i, j);
00409 const PointColorEstimator* pce = *(cell.getItemList().begin());
00410 out << pce->estimate() << " ";
00411 }
00412 out << std::endl;
00413 }
00414 }
00415 };
00416
00426 inline CGAL::Qt_widget& operator<<(CGAL::Qt_widget& widget,
00427 GridColorEstimator& p) {
00428 p.visualize(widget);
00429 return widget;
00430 }
00431
00440 template<typename charT, typename traits>
00441 std::basic_ostream<charT,traits>&
00442 operator<<(std::basic_ostream<charT,traits>& out,
00443 const GridColorEstimator& p) {
00444 p.write(out);
00445 return out;
00446 }
00447
00448 }
00449
00450 #endif