AutoParameterExplorer.cpp
Go to the documentation of this file.
00001 #include <face_contour_detector/AutoParameterExplorer.h>
00002 #include <algorithm>
00003 #include <queue>
00004 #include <deque>
00005 #include <limits>
00006 #include <sstream>
00007 #include <ros/assert.h>
00008 
00009 namespace face_contour_detector {
00010 
00011         AutoParameterExplorer::AutoParameterExplorer(boost::function<void (const std::vector<double>&, std::map<std::string, double>&)> paramsFunction, boost::function<double (const std::map<std::string, double>&, const std::map<std::string, double>&)> costsFunction) : m_paramsFunction(paramsFunction), m_costsFunction(costsFunction) {}
00012         AutoParameterExplorer::~AutoParameterExplorer() {}
00013 
00014         void AutoParameterExplorer::AddParameter(const std::string& name, double min, double max) {
00015                 ROS_ASSERT(min < max);
00016 
00017                 m_paramNames.push_back(name);
00018                 m_startEnd.push_back(std::pair<double,double>(min, max));
00019         }
00020 
00021         void AutoParameterExplorer::FindBest(std::map<std::string, double> targetValue, int steps, int numResults, std::vector<std::map<std::string, double> >& results) {
00022 
00023                 //Ok let's do this
00024                 //generate the starting area that encloses everything
00025                 ParameterPoint base;
00026                 {
00027                         std::vector<std::pair<double,double> >::iterator it;
00028                         for (it = m_startEnd.begin(); it != m_startEnd.end(); it++) {
00029                                 base.AddParam(it->first);
00030                         }
00031                 }
00032                 Area a(base);
00033                 {
00034                         std::vector<std::pair<double,double> >::iterator it;
00035                         for (it = m_startEnd.begin(); it != m_startEnd.end(); it++) {
00036                                 a.AddDimension(it->second - it->first);
00037                         }
00038                 }
00039                 //check if the area should have the target value in it
00040                 if (!M_IsTargetValueInside(targetValue, a)) {
00041                         ROS_ERROR("The main parameter area does not contain the target values");
00042                         return;
00043                 }
00044 
00045                 //get the costs for the Area
00046                 M_GetCosts(targetValue, a);
00047 
00048                 //initialize the min ordered list
00049                 std::priority_queue<Area, std::vector<Area>, Area::GreaterCosts> activeQueue;
00050                 activeQueue.push(a);
00051 
00052                 //this is where the areas will be saved that could not be improved
00053                 std::priority_queue<Area, std::vector<Area>, Area::GreaterCosts> inactiveQueue;
00054                 //double lastBestCosts = std::numeric_limits<double>::infinity();
00055                 //bool foundBetter = true;
00056                 for (int i = 0; i < steps; i++) {
00057                         //foundBetter = false;
00058                         ROS_INFO("step %i", i);
00059                         Area currArea = activeQueue.top();
00060                         activeQueue.pop();
00062                         std::stringstream strS;
00063                         strS<<currArea;
00064                         ROS_INFO("%s", strS.str().c_str());
00065                         std::vector<Area> subAreas;
00066                         currArea.SubAreas(subAreas);
00067                         std::vector<Area>::iterator subIt;
00068                         bool foundGoodSubArea = false;
00069                         for (subIt = subAreas.begin(); subIt != subAreas.end(); subIt++) {
00070                                 if (M_IsTargetValueInside(targetValue, *subIt)) {
00071                                         foundGoodSubArea = true;
00072                                         M_GetCosts(targetValue, *subIt);
00073                                         /*if (lastBestCosts > subIt->Costs()) {
00074                                                 lastBestCosts = subIt->Costs();
00075                                                 foundBetter = true;
00076                                         }*/
00077                                         activeQueue.push(*subIt);
00078                                 }
00079                         }
00080                         if (!foundGoodSubArea) {
00081                                 inactiveQueue.push(currArea);
00082                         }
00083                 }
00084 
00085                 //Ok let's read out all the points for the top numResults areas
00086                 face_contour_detector::LimitedPriorityQueueSet<ParameterPoint, ParameterPoint::LessCosts> resultPoints(numResults);
00087                 while (resultPoints.Size() < numResults) {
00088                         if (activeQueue.empty() && inactiveQueue.empty()) {
00089                                 break;
00090                         }
00091                         if (activeQueue.empty()) {
00092                                 Area top = inactiveQueue.top();
00093                                 M_PushAllPoints(top, targetValue, resultPoints);
00094                                 inactiveQueue.pop();
00095                         } else if (inactiveQueue.empty()) {
00096                                 Area top = activeQueue.top();
00097                                 M_PushAllPoints(top, targetValue, resultPoints);
00098                                 activeQueue.pop();
00099                         } else {
00100                                 Area activeTop = activeQueue.top();
00101                                 Area inactiveTop = inactiveQueue.top();
00102                                 if (activeTop.Costs() > inactiveTop.Costs()) {
00103                                         M_PushAllPoints(inactiveTop, targetValue, resultPoints);
00104                                         inactiveQueue.pop();
00105                                 } else  {
00106                                         M_PushAllPoints(activeTop, targetValue, resultPoints);
00107                                         activeQueue.pop();
00108                                 }
00109                         }
00110 
00111                 }
00112 
00113                 //save out the results
00114                 for (int i = 0; i < numResults && !resultPoints.Empty(); i++) {
00115                         ParameterPoint currP = resultPoints.PopFront();
00116 
00117                         std::map<std::string, double> currResult;
00118                         std::vector<double> params = currP.Params();
00119                         std::vector<std::string>::iterator nameIt = m_paramNames.begin();
00120                         std::vector<double>::iterator valueIt = params.begin();
00121 
00122                         while (valueIt != params.end()) {
00123                                 currResult[*nameIt] = *valueIt;
00124                                 nameIt++;
00125                                 valueIt++;
00126                         }
00127                         results.push_back(currResult);
00128                 }
00129 
00130         }
00131 
00132         void AutoParameterExplorer::M_GetCosts(std::map<std::string, double>& targetValue, ParameterPoint& paramPoint) {
00133                 /*std::map<std::string, double> vars;
00134                 std::vector<double>& values = paramPoint.Params();
00135                 std::vector<std::string>::iterator nameIt = m_paramNames.begin();
00136                 std::vector<double>::iterator valueIt = values.begin();
00137 
00138                 while (valueIt != values.end()) {
00139 
00140                         vars[*nameIt] = *valueIt;
00141 
00142                         valueIt++;
00143                         nameIt++;
00144                 }
00145                 ROS_ASSERT(valueIt == values.end());
00146                 ROS_ASSERT(nameIt == m_paramNames.end());
00147 
00148                 paramPoint.Costs(m_costsFunction(vars));
00149                 ROS_ASSERT(paramPoint.HasCosts());*/
00150 
00151                 std::map<std::string, double> results;
00152                 m_paramsFunction(paramPoint.Params(), results);
00153                 paramPoint.Costs(m_costsFunction(results, targetValue));
00154                 ROS_ASSERT(paramPoint.HasCosts());
00155 
00156         }
00157 
00158         void AutoParameterExplorer::M_GetCosts(std::map<std::string, double>& targetValue, Area& area) {
00160                 /*ParameterPoint middle = area.Middle();
00161                 std::map<std::string, double> results;
00162                 m_paramsFunction(middle.Params(), results);
00163                 area.Costs(m_costsFunction(targetValue, results));*/
00164 
00165                 face_contour_detector::LimitedPriorityQueueSet<ParameterPoint, ParameterPoint::LessCosts>  queue = face_contour_detector::LimitedPriorityQueueSet<ParameterPoint, ParameterPoint::LessCosts>(1);
00166 
00167                 M_PushAllPoints(area, targetValue, queue);
00168 
00169                 area.Costs(queue.Front().Costs());
00170 
00171                 //alternatively: middle over all the costs of the edges
00172                 /*std::vector<ParameterPoint> edges;
00173                 area.EdgePoints(edges);
00174                 double sum;
00175                 std::vector<ParameterPoint>::iterator it;
00176                 for (it = edges.begin(); it != edges.end(); it++) {
00177                         M_GetCosts(*it);
00178                         sum = it-
00179                 }*/
00180         }
00181 
00182         bool AutoParameterExplorer::M_IsTargetValueInside(std::map<std::string, double>& targetValue, Area& area) {
00183 
00184                 //initialize the dimension checks
00185                 std::map<std::string, bool> foundMin;
00186                 std::map<std::string, bool> foundMax;
00187 
00188                 {
00189                         std::map<std::string, double>::iterator it;
00190                         for (it = targetValue.begin(); it != targetValue.end(); it++) {
00191                                 foundMin[it->first] = false;
00192                                 foundMax[it->first] = false;
00193                         }
00194                 }
00195 
00196                 //
00197                 std::vector<ParameterPoint> edges;
00198                 area.EdgePoints(edges);
00199                 std::vector<ParameterPoint>::iterator edgeIt;
00200                 for (edgeIt = edges.begin(); edgeIt != edges.end(); edgeIt++) {
00201                         //get result value for the point
00202                         std::map<std::string, double> result;
00203                         m_paramsFunction(edgeIt->Params(), result);
00204 
00205                         //let's go through the dimensions
00206                         std::map<std::string, double>::iterator reIt;
00207                         for (reIt = result.begin(); reIt != result.end(); reIt++) {
00208                                 if (reIt->second < targetValue[reIt->first]) {
00209                                         foundMin[reIt->first] = true;
00210                                 } else if (reIt->second > targetValue[reIt->first]) {
00211                                         foundMax[reIt->first] = true;
00212                                 } else if (reIt->second == targetValue[reIt->first]) {
00213                                         foundMax[reIt->first] = true;
00214                                         foundMin[reIt->first] = true;
00215                                 }
00216                         }
00217                 }
00218 
00219                 //check if all the dimensions were within
00220                 std::map<std::string, bool>::iterator minIt;
00221                 for (minIt = foundMin.begin(); minIt != foundMin.end(); minIt++) {
00222                         if (!(minIt->second)) return false;
00223                 }
00224 
00225                 std::map<std::string, bool>::iterator maxIt;
00226                 for (maxIt = foundMax.begin(); maxIt != foundMax.end(); maxIt++) {
00227                         if (!(maxIt->second)) return false;
00228                 }
00229                 return true;
00230 
00231         }
00232 
00233         void AutoParameterExplorer::M_PushAllPoints(Area& area, std::map<std::string, double>& targetValues, face_contour_detector::LimitedPriorityQueueSet<AutoParameterExplorer::ParameterPoint, AutoParameterExplorer::ParameterPoint::LessCosts>& results) {
00234                 std::vector<ParameterPoint> points;
00235                 area.EdgePoints(points);
00236                 points.push_back(area.Middle());
00237                 std::vector<ParameterPoint>::iterator it;
00238                 for (it = points.begin(); it != points.end(); it++) {
00239                         M_GetCosts(targetValues, *it);
00240                         results.Push(*it);
00241                 }
00242         }
00243 
00244         //Parampoint
00245 
00246         AutoParameterExplorer::ParameterPoint::ParameterPoint() : m_costsSet(false) {}
00247 
00248         AutoParameterExplorer::ParameterPoint::ParameterPoint(const ParameterPoint& other) : m_params(other.m_params), m_costsSet(other.m_costsSet), m_costs(other.m_costs) {}
00249 
00250         void AutoParameterExplorer::ParameterPoint::AddParam(double value) {
00251                 m_params.push_back(value);
00252         }
00253 
00254         AutoParameterExplorer::ParameterPoint AutoParameterExplorer::ParameterPoint::Midpoint(ParameterPoint& other) {
00255                 ROS_ASSERT(m_params.size() == other.m_params.size());
00256                 ParameterPoint re;
00257                 std::vector<double>::iterator itThis = m_params.begin();
00258                 std::vector<double>::iterator itOther = other.m_params.begin();
00259                 while (itThis != m_params.end()) {
00260 
00261                         re.AddParam( (((*itOther) - (*itThis))/2.0) +(*itThis) );
00262 
00263                         itThis++;
00264                         itOther++;
00265                 }
00266         }
00267 
00268         AutoParameterExplorer::Vector AutoParameterExplorer::ParameterPoint::VectorTo(const AutoParameterExplorer::ParameterPoint& other) {
00269 
00270                 Vector v;
00271 
00272                 std::vector<double>::const_iterator thisIt = m_params.begin();
00273                 std::vector<double>::const_iterator otherIt = other.m_params.begin();
00274 
00275                 while (thisIt != m_params.end()) {
00276 
00277                         v.AddParam((*otherIt) - (*thisIt));
00278 
00279                         thisIt++;
00280                         otherIt++;
00281                 }
00282                 ROS_ASSERT(thisIt == m_params.end());
00283                 ROS_ASSERT(otherIt == other.m_params.end());
00284 
00285                 return v;
00286         }
00287 
00288         AutoParameterExplorer::ParameterPoint AutoParameterExplorer::ParameterPoint::operator+ (const AutoParameterExplorer::Vector& vector) {
00289 
00290                 ParameterPoint p;
00291 
00292                 std::vector<double>::const_iterator thisIt = m_params.begin();
00293                 std::vector<double>::const_iterator otherIt = vector.values.begin();
00294 
00295                 while (thisIt != m_params.end()) {
00296 
00297                         p.AddParam((*otherIt) + (*thisIt));
00298 
00299                         thisIt++;
00300                         otherIt++;
00301                 }
00302                 ROS_ASSERT(thisIt == m_params.end());
00303                 ROS_ASSERT(otherIt == vector.values.end());
00304 
00305                 return p;
00306 
00307         }
00308 
00309         //Vector
00310         AutoParameterExplorer::Vector::Vector() {}
00311 
00312         AutoParameterExplorer::Vector::Vector(const Vector& other) : values(other.values) { }
00313 
00314         void AutoParameterExplorer::Vector::AddParam(double value) { values.push_back(value); }
00315 
00316         AutoParameterExplorer::Vector AutoParameterExplorer::Vector::operator+(const AutoParameterExplorer::Vector& other) {
00317                 Vector v;
00318 
00319                 std::vector<double>::const_iterator thisIt = values.begin();
00320                 std::vector<double>::const_iterator otherIt = other.values.begin();
00321 
00322                 while (thisIt != values.end()) {
00323 
00324                         v.AddParam((*otherIt) + (*thisIt));
00325 
00326                         thisIt++;
00327                         otherIt++;
00328                 }
00329                 ROS_ASSERT(thisIt == values.end());
00330                 ROS_ASSERT(otherIt == other.values.end());
00331 
00332                 return v;
00333         }
00334 
00335         AutoParameterExplorer::Vector AutoParameterExplorer::Vector::operator*(double factor) {
00336                 Vector v;
00337                 std::vector<double>::const_iterator thisIt;
00338                 for (thisIt = values.begin(); thisIt != values.end(); thisIt++) {
00339                         v.AddParam((*thisIt) * factor);
00340                 }
00341                 return v;
00342         }
00343 
00344         //Area
00345 
00346         AutoParameterExplorer::Area::Area(const AutoParameterExplorer::ParameterPoint& base) : base(base), m_hasCosts(false) {
00347 
00348         }
00349         void AutoParameterExplorer::Area::AddDimension(double value) {
00350                 dimensions.push_back(value);
00351         }
00352 
00353         AutoParameterExplorer::ParameterPoint AutoParameterExplorer::Area::Middle() {
00354                 ROS_ASSERT(dimensions.size() > 0);
00355 
00356                 ParameterPoint p;
00357                 std::vector<double>::iterator it;
00358                 Vector sumVector;
00359 
00360                 for (it = dimensions.begin(); it != dimensions.end(); it++) {
00361                         sumVector.AddParam((*it) * 0.5);
00362                 }
00363                 return base + sumVector;
00364 
00365         }
00366 
00367         void AutoParameterExplorer::Area::SubAreas(std::vector<AutoParameterExplorer::Area>& re) {
00368                 ROS_ASSERT(dimensions.size() > 0);
00369 
00370 
00371                 for (unsigned int i = 0; i < M_UIntPower2(dimensions.size()); i++) {
00372                         //callculate the base
00373                         ParameterPoint subbase;
00374                         //iterate through dimensions
00375                         std::vector<double>::iterator dimIt;
00376                         int dim = 0;
00377                         for (dimIt = dimensions.begin(); dimIt != dimensions.end(); dimIt++) {
00378                                 ROS_ASSERT(dim < 30);
00379                                 if ((i) & (1<<(dim))) {
00380                                         subbase.Params().push_back(base.Params().at(dim) + dimensions.at(dim)/2.0);
00381                                 } else {
00382                                         subbase.Params().push_back(base.Params().at(dim));
00383                                 }
00384                                 dim++;
00385                         }
00386 
00387                         Area subArea(subbase);
00388                         for (dimIt = dimensions.begin(); dimIt != dimensions.end(); dimIt++) {
00389                                 subArea.AddDimension((*dimIt)/2.0);
00390                         }
00391                         re.push_back(subArea);
00392                 }
00393 
00394         }
00395 
00396         void AutoParameterExplorer::Area::EdgePoints(std::vector<AutoParameterExplorer::ParameterPoint>& re) {
00397                 ROS_ASSERT(dimensions.size() > 0);
00398 
00399                 for (unsigned int i = 0; i < M_UIntPower2(dimensions.size()); i++) {
00400                         //callculate the edge
00401                         ParameterPoint edge;
00402                         //iterate through dimensions
00403                         std::vector<double>::iterator dimIt;
00404                         int dim = 0;
00405                         for (dimIt = dimensions.begin(); dimIt != dimensions.end(); dimIt++) {
00406                                 ROS_ASSERT(dim < 30);
00407                                 if ((i) & (1<<(dim))) {
00408                                         edge.Params().push_back(base.Params().at(dim) + dimensions.at(dim));
00409                                 } else {
00410                                         edge.Params().push_back(base.Params().at(dim));
00411                                 }
00412                                 dim++;
00413                         }
00414                         re.push_back(edge);
00415                 }
00416 
00417         }
00418 
00419         bool AutoParameterExplorer::Area::HasCosts() const {
00420                 return m_hasCosts;
00421         }
00422 
00423         void AutoParameterExplorer::Area::Costs(double costs) {
00424                 m_hasCosts = true;
00425                 m_costs = costs;
00426         }
00427 
00428         double AutoParameterExplorer::Area::Costs() const {
00429                 ROS_ASSERT(m_hasCosts);
00430                 return m_costs;
00431         }
00432 
00433         bool AutoParameterExplorer::Area::GreaterCosts::operator() (const Area& x, const Area& y) const {
00434                 return x.Costs()>y.Costs();
00435         }
00436 
00437 } //namespace face_contour_detector
00438 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends


face_contour_detector
Author(s): Fabian Wenzelmann and Julian Schmid
autogenerated on Wed Dec 26 2012 16:18:17