optimizable_graph.cpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, H. Strasdat, W. Burgard
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "optimizable_graph.h"
00018 
00019 #include <cassert>
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <fstream>
00023 #include <algorithm>
00024 
00025 #include "estimate_propagator.h"
00026 #include "factory.h"
00027 #include "solver_property.h"
00028 #include "hyper_graph_action.h"
00029 
00030 #include "g2o/stuff/macros.h"
00031 #include "g2o/stuff/color_macros.h"
00032 #include "g2o/stuff/string_tools.h"
00033 #include "g2o/stuff/misc.h"
00034 
00035 namespace g2o {
00036 
00037   using namespace std;
00038 
00039   OptimizableGraph::Vertex::Vertex() :
00040     HyperGraph::Vertex(),
00041     _graph(0), _userData(0), _tempIndex(-1), _fixed(false), _marginalized(false),
00042     _colInHessian(-1)
00043   {
00044 
00045   }
00046 
00047   OptimizableGraph::Vertex::~Vertex()
00048   {
00049     delete _userData;
00050   }
00051   
00052   OptimizableGraph::Vertex* OptimizableGraph::Vertex::clone() const
00053   {
00054     // TODO
00055     return 0;
00056   }
00057 
00058   bool OptimizableGraph::Vertex::setEstimateData(const double *)
00059   {
00060     return false;
00061   }
00062 
00063   bool OptimizableGraph::Vertex::getEstimateData(double *) const
00064   {
00065     return false;
00066   }
00067 
00068   int OptimizableGraph::Vertex::estimateDimension() const
00069   {
00070     return -1;
00071   }
00072 
00073   bool OptimizableGraph::Vertex::setMinimalEstimateData(const double *)
00074   {
00075     return false;
00076   }
00077 
00078   bool OptimizableGraph::Vertex::getMinimalEstimateData(double *) const
00079   {
00080     return false;
00081   }
00082 
00083   int OptimizableGraph::Vertex::minimalEstimateDimension() const
00084   {
00085     return -1;
00086   }
00087 
00088 
00089   OptimizableGraph::Edge::Edge() :
00090     HyperGraph::Edge(),
00091     _dimension(-1), _level(0), _robustKernel(false), _huberWidth(1.)
00092   {
00093   }
00094 
00095   bool OptimizableGraph::Edge::setMeasurementData(const double *)
00096   {
00097     return false;
00098   }
00099 
00100   bool OptimizableGraph::Edge::getMeasurementData(double *) const
00101   {
00102     return false;
00103   }
00104 
00105   int OptimizableGraph::Edge::measurementDimension() const
00106   {
00107     return -1;
00108   }
00109 
00110   bool OptimizableGraph::Edge::setMeasurementFromState(){
00111     return false;
00112   }
00113 
00114 
00115   OptimizableGraph::Edge* OptimizableGraph::Edge::clone() const
00116   {
00117     // TODO
00118     return 0;
00119   }
00120 
00121   OptimizableGraph::OptimizableGraph()
00122   {
00123     _upperGraph=0; _lowerGraph=0; _nextEdgeId = 0; _edge_has_id = false;
00124     _graphActions.resize(AT_NUM_ELEMENTS);
00125   }
00126 
00127   OptimizableGraph::~OptimizableGraph()
00128   {
00129     clear();
00130   }
00131 
00132   bool OptimizableGraph::addVertex(Vertex* v, Data* userData)
00133   {
00134     Vertex* inserted = vertex(v->id());
00135     if (inserted)
00136       return false;
00137     if (userData)
00138       v->setUserData(userData);
00139     HyperGraph::addVertex(v);
00140     OptimizableGraph::Vertex* ov=dynamic_cast<OptimizableGraph::Vertex*>(v);
00141     assert(ov);
00142     ov->_graph=this;
00143     return true;
00144   }
00145 
00146   bool OptimizableGraph::addEdge(OptimizableGraph::Edge* e)
00147   {
00148     OptimizableGraph::Edge* eresult = dynamic_cast<OptimizableGraph::Edge*>(HyperGraph::addEdge(e));
00149     if (! eresult)
00150       return false;
00151     e->_internalId = _nextEdgeId++;
00152     return true;
00153   }
00154 
00155   int OptimizableGraph::optimize(int /*iterations*/, bool /*online*/) {return 0;}
00156 
00157 double OptimizableGraph::chi2() const
00158 {
00159   double chi = 0.0;
00160   for (OptimizableGraph::EdgeSet::const_iterator it = this->edges().begin(); it != this->edges().end(); it++) {
00161     const OptimizableGraph::Edge* e = static_cast<const OptimizableGraph::Edge*>(*it);
00162     chi += e->chi2();
00163   }
00164   return chi;
00165 }
00166 
00167 void OptimizableGraph::push()
00168 {
00169   for (OptimizableGraph::VertexIDMap::iterator it=_vertices.begin(); it!=_vertices.end(); it++) {
00170     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(it->second);
00171     v->push();
00172   }
00173 }
00174 
00175 void OptimizableGraph::pop()
00176 {
00177   for (OptimizableGraph::VertexIDMap::iterator it=_vertices.begin(); it!=_vertices.end(); it++) {
00178     OptimizableGraph::Vertex* v= static_cast<OptimizableGraph::Vertex*>(it->second);
00179     v->pop();
00180   }
00181 }
00182 
00183 void OptimizableGraph::discardTop()
00184 {
00185   for (OptimizableGraph::VertexIDMap::iterator it=_vertices.begin(); it!=_vertices.end(); it++) {
00186     OptimizableGraph::Vertex* v= static_cast<OptimizableGraph::Vertex*>(it->second);
00187     v->discardTop();
00188   }
00189 }
00190 
00191 void OptimizableGraph::push(HyperGraph::VertexSet& vset)
00192 {
00193   for (HyperGraph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00194     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00195     v->push();
00196   }
00197 }
00198 
00199 void OptimizableGraph::pop(HyperGraph::VertexSet& vset)
00200 {
00201   for (HyperGraph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00202     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00203     v->pop();
00204   }
00205 }
00206 
00207 void OptimizableGraph::discardTop(HyperGraph::VertexSet& vset)
00208 {
00209   for (HyperGraph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00210     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00211     v->discardTop();
00212   }
00213 }
00214 
00215   void OptimizableGraph::setFixed(HyperGraph::VertexSet& vset, bool fixed)
00216 {
00217   for (HyperGraph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00218     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00219     v->setFixed(fixed);
00220   }
00221 }
00222 
00223 
00224 bool OptimizableGraph::load(istream& is, bool createEdges)
00225 {
00226   set<string> warnedUnknownTypes;
00227   stringstream currentLine;
00228   string token;
00229 
00230   Factory* factory = Factory::instance();
00231 
00232   while (1) {
00233     int bytesRead = readLine(is, currentLine);
00234     if (bytesRead == -1)
00235       break;
00236     currentLine >> token;
00237     if (bytesRead == 0 || token.size() == 0 || token[0] == '#')
00238       continue;
00239      
00240     // do the mapping to an internal type if it matches
00241     if (_renamedTypesLookup.size() > 0) {
00242       map<string, string>::const_iterator foundIt = _renamedTypesLookup.find(token);
00243       if (foundIt != _renamedTypesLookup.end()) {
00244         token = foundIt->second;
00245       }
00246     }
00247 
00248     HyperGraph::HyperGraphElement* element = factory->construct(token);
00249 
00250     if (! element) {
00251       if (warnedUnknownTypes.count(token) != 1) {
00252         warnedUnknownTypes.insert(token);
00253         cerr << CL_RED(__PRETTY_FUNCTION__ << " unknown type: " << token) << endl;
00254       }
00255       continue;
00256     }
00257 
00258     if (dynamic_cast<Vertex*>(element)) { // it's a vertex type
00259       Vertex* v = static_cast<Vertex*>(element);
00260       int id;
00261       currentLine >> id;
00262       bool r = v->read(currentLine);
00263       if (! r)
00264         cerr << __PRETTY_FUNCTION__ << ": Error reading vertex " << token << " " << id << endl;
00265       v->setId(id);
00266       if (!addVertex(v)) {
00267         cerr << __PRETTY_FUNCTION__ << ": Failure adding Vertex, " << token << " " << id << endl;
00268         delete v;
00269       }
00270     }
00271     else if (dynamic_cast<Edge*>(element)) {
00272       Edge* e = static_cast<Edge*>(element);
00273       int numV = e->vertices().size();
00274       if (_edge_has_id){
00275         int id;
00276         currentLine >> id;
00277         e->setId(id);
00278       }
00279       //cerr << PVAR(token) << " " << PVAR(numV) << endl;
00280       if (numV == 2) { // it's a pairwise / binary edge type which we handle in a special way
00281         int id1, id2;
00282         currentLine >> id1 >> id2;
00283         Vertex* from = vertex(id1);
00284         Vertex* to = vertex(id2);
00285         int doInit=0;
00286         if ((!from || !to) ) {
00287           if (! createEdges) {
00288             cerr << __PRETTY_FUNCTION__ << ": Unable to find vertices for edge " << token << " " << id1 << " <-> " << id2 << endl;
00289             delete e;
00290           } else {
00291             if (! from) {
00292               from=e->createFrom();
00293               from->setId(id1);
00294               addVertex(from);
00295               doInit=2;
00296             }
00297             if (! to) {
00298               to=e->createTo();
00299               to->setId(id2);
00300               addVertex(to);
00301               doInit=1;
00302             }
00303           }
00304         }
00305         if (from && to) {
00306           e->read(currentLine);
00307           e->vertices()[0] = from;
00308           e->vertices()[1] = to;
00309           if (!addEdge(e)) {
00310             cerr << __PRETTY_FUNCTION__ << ": Unable to add edge " << token << " " << id1 << " <-> " << id2 << endl;
00311             delete e;
00312           } else {
00313             switch (doInit){
00314               case 1: 
00315                 {
00316                   HyperGraph::VertexSet fromSet;
00317                   fromSet.insert(from);
00318                   e->initialEstimate(fromSet, to);
00319                   break;
00320                 }
00321               case 2:
00322                 {
00323                   HyperGraph::VertexSet toSet;
00324                   toSet.insert(to);
00325                   e->initialEstimate(toSet, from);
00326                   break;
00327                 }
00328               default:;
00329             }
00330           }
00331         }
00332       }
00333       else {
00334         vector<int> ids;
00335         ids.resize(numV);
00336         for (int l = 0; l < numV; ++l)
00337           currentLine >> ids[l];
00338         bool vertsOkay = true;
00339         for (int l = 0; l < numV; ++l) {
00340           e->vertices()[l] = vertex(ids[l]);
00341           if (e->vertices()[l] == 0) {
00342             vertsOkay = false;
00343             break;
00344           }
00345         }
00346         if (! vertsOkay) {
00347           cerr << __PRETTY_FUNCTION__ << ": Unable to find vertices for edge " << token;
00348           for (int l = 0; l < numV; ++l) {
00349             if (l > 0)
00350               cerr << " <->";
00351             cerr << " " << ids[l];
00352           }
00353           delete e;
00354         } else {
00355           bool r = e->read(currentLine);
00356           if (!r || !addEdge(e)) {
00357             cerr << __PRETTY_FUNCTION__ << ": Unable to add edge " << token; 
00358             for (int l = 0; l < numV; ++l) {
00359               if (l > 0)
00360                 cerr << " <->";
00361               cerr << " " << ids[l];
00362             }
00363             delete e;
00364           }
00365         }
00366 
00367       }
00368 
00369     }
00370 
00371   } // while read line
00372   
00373   return true;
00374 }
00375 
00376 bool OptimizableGraph::load(const char* filename, bool createEdges)
00377 {
00378   ifstream ifs(filename);
00379   if (!ifs) {
00380     cerr << __PRETTY_FUNCTION__ << " unable to open file " << filename << endl;
00381     return false;
00382   }
00383   return load(ifs, createEdges);
00384 }
00385 
00386 bool OptimizableGraph::save(const char* filename, int level) const
00387 {
00388   ofstream ofs(filename);
00389   if (!ofs)
00390     return false;
00391   return save(ofs, level);
00392 }
00393 
00394 bool OptimizableGraph::save(ostream& os, int level) const
00395 {
00396   Factory* factory = Factory::instance();
00397 
00398   set<Vertex*, VertexIDCompare> verticesToSave;
00399   for (HyperGraph::EdgeSet::const_iterator it = edges().begin(); it != edges().end(); ++it) {
00400     OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
00401     if (e->level() == level) {
00402       for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00403         verticesToSave.insert(static_cast<OptimizableGraph::Vertex*>(*it));
00404       }
00405     }
00406   }
00407 
00408   for (set<Vertex*, VertexIDCompare>::const_iterator it = verticesToSave.begin(); it != verticesToSave.end(); ++it){
00409     OptimizableGraph::Vertex* v = *it;
00410     string tag = factory->tag(v);
00411     if (tag.size() > 0) {
00412       os << tag << " " << v->id() << " ";
00413       v->write(os);
00414       os << endl;
00415     }
00416   }
00417 
00418   EdgeContainer edgesToSave;
00419   for (HyperGraph::EdgeSet::const_iterator it = edges().begin(); it != edges().end(); ++it) {
00420     const OptimizableGraph::Edge* e = dynamic_cast<const OptimizableGraph::Edge*>(*it);
00421     if (e->level() == level)
00422       edgesToSave.push_back(const_cast<Edge*>(e));
00423   }
00424   sort(edgesToSave.begin(), edgesToSave.end(), EdgeIDCompare());
00425 
00426   for (EdgeContainer::const_iterator it = edgesToSave.begin(); it != edgesToSave.end(); ++it) {
00427     OptimizableGraph::Edge* e = *it;
00428     string tag = factory->tag(e);
00429     if (tag.size() > 0) {
00430       os << tag << " ";
00431       if (_edge_has_id)
00432         os << e->id() << " ";
00433       for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00434         OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00435         os << v->id() << " ";
00436       }
00437       e->write(os);
00438       os << endl;
00439     }
00440   }
00441 
00442   return os.good();
00443 }
00444 
00445 
00446 bool OptimizableGraph::saveSubset(ostream& os, HyperGraph::VertexSet& vset, int level)
00447 {
00448   Factory* factory = Factory::instance();
00449 
00450   for (HyperGraph::VertexSet::const_iterator it=vset.begin(); it!=vset.end(); it++){
00451     OptimizableGraph::Vertex* v = dynamic_cast<OptimizableGraph::Vertex*>(*it);
00452     string tag = factory->tag(const_cast<OptimizableGraph::Vertex*>(v));
00453     if (tag.size() > 0) {
00454       os << tag << " " << v->id() << " ";
00455       v->write(os);
00456       os << endl;
00457     }
00458   }
00459   for (HyperGraph::EdgeSet::const_iterator it = edges().begin(); it != edges().end(); ++it) {
00460     OptimizableGraph::Edge* e = dynamic_cast< OptimizableGraph::Edge*>(*it);
00461     if (e->level() != level)
00462       continue;
00463 
00464     bool verticesInEdge = true;
00465     for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00466       if (vset.find(*it) == vset.end()) {
00467         verticesInEdge = false;
00468         break;
00469       }
00470     }
00471     if (! verticesInEdge)
00472       continue;
00473 
00474     string tag = factory->tag(const_cast<OptimizableGraph::Edge*>(e));
00475     if (tag.size() > 0) {
00476       os << tag << " ";
00477       if (_edge_has_id)
00478         os << e->id() << " ";
00479       for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00480         OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00481         os << v->id() << " ";
00482       }
00483       e->write(os);
00484       os << endl;
00485     }
00486 
00487   }
00488 
00489   return os.good();
00490 }
00491 
00492 bool OptimizableGraph::saveSubset(ostream& os, HyperGraph::EdgeSet& eset)
00493 {
00494   Factory* factory = Factory::instance();
00495 
00496   std::set<OptimizableGraph::Vertex*> vset;
00497   for (HyperGraph::EdgeSet::const_iterator it = eset.begin(); it != eset.end(); ++it) {
00498     HyperGraph::Edge* e = *it;
00499     for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00500       OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00501       vset.insert(v);
00502     }
00503   }
00504 
00505   for (std::set<OptimizableGraph::Vertex*>::const_iterator it=vset.begin(); it!=vset.end(); ++it){
00506     OptimizableGraph::Vertex* v = dynamic_cast<OptimizableGraph::Vertex*>(*it);
00507     string tag = factory->tag(const_cast<OptimizableGraph::Vertex*>(v));
00508     if (tag.size() > 0) {
00509       os << tag << " " << v->id() << " ";
00510       v->write(os);
00511       os << endl;
00512     }
00513   }
00514 
00515   for (HyperGraph::EdgeSet::const_iterator it = eset.begin(); it != eset.end(); ++it) {
00516     OptimizableGraph::Edge* e = dynamic_cast< OptimizableGraph::Edge*>(*it);
00517     string tag = factory->tag(const_cast<OptimizableGraph::Edge*>(e));
00518     if (tag.size() == 0)
00519       continue;
00520 
00521     bool verticesInEdge = true;
00522     for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00523       OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00524       if (vset.find(v) == vset.end()) {
00525         verticesInEdge = false;
00526         break;
00527       }
00528     }
00529     if (! verticesInEdge)
00530       continue;
00531 
00532     os << tag << " ";
00533     for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00534       OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00535       os << v->id() << " ";
00536     }
00537     e->write(os);
00538     os << endl;
00539   }
00540 
00541   return os.good();
00542 }
00543   
00544 void OptimizableGraph::addGraph(OptimizableGraph* g){
00545   for (HyperGraph::VertexIDMap::iterator it=g->vertices().begin(); it!=g->vertices().end(); it++){
00546     OptimizableGraph::Vertex* v= (OptimizableGraph::Vertex*)(it->second);
00547     if (vertex(v->id()))
00548       continue;
00549     OptimizableGraph::Vertex* v2=v->clone();
00550     v2->edges().clear();
00551     v2->setTempIndex(-1);
00552     addVertex(v2);
00553   }
00554   for (HyperGraph::EdgeSet::iterator it=g->edges().begin(); it!=g->edges().end(); it++){
00555     OptimizableGraph::Edge* e = (OptimizableGraph::Edge*)(*it);
00556     OptimizableGraph::Edge* en = e->clone();
00557     en->resize(e->vertices().size());
00558     int cnt = 0;
00559     for (vector<HyperGraph::Vertex*>::const_iterator it = e->vertices().begin(); it != e->vertices().end(); ++it) {
00560       OptimizableGraph::Vertex* v = (OptimizableGraph::Vertex*) vertex((*it)->id());
00561       assert(v);
00562       en->vertices()[cnt++] = v;
00563     }
00564     addEdge(en);
00565   }
00566 }
00567 
00568 int OptimizableGraph::maxDimension() const{
00569   int maxDim=0;
00570   for (HyperGraph::VertexIDMap::const_iterator it=vertices().begin(); it!=vertices().end(); it++){
00571     const OptimizableGraph::Vertex* v= static_cast< const OptimizableGraph::Vertex*>(it->second);
00572     maxDim = std::max(maxDim, v->dimension());
00573   }
00574   return maxDim;
00575 }
00576 
00577 void OptimizableGraph::setRenamedTypesFromString(const std::string& types)
00578 {
00579   Factory* factory = Factory::instance();
00580   vector<string> typesMap = strSplit(types, ",");
00581   for (size_t i = 0; i < typesMap.size(); ++i) {
00582     vector<string> m = strSplit(typesMap[i], "=");
00583     if (m.size() != 2) {
00584       cerr << __PRETTY_FUNCTION__ << ": unable to extract type map from " << typesMap[i] << endl;
00585       continue;
00586     }
00587     string typeInFile = trim(m[0]);
00588     string loadedType = trim(m[1]);
00589     if (! factory->knowsTag(loadedType)) {
00590       cerr << __PRETTY_FUNCTION__ << ": unknown type " << loadedType << endl;
00591       continue;
00592     }
00593 
00594     _renamedTypesLookup[typeInFile] = loadedType;
00595   }
00596 
00597   cerr << "# load look up table" << endl;
00598   for (std::map<std::string, std::string>::const_iterator it = _renamedTypesLookup.begin(); it != _renamedTypesLookup.end(); ++it) {
00599     cerr << "#\t" << it->first << " -> " << it->second << endl;
00600   }
00601 }
00602 
00603 bool OptimizableGraph::isSolverSuitable(const SolverProperty& solverProperty, const std::set<int>& vertDims_) const
00604 {
00605   std::set<int> auxDims;
00606   if (vertDims_.size() == 0) {
00607     auxDims = dimensions();
00608   }
00609   const set<int>& vertDims = vertDims_.size() == 0 ? auxDims : vertDims_;
00610   bool suitableSolver = true;
00611   if (vertDims.size() == 2) {
00612     if (solverProperty.requiresMarginalize) {
00613       suitableSolver = vertDims.count(solverProperty.poseDim) == 1 && vertDims.count(solverProperty.landmarkDim) == 1;
00614     }
00615     else {
00616       suitableSolver = solverProperty.poseDim == -1;
00617     }
00618   } else if (vertDims.size() == 1) {
00619     suitableSolver = vertDims.count(solverProperty.poseDim) == 1 || solverProperty.poseDim == -1;
00620   } else {
00621     suitableSolver = solverProperty.poseDim == -1 && !solverProperty.requiresMarginalize;
00622   }
00623   return suitableSolver;
00624 }
00625 
00626 std::set<int> OptimizableGraph::dimensions() const
00627 {
00628   std::set<int> auxDims;
00629   for (VertexIDMap::const_iterator it = vertices().begin(); it != vertices().end(); ++it) {
00630     OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(it->second);
00631     auxDims.insert(v->dimension());
00632   }
00633   return auxDims;
00634 }
00635 
00636 void OptimizableGraph::preIteration(int iter)
00637 {
00638   HyperGraphActionSet& actions = _graphActions[AT_PREITERATION];
00639   if (actions.size() > 0) {
00640     HyperGraphAction::ParametersIteration params(iter);
00641     for (HyperGraphActionSet::iterator it = actions.begin(); it != actions.end(); ++it) {
00642       (*(*it))(this, &params);
00643     }
00644   }
00645 }
00646 
00647 void OptimizableGraph::postIteration(int iter)
00648 {
00649   HyperGraphActionSet& actions = _graphActions[AT_POSTITERATION];
00650   if (actions.size() > 0) {
00651     HyperGraphAction::ParametersIteration params(iter);
00652     for (HyperGraphActionSet::iterator it = actions.begin(); it != actions.end(); ++it) {
00653       (*(*it))(this, &params);
00654     }
00655   }
00656 }
00657 
00658 bool OptimizableGraph::addPostIterationAction(HyperGraphAction* action)
00659 {
00660   std::pair<HyperGraphActionSet::iterator, bool> insertResult = _graphActions[AT_POSTITERATION].insert(action);
00661   return insertResult.second;
00662 }
00663 
00664 bool OptimizableGraph::addPreIterationAction(HyperGraphAction* action)
00665 {
00666   std::pair<HyperGraphActionSet::iterator, bool> insertResult = _graphActions[AT_PREITERATION].insert(action);
00667   return insertResult.second;
00668 }
00669 
00670 bool OptimizableGraph::removePreIterationAction(HyperGraphAction* action)
00671 {
00672   return _graphActions[AT_PREITERATION].erase(action) > 0;
00673 }
00674 
00675 bool OptimizableGraph::removePostIterationAction(HyperGraphAction* action)
00676 {
00677   return _graphActions[AT_POSTITERATION].erase(action) > 0;
00678 }
00679 
00680 } // end namespace


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:02