Generated on Tue Dec 16 13:34:01 2008 for ell-3.0.0 by doxygen 1.5.1

src/ell/LT_BarrierTree.cc

Go to the documentation of this file.
00001 
00002 #include "ell/LT_BarrierTree.hh"
00003 #include "ell/LT_SaddleNet.hh"
00004 
00005 #include <iomanip>
00006 #include <fstream>
00007 #include <sstream>
00008 #include <cmath>
00009 #include <algorithm>
00010 #include <list>
00011 #include <stack>
00012 #include <set>
00013 
00014 #include <cstring>
00015 #include <ctime>
00016     
00017 namespace ell {
00018 
00019     const std::string LT_BarrierTree::LT_ID = "BT";
00020 
00021 
00023     LT_BarrierTree::LT_BarrierTree( const double maxMergeBarrier_ )
00025      :  LT_MinimaSet()
00026         , maxMergeBarrier(maxMergeBarrier_)
00027         , root(NULL)
00028         , min2node()
00029         , numOfLeaves(0)
00030     { 
00031     }
00032 
00034     LT_BarrierTree::LT_BarrierTree( const LT_BarrierTree& toCopy )
00036     {
00037         this->operator =(toCopy);
00038     }
00039     
00040     
00042     LT_BarrierTree&
00043     LT_BarrierTree::
00044 	operator = ( const LT_MinimaSet& toCopy )
00046     {
00047           // check if toCopy is not the same object than this
00048         if (this == &toCopy) {
00049             return *this;
00050         }
00051           // check if it is a barrier tree
00052         const LT_BarrierTree* bt = dynamic_cast<const LT_BarrierTree*>(&toCopy);
00053         
00054         if (bt != NULL) {
00055             return this->operator =(*bt);
00056         } else {
00057             double oldMaxMergeBarrier = maxMergeBarrier;
00058               // clear data structure
00059             this->clear();
00060               // reset maximal merge barrier to previous value
00061             maxMergeBarrier = oldMaxMergeBarrier;
00062               // copy all minima
00063             for (size_t i=0; i<toCopy.getMinCount(); i++) {
00064                   // add minimum to tree
00065                 this->addMin(toCopy.getMin(i));
00066             }
00067               // update mfe index
00068             mfeIndex = getMinIndex(toCopy.getMFEState());
00069               // update sorted status
00070             if (!toCopy.isSorted()) {
00071                 sorted = false;
00072             }
00073         }
00074         return *this;
00075     }
00076     
00078     LT_BarrierTree&
00079     LT_BarrierTree::
00080 	operator = ( const LT_BarrierTree& toCopy )
00082     {
00083           // check if toCopy is not the same object than this
00084         if (this == &toCopy) {
00085             return *this;
00086         }
00087           // clear data structures
00088         this->clear();
00089         
00090           // copy maximal merge barrier used in the other tree
00091         maxMergeBarrier = toCopy.maxMergeBarrier;
00092         
00093           // check if the other tree contains nodes
00094         if (toCopy.root != NULL) {
00095             root = new Node(NULL,NULL,NULL,true);
00096         } else {
00097             return *this;
00098         }
00099         
00100           // copy all nodes and update vMinima list 
00101         typedef std::pair<const Node*,Node*> NP;
00102         std::list< NP > nodes;
00103         nodes.push_back(NP(toCopy.root,root));
00104         
00105         State* dummyState = toCopy.getMFEState()->clone();
00106         
00107         numOfLeaves = 0;
00108         while (!nodes.empty()) {
00109               // get next node pair to handle
00110             NP n = nodes.front();
00111             nodes.pop_front();
00112             
00113             if (n.first != NULL) {
00114                   // check if internal node
00115                 if (n.first->children != NULL) {
00116                     // push all children nodes to node stack 
00117                     const NodeList* children = n.first->children;
00118                     n.second->children = new NodeList(root, NULL);
00119                     NodeList** myChildren = &(n.second->children);
00120                     while (children != NULL) {
00121                         assertbiu(children->current != NULL, "current child of toCopy node has no link to other node (==NULL)");
00122                           // add new child to this tree
00123                         Node* child = new Node(n.second,NULL,NULL,true);
00124                         (*myChildren)->current = child;
00125                           // push to stack for later filling
00126                         nodes.push_back(NP(children->current,child));
00127                           // go to next child in the list
00128                         children = children->next;
00129                         myChildren = &((*myChildren)->next);
00130                         if (children != NULL)
00131                             *myChildren = new NodeList(root, NULL);
00132                     }
00133                     assertbiu(n.second->children != NULL , "internal node has no children after copying");
00134                       // copy all barrier states
00135                     const StateList* states = n.first->content;
00136                     n.second->content = new StateList(dummyState,NULL);
00137                     StateList* myStates = n.second->content;
00138                     while (states != NULL) {
00139                         assertbiu(states->current != NULL, "current state of toCopy node has no link to other node (==NULL)");
00140                         myStates->current = states->current->clone();
00141                           // go to next barrier
00142                         states = states->next;
00143                         myStates = myStates->next;
00144                         if (states != NULL)
00145                             myStates = new StateList(dummyState,NULL);
00146                     }
00147                     assertbiu(n.second->content != NULL || n.second->parent == NULL, "internal node has no content after copying");
00148                 } else {
00149                     // leaf node
00150                     numOfLeaves++;
00151                     
00152                       // copy all minimum states and add to vMinima list
00153                     const StateList* states = n.first->content;
00154                     n.second->content = new StateList(dummyState,NULL);
00155                     StateList* myStates = n.second->content;
00156                     while (states != NULL) {
00157                         assertbiu(states->current != NULL
00158                                 , "current state of toCopy node has no link to other node (==NULL)");
00159                           // add to list
00160                         State* s = states->current->clone();
00161                         myStates->current = s;
00162                           // add to vMinima
00163                         vMinima.push_back(s);
00164                           // update mapping
00165                         min2node[s] = n.second;
00166                           // go to next minimum in the list
00167                         states = states->next;
00168                         if (states != NULL)
00169                             myStates->next = new StateList(dummyState,NULL);
00170                         myStates = myStates->next;
00171                     }
00172                     assertbiu(n.second->content != NULL 
00173                                 , "leaf node has no content after copying");
00174                 }
00175             }
00176         }  // while (on all nodes)
00177         delete dummyState;
00178         assertbiu(numOfLeaves == toCopy.numOfLeaves
00179                         , "different number of leaves after copying");
00180         
00181           // get mfe state index
00182         mfeIndex = getMinIndex( toCopy.getMFEState() );
00183         assertbiu(mfeIndex != INVALID_INDEX
00184                         , "mfe structure not found after copying");
00185         
00186         sorted = false;
00187           // ensure sorting if origin is sorted
00188         if (toCopy.sorted) {
00189             this->sort();
00190         }
00191         
00192         return *this;
00193     }
00194 
00195 
00197     void 
00198     LT_BarrierTree::clear() 
00199     
00200     {
00201         if (root != NULL && mfeIndex != LandscapeTopology::INVALID_INDEX ) {
00202             delete root;
00203         }
00204         vMinima.clear();
00205         mfeIndex = LandscapeTopology::INVALID_INDEX;
00206         sorted = true;
00207         maxMergeBarrier = 0.0;
00208         root = NULL;
00209         min2node.clear();
00210         numOfLeaves = 0;
00211     }
00212 
00214     LT_BarrierTree::~LT_BarrierTree() {
00216         clear();
00217     }
00218 
00220     bool
00221     LT_BarrierTree::
00222 	addSaddle(const size_t i, const size_t j, const State* const s) 
00223     
00224     {
00225           // check
00226         assertbiu(i!=j, "index i and j are equal!");
00227         assertbiu(i<vMinima.size(), "index i out of vMinima range");
00228         assertbiu(j<vMinima.size(), "index j out of vMinima range");
00229         assertbiu(s->getEnergy() >= vMinima[i]->getEnergy()
00230                         , "saddle has lower energy than minimum i");
00231         assertbiu(s->getEnergy() >= vMinima[j]->getEnergy()
00232                         , "saddle has lower energy than minimum j");
00233         
00234           // get nodes of the minima
00235         Node* nm1 = min2node[ vMinima[i] ];
00236         Node* nm2 = min2node[ vMinima[j] ];
00237         
00238           // check if minima not already merged
00239         if (nm1 == nm2) {
00240             return false;
00241         }
00242         
00243           // get representive minimum of the nodes
00244         const State* m1 = nm1->content->current;
00245         const State* m2 = nm2->content->current;
00246         
00247           // m1 is the smaller 'leading' minimum of both 
00248         if (State::less(m2,m1)) {
00249             std::swap(m1,m2);
00250             std::swap(nm1,nm2);
00251         }
00252         
00253 //{
00254 //std::cerr <<"\n######  ADDING OF (" <<i <<"=" <<vMinima[i]->toString() <<", " <<j<<"=" <<vMinima[j]->toString()<<", "<<s->toString() <<") ###\n";
00255 // bool nomore = false;
00256 //for (std::map<const State*,Node*>::const_iterator it=min2node.begin();it!=min2node.end();it++) {
00257 //  std::cerr <<"## " <<getMinIndex(it->first) <<" = " <<it->first->toString() <<" --> " <<it->second;
00258 //  Node* p = it->second->parent;
00259 //  size_t i =0;
00260 //  while (p!=NULL) {
00261 //      std::cerr <<" --> " <<p;
00262 //      p = p->parent;
00263 //      if (i++ > 20) {
00264 //          nomore = true;
00265 //          break;
00266 //      }
00267 //  } std::cerr <<"\n";
00268 //}
00269 //std::cerr <<"## nm1 = " <<nm1 <<" = " <<m1->toString() <<" p=" <<nm1->parent <<" -> " <<nm1->parent->parent<<"\n";
00270 //std::cerr <<"## nm2 = " <<nm2 <<" = " <<m2->toString() <<" p=" <<nm2->parent <<" -> " <<nm2->parent->parent<<"\n";
00271 //}
00272           // get energy difference of higher minimum to saddle
00273         const double eDiff = s->getEnergy() - m2->getEnergy();
00274           // check if m2 has to be merged with m1
00275         if ( eDiff <= maxMergeBarrier) 
00276         {
00277 
00278             // move list of minima that were already merged with m2
00279             {
00280                 StateList* l = nm2->content;
00281                 while (l != NULL) {
00282                       // update node index of all minima that are merged with m2
00283                     min2node[ l->current ] = nm1;
00284                       // add all minima that are merged with m2 to m1
00285                     StateList::addToList( nm1->content, l->current );
00286                       // remove State pointer from list to avoid deletion of
00287                       // moved State
00288                     l->current = NULL;
00289                       // go to next minimum merged with m2
00290                     l = l->next;
00291                 }
00292             }
00293               // update tree structure
00294             Node* m1MergeParent = nm1;
00295             if (nm2->parent->content != NULL) {
00296 
00297                 m1MergeParent 
00298                 = getHighestParentLEQ( nm1 
00299                                 , nm2->parent->content->current->getEnergy());
00300             } else {
00301                 m1MergeParent = root;
00302             }
00303             
00304               // remove m2 from children list of m2->parent
00305             NodeList::remFromList( nm2->parent->children, nm2 );
00306             
00307               // consolidate changed tree
00308             Node* newRoot = mergeSubTrees( m1MergeParent, nm2->parent );
00309             
00310               // remove obsolete empty node nm2
00311             delete nm2;
00312               // remind the loss of a leaf
00313             numOfLeaves--;
00314             
00315               // check if new root has only one child and is therefore obsolete
00316             checkIfObsolete( newRoot );
00317             
00318               // barrier tree was changed due to minima (leave) merge
00319             return true;
00320         }
00321 
00322         
00323           // --> check if barrier is lower than already know one
00324         Node* knownBarrier = getLCA( nm1, nm2 );
00325         if (    knownBarrier->content == NULL  // in different trees of forest
00326                 || State::less( s, knownBarrier->content->current ) 
00327             )
00328         {
00329             
00330               // check if known barrier has same energy as new state
00331               // --> node barrier state has to be updated
00332             if (knownBarrier->content != NULL
00333                 && knownBarrier->content->current->getEnergy() == s->getEnergy())
00334             {
00335                   // because we are in this program part : s < knownBarrier
00336 //                // remove old barrier state
00337 //              delete knownBarrier->content->current;
00338                   // set new barrier state
00339                 knownBarrier->content->current = s->clone(knownBarrier->content->current);
00340                   // barrier was changed
00341                 return true;
00342             }
00343 
00344             // --> update barrier
00345               // get nodes to join below new barrier
00346             Node* t1 = getHighestParentLEQ( nm1, s->getEnergy());
00347             Node* t2 = getHighestParentLEQ( nm2, s->getEnergy());
00348               // get their parent nodes
00349             Node* pt1 = t1->parent;
00350             Node* pt2 = t2->parent;
00351 
00352               // pointer to newly generated node
00353             Node* newNode = NULL;
00354             
00355               // check if t1 represents already barrier height to add to tree
00356             if (t1->content->current->getEnergy() == s->getEnergy()) {
00357                   // no new node has to be added
00358                 newNode = t1;
00359                   // exchange the barrier state if the new one is smaller
00360                   // according to the order
00361                 if (State::less(s,newNode->content->current))
00362                 {
00363 //                    // remove old barrier state
00364 //                  delete newNode->content->current;
00365                       // set new barrier state
00366                     newNode->content->current = s->clone(newNode->content->current);
00367                 }
00368                 
00369             } else {
00370                   // add new internal node containing s with children t1 and t2
00371                 newNode = new Node( root
00372                                     , new NodeList(t1,NULL)
00373                                     , new StateList(s->clone(), NULL )
00374                                     );
00375             }
00376 
00377               // set new parent for t1 and t2
00378             NodeList::remFromList( pt1->children, t1 );
00379             NodeList::remFromList( pt2->children, t2 );
00380             t1->parent = newNode;
00381             t2->parent = newNode;
00382             
00383               // check second node if to join below barrier
00384             if (t2->content->current->getEnergy() 
00385                     < newNode->content->current->getEnergy()
00386                 || t2->children == NULL  ) // is leaf 
00387             {
00388                   // we add the node to the children list
00389                 NodeList::addToList( newNode->children, t2 );
00390             } else {
00391             
00392                  // t2 is internal node
00393                  // t2 is obsolete because it represents the same barrier height
00394                  // as newNode --> join both and remove t2
00395                 
00396                   // exchange the barrier state if the new one is smaller
00397                   // according to the order
00398                 if (State::less(    t2->content->current
00399                                     , newNode->content->current))
00400                 {
00401                       // remove old barrier state
00402                     delete newNode->content->current;
00403                       // set new barrier state
00404                     newNode->content->current = t2->content->current;
00405                       // remove moved barrier state to avoid recursive deletion
00406                     t2->content->current = NULL;
00407                 }
00408                     
00409                   // move all children hold by t2 into newNode
00410                 NodeList* n = t2->children;
00411                 while (n != NULL) {
00412                       // add all states that are merged with t2 to newNode
00413                     NodeList::addToList( newNode->children, n->current );
00414                       // update parent information
00415                     n->current->parent = newNode;
00416                       // remove State pointer from list to avoid deletion of moved
00417                       // State
00418                     n->current = NULL;
00419                       // go to next minimum merged with m2
00420                     n = n->next;
00421                 }
00422                 
00423                   // remove obsolete and empty t2
00424                 delete t2;
00425             }
00426             
00427             
00428               // add new node as child to lower barrier from pt1/pt2
00429             if (pt1 == pt2) { 
00430                   // same sub tree root parent --> one operation sufficient
00431                 NodeList::addToList( pt1->children, newNode );
00432                   // set parent node of newNode
00433                 newNode->parent = pt1;
00434                   // check if pt1/pt2 is obsolete due to only a single child left
00435                 pt1 = checkIfObsolete( pt1 );
00436             } else {
00437                 if (    pt1 != root
00438                         && (pt2 == root 
00439                                 || pt1->content->current->getEnergy() 
00440                                     < pt2->content->current->getEnergy() )
00441                     )
00442                 {  // pt1 is the lower of both barriers
00443                       // add newNode to pt1 children
00444                     NodeList::addToList( pt1->children, newNode );
00445                       // set parent node of newNode
00446                     newNode->parent = pt1;
00447                       // merge the trees of pt1 and pt2
00448 
00449                     Node* newRoot = mergeSubTrees( pt1, pt2 );
00450                       // check if newRoot is obsolete due to only a single child left
00451                     newRoot = checkIfObsolete( newRoot );
00452                 } else {
00453                     // pt2 is the lower of both barriers
00454                       // add newNode to pt2 children
00455                     NodeList::addToList( pt2->children, newNode );
00456                       // set parent node of newNode
00457                     newNode->parent = pt2;
00458                       // merge the trees of pt1 and pt2
00459                     Node* newRoot = mergeSubTrees( pt2, pt1 );
00460                       // check if newRoot is obsolete due to only a single child left
00461                     newRoot = checkIfObsolete( newRoot );
00462                 }
00463             }
00464 
00465               // barrier was updated
00466             return true;
00467             
00468         }
00469         
00470           // known barrier is smaller than the new one to update 
00471         return false;
00472     }
00473 
00474 
00476     bool
00477     LT_BarrierTree::
00478 	addSaddle(const State* const si, const State* const sj,const State* const s) 
00479     
00480     {
00481         
00482         bool hasChanged = false;
00483         
00484           // get index of the minimum i
00485         size_t idx_i = getMinIndex(si);
00486           // if not known add to tree
00487         if (idx_i == LandscapeTopology::INVALID_INDEX ) {
00488             idx_i = addMin(si);
00489             hasChanged = true;
00490         }
00491           // get index of the minimum j 
00492         size_t idx_j = getMinIndex(sj);
00493           // if not known add to tree
00494         if (idx_j == LandscapeTopology::INVALID_INDEX ) {
00495             idx_j = addMin(sj);
00496             hasChanged = true;
00497         }
00498         
00499           // add saddle and return if barrier tree was changed
00500         return addSaddle( idx_i, idx_j, s) || hasChanged;
00501     }
00502 
00504     const size_t 
00505     LT_BarrierTree::
00506 	addMin(const State* const s) 
00507     {
00509         assertbiu(s != NULL, "given minimum State to add is NULL");
00510         assertbiu(getMinIndex(s) == LandscapeTopology::INVALID_INDEX
00511                 , "given minimum is known and already part of the landscape");
00512 
00513           // make copy of the minimum to add
00514         State* newMin = s->clone();
00515         
00516           // add the minimum to the minima reference
00517         vMinima.push_back(newMin);
00518         
00519           // create new node to add to the tree
00520         Node* newNode = new Node( NULL, NULL, new StateList(newMin,NULL) );
00521           // update minima --> node mapping
00522         min2node[newMin] = newNode;
00523         
00524           // add node to the tree
00525         if (root == NULL) {
00526               // no tree available --> make new minimum to root
00527             root = newNode;
00528             newNode->parent = NULL;
00529         } else {
00530             if (root->content != NULL) {
00531                   // current root is a minimum or a barrier, but we have to
00532                   // create a forest with virtual root node
00533                 Node* newRoot 
00534                         = new Node(NULL, new NodeList(root,NULL), NULL, true);
00535                 root->parent = newRoot;
00536                 root = newRoot;
00537             }
00538               // add new minimum as a new barrier tree to the forest
00539             NodeList::addToList(root->children, newNode);
00540             newNode->parent = root;
00541         }
00542 
00543          // update mfeIndex if necessary
00544         if (vMinima.size() == 1) {
00545             mfeIndex = 0;
00546         } else {
00547             if (State::less( s, vMinima[mfeIndex])) {
00548                   // new energy is smaller 
00549                   // OR new energy is equal but string representation is smaller
00550                 mfeIndex = vMinima.size()-1;
00551                   // is not sorted anymore because smallest is at the end now
00552                 sorted = false;
00553             } else if (sorted) {
00554                   // compare last with newly added if the new one is not smaller
00555                 sorted = State::less( vMinima[vMinima.size()-2], s );
00556             }
00557         }
00558         
00559           // remind the newly added leaf
00560         numOfLeaves++;
00561 
00562         return vMinima.size()-1;
00563     }
00564 
00565 
00566 
00567     // calculates the distance between this and a given LT_BarrierTree
00569     double 
00570     LT_BarrierTree::
00571 	getDistance(const LandscapeTopology* const pLT ) const 
00572     {
00574         assertbiu(pLT!=NULL, "given LandscapeTopology is NULL!");
00575         
00576         const LT_BarrierTree* const bt 
00577                     = dynamic_cast<const LT_BarrierTree* const>(pLT);
00578 
00579         if ( bt == NULL ) { 
00580             // no LT_SaddleNet --> use default function
00581             return LandscapeTopology::getDistance(pLT);
00582         }
00583             
00584         double squareDeviation = 0.0;
00585         size_t numOfDeviations = 0;
00586         double minimaDistance = 0.0;
00587         size_t numOfDifferentMinima = 0;
00588         
00589 //      @TODO TESTING !!!
00592 //for (std::map<const State*,Node*>::const_iterator it=min2node.begin();it!=min2node.end();it++) {
00593 //  //std::cerr <<"## " <<getMinIndex(it->first) <<" : " <<it->first->toString() <<" --> " <<it->second <<" --> " <<it->second->parent <<" --> " <<it->second->parent->parent<<"\n";
00594 //}
00595           // set up mapping of leaves (minima) between the two barrier trees
00596         Node2Node_MAP minMap1to2;
00597         Node2Node_MAP minMap2to1;
00598           // find and mark the intersection of both minima(leave) sets
00599         std::stack<const NodeList*> childStack;
00600           // find mapping for all leaves of this barrier tree
00601         if (this->root != NULL) {
00602             childStack.push(this->root->children);
00603         }
00604         const NodeList* nextChild = NULL;
00605         while( !childStack.empty() ) {
00606             nextChild = childStack.top();
00607             if (nextChild == NULL)  {
00608                   // last of the current children list was handled
00609                 childStack.pop();
00610             } else {
00611                   // set stack top to the next in the current children list
00612                 childStack.top() = nextChild->next;
00613                 
00614                 assertbiu( nextChild->current != NULL
00615                                 , "child information has no node link");
00616                 
00617                   // check children of current node
00618                 if (nextChild->current->children != NULL) {
00619                       // internal node found
00620                     childStack.push( nextChild->current->children );
00621                 } else {
00622                       // leaf found
00623                       // check if one of the minima of this leaf are present in
00624                       // the other barrier tree
00625                     StateList* s = nextChild->current->content;
00626                     while( s != NULL ) {
00627                           // check if the current minimum of the leaf is element
00628                           // of the other tree
00629                         size_t to = bt->getMinIndex(s->current);
00630                           // store leave/minima mapping
00631                         if (to != INVALID_INDEX) {
00632                               // get corresponding leaf
00633                             const Node* toNode = bt->min2node.find(
00634                                                     bt->vMinima[to])->second;
00635                               // update mapping
00636                             minMap1to2[nextChild->current] = toNode;
00637                             minMap2to1[toNode] = nextChild->current;
00638                               // found mapping --> leave minima loop
00639                             break;
00640                         }
00641                           // go to next minimum of this leaf
00642                         s = s->next;
00643                     }
00644                     if (minMap1to2.find(nextChild->current) != minMap1to2.end())
00645                     { // still not present in m2 --> handle missing minimum 
00646                         numOfDifferentMinima++;
00647                         minimaDistance += MISSING_MINIMUM_PENALTY 
00648                                 * exp( -(nextChild->current->content
00649                                             ->current->getEnergy())
00650                                         / BOLTZMANN_KT );
00651                     }
00652                 }
00653             }
00654         }
00655           // find mapping for all leaves of the other barrier tree
00656         if (bt->root != NULL) {
00657             childStack.push(bt->root->children);
00658         }
00659         while( !childStack.empty() ) {
00660             nextChild = childStack.top();
00661             if (nextChild == NULL)  {
00662                   // last of the current children list was handled
00663                 childStack.pop();
00664             } else {
00665                   // set stack top to the next in the current children list
00666                 childStack.top() = nextChild->next;
00667                 
00668                   // check children of current node
00669                 if (nextChild->current->children != NULL) {
00670                       // internal node found
00671                     childStack.push( nextChild->current->children );
00672                 } else {
00673                       // leaf found --> check if already mapped
00674                     if (minMap2to1.find(nextChild->current) != minMap2to1.end()) 
00675                     { 
00676                           // check if one of the minima of this leaf are present
00677                           // in the other barrier tree
00678                         StateList* s = nextChild->current->content;
00679                         while( s != NULL ) 
00680                         {
00681                               // check if the current minimum of the leaf is element
00682                               // of the other tree
00683                             size_t to = this->getMinIndex(s->current);
00684                               // store leave/minima mapping
00685                             if (to != INVALID_INDEX) {
00686                                   // get corresponding leaf
00687                                 const Node* toNode = this->min2node.find(
00688                                                     this->vMinima[to])->second;
00689                                   // update mapping
00690                                 minMap2to1[nextChild->current] = toNode;
00691                                   // found mapping --> leave minima loop
00692                                 break;
00693                             }
00694                               // go to next minimum of this leaf
00695                             s = s->next;
00696                         }
00697                     }
00698                     if (minMap2to1.find(nextChild->current) != minMap2to1.end()) 
00699                     { // still not present in m1 --> handle missing leaf 
00700                         numOfDifferentMinima++;
00701                         minimaDistance += MISSING_MINIMUM_PENALTY 
00702                                 * exp( -(nextChild->current->content
00703                                             ->current->getEnergy())
00704                                         / BOLTZMANN_KT );
00705                     }
00706                 }
00707             }
00708         }
00709         
00710           // normalize minima distance
00711         minimaDistance /= (double)numOfDifferentMinima;
00712 
00713         // calculate barrier square deviation
00714         
00715         // --> get maximal barrier height maxDelta of this and the other tree
00716         // this value will be used if a barrier in one of the trees is missing
00717         double maxBarrierHeight = 0.0;
00718         {
00719             // NOTE: only ensuringing highest barrier if this is no forest ...
00720             
00721               // get max barrier height of this tree
00722             Node* mfeRoot = this->min2node.find(this->getMFEState())->second;
00723             while( mfeRoot->parent != NULL && mfeRoot->parent->content != NULL ) {
00724                 mfeRoot = mfeRoot->parent;
00725             }
00726             if (mfeRoot->content != NULL) { // mfe is no single tree in forest
00727                 maxBarrierHeight = mfeRoot->content->current->getEnergy()
00728                                     - this->getMFEState()->getEnergy();
00729             }
00730               // get max barrier height of the other tree
00731             mfeRoot = bt->min2node.find(bt->getMFEState())->second;
00732             while( mfeRoot->parent != NULL && mfeRoot->parent->content != NULL ) {
00733                 mfeRoot = mfeRoot->parent;
00734             }
00735             if (mfeRoot->content != NULL) { // mfe is no single tree in forest
00736                   // check if this barrier height is higher than of this tree
00737                 maxBarrierHeight = std::max( maxBarrierHeight 
00738                                         , mfeRoot->content->current->getEnergy()
00739                                             - bt->getMFEState()->getEnergy());
00740             }
00741         }
00742           // calculate square value
00743         maxBarrierHeight *= maxBarrierHeight;
00744         
00745         // --> calculate square deviations of all barriers between minima leaves
00746         //     that are present in both trees
00747           // needed to know if a minimum leaf is unique in the second tree
00748         std::set<const Node*> mappedFrom1;
00749           // check all barriers present in this tree
00750         typedef Node2Node_MAP::const_iterator MapIter;
00751         for (MapIter from=minMap1to2.begin(); from != minMap1to2.end(); from++) 
00752         {
00753               // store that this node was reached from this tree
00754             mappedFrom1.insert(from->second);
00755               // calc barriers to all other leaves
00756             for (MapIter to = from; ++to != minMap1to2.end(); ) 
00757             {
00758                   // calculate barrier
00759                 const Node* lca1 = this->getLCA(from->first, to->first);
00760                 const Node* lca2 = bt->getLCA(from->second, to->second);
00761                 if (lca1->content != NULL && lca2->content != NULL) {
00762                     // there exists a barrier in both trees 
00763                     // --> calculate square deviation
00764                       // get barrier height of 'from' node in this tree 
00765                     double bDiff = from->first->content->current->getEnergy()
00766                                     - lca1->content->current->getEnergy();
00767                       // substract barrier height of 'from' node in the other tree 
00768                     bDiff -= from->second->content->current->getEnergy()
00769                                 - lca2->content->current->getEnergy();
00770                       // calculate square deviation and store
00771                     squareDeviation += (bDiff * bDiff);
00772                 } else
00773                 if (    (lca1->content != NULL && lca2->content == NULL)
00774                         || (lca1->content == NULL && lca2->content != NULL) ) 
00775                 {
00776                     // a MISSING BARRIER found --> increase deviation
00777                     squareDeviation += maxBarrierHeight;
00778 //              } else {
00779                   // both are in different trees in the forest 
00780                   // --> therefore no barrier difference and no squareDeviation
00781                 }
00782                   // count that we have handled a barrier
00783                 numOfDeviations++;
00784             }
00785         }
00786           // check all remaining barriers present in the other tree ONLY
00787         for (MapIter from=minMap2to1.begin(); from != minMap2to1.end(); from++) 
00788         {
00789               // check if this leaf was already mapped
00790             if (mappedFrom1.find(from->first) != mappedFrom1.end()) {
00791                 continue;
00792             }
00793               // calc barriers to all other leaves
00794             for (MapIter to = minMap2to1.begin(); to != minMap2to1.end(); to++) 
00795             {
00796                   // check if this is the source and thus to skip
00797                 if (to->first == from->first) {
00798                     continue;
00799                 }
00800                 
00801                   // calculate barrier
00802                 const Node* lca2 = bt->getLCA(from->first, to->first);
00803                 const Node* lca1 = this->getLCA(from->second, to->second);
00804                 if (lca1->content != NULL && lca2->content != NULL) {
00805                     // there exists a barrier in both trees 
00806                     // --> calculate square deviation
00807                       // get barrier height of 'from' node in this tree 
00808                     double bDiff = from->first->content->current->getEnergy()
00809                                     - lca1->content->current->getEnergy();
00810                       // substract barrier height of 'from' node in the other tree 
00811                     bDiff -= from->second->content->current->getEnergy()
00812                                 - lca2->content->current->getEnergy();
00813                       // calculate square deviation and store
00814                     squareDeviation += (bDiff * bDiff);
00815                 } else
00816                 if (    (lca1->content != NULL && lca2->content == NULL)
00817                         || (lca1->content == NULL && lca2->content != NULL)) 
00818                 {
00819                     // a MISSING BARRIER found --> increase deviation
00820                     squareDeviation += maxBarrierHeight;
00821 //              } else {
00822                   // both are in different trees in the forest
00823                   // --> therefore no barrier difference and no squareDeviation
00824                 }
00825                   // count that we have added a barrier
00826                 numOfDeviations++;
00827             }
00828         }
00829         
00830         
00831           // nothing was matched etc --> use minima distance only
00832         if (numOfDeviations == 0) {
00833             return minimaDistance;
00834         }
00835           // calculate distance via barrier RMSD and minima distance
00836         return minimaDistance
00837                 + sqrt( squareDeviation / (double)numOfDeviations );
00838     }
00839 
00840 
00842     std::pair<int,std::string>
00843     LT_BarrierTree::read(   std::istream & in, 
00844                         const State * const templateState )
00846     {
00847 
00848         typedef std::pair<int,std::string> RETURNTYPE;
00849         State* s;
00850         
00851           // stores the mapping of the minima indices in the file to the indices
00852           // used in the barrier tree to add the barriers
00853         Int2SizeT_MAP idx2min;
00854         
00855         std::string line;
00856         std::stringstream sstr;
00857         
00858         bool headerParsed = false;
00859         size_t dim = 0;
00860         size_t lineNumber = 0;
00861         
00862         std::string::size_type i;
00863         
00867 
00868         while( std::getline(in, line) ) {
00869             ++lineNumber;
00870             s = NULL;
00871             
00873             if(line.find("GRAPHVIZ") != std::string::npos) {
00874                 break;
00875             }
00876             
00878               // check if next line describes the header information
00880             i = line.find(OUTPUT_KEY_ELL_HEAD);
00881             if(i != std::string::npos) {
00882                 
00883                 std::string lt_id("");
00884                 dim = 0;
00885                 std::string stateDescr("");
00886                 
00887                   // parse the minimum
00888                 RETURNTYPE ret 
00889                     = LandscapeTopology::parseHeader(   line.substr(i), 
00890                                                         lt_id,
00891                                                         dim,
00892                                                         stateDescr );
00893                   // check for parsing errors
00894                 if (ret.first != 0) {
00895                     sstr.clear();
00896                     sstr <<"line " <<lineNumber
00897                         <<" : "<<ret.second;
00898                     return RETURNTYPE(ret.first,sstr.str());
00899                 }
00900                   // check for semantical errors
00901                 if ( lt_id.compare(LT_MinimaSet::LT_ID) != 0 
00902                      && lt_id.compare(LT_BarrierTree::LT_ID) != 0
00903                      && lt_id.compare(LT_SaddleNet::LT_ID) != 0) 
00904                 {
00905                     return RETURNTYPE(-1,"ELL-LT-TYPE not supported");
00906                 }
00907                 if (stateDescr.compare(templateState->getID()) != 0 ) {
00908                     return RETURNTYPE(-2,"STATETYPE differs from given type");
00909                 } 
00910                 headerParsed = true;
00911             }
00912             
00914               // check if next line describes a minimum
00916             i = line.find(OUTPUT_KEY_MINIMUM);
00917             if(i != std::string::npos) {
00918                   // check if header already parsed
00919                 if (!headerParsed) {
00920                     sstr.clear();
00921                     sstr <<"line " <<lineNumber
00922                         <<" : minimum present but no header found so far";
00923                     return RETURNTYPE(-2,sstr.str());
00924                 }
00925                 
00926                   // count the new found minimum
00927                 if (dim == 0) {
00928                     return RETURNTYPE(-3,"MORE minima present than given via DIMENSION");
00929                 }
00930                 dim--;
00931                 
00932                   // parse the minimum
00933                 RETURNTYPE ret 
00934                     = LandscapeTopology::parseMinimum(  *this, 
00935                                                         line.substr(i), 
00936                                                         templateState, 
00937                                                         idx2min );
00938                 
00939                   // check for parsing errors
00940                 if (ret.first != 0) {
00941                     sstr.clear();
00942                     sstr <<"line " <<lineNumber
00943                         <<" : "<<ret.second;
00944                     return RETURNTYPE(ret.first,sstr.str());
00945                 }
00946                   // check for minima merged with the added one
00947                 if (ret.second.size() > 0) {
00948                       // get leaf node of last minimum added
00949                     Node* lastAddedNode = min2node[vMinima[vMinima.size()-1]];
00950                       // parse remaining minima
00951                     size_t start = ret.second.find_first_not_of(' ',0);
00952                     while (start < ret.second.size()) {
00953                           // get end of encoding
00954                         size_t end = ret.second.find_first_of(' ',start);
00955                         State* subMin = templateState->fromString(ret.second.substr(start,end-start));
00956                         assertbiu(subMin != NULL, "minimum parsing failed");
00957                           // add min to minima list of last added node
00958                         StateList::addToList( lastAddedNode->content, subMin);
00959                           // add min to global minima list
00960                         vMinima.push_back(subMin);
00961                         min2node[subMin] = lastAddedNode;
00962                           // go to next minimum encoding
00963                         start = ret.second.find_first_not_of(' ',end);
00964                     }
00965                 }
00966             } 
00967             
00969               // check if next line describes a barrier
00971             i = line.find(OUTPUT_KEY_BARRIER);
00972             if(i != std::string::npos) {
00973                   // check if header already parsed
00974                 if (!headerParsed) {
00975                     sstr.clear();
00976                     sstr <<"line " <<lineNumber
00977                         <<" : barrier present but no header found so far";
00978                     return RETURNTYPE(-2,sstr.str());
00979                 }
00980                 
00981                   // parse the barrier
00982                 RETURNTYPE ret 
00983                     = LandscapeTopology::parseBarrier(  *this, 
00984                                                         line.substr(i), 
00985                                                         templateState, 
00986                                                         idx2min );
00987                 
00988                   // check for parsing errors
00989                 if (ret.first != 0) {
00990                     sstr.clear();
00991                     sstr <<"line " <<lineNumber
00992                         <<" : "<<ret.second;
00993                     return RETURNTYPE(ret.first,sstr.str());
00994                 }
00995             } 
00996             
00998               // check if next line describes a saddle
01000             i = line.find(OUTPUT_KEY_SADDLE);
01001             if(i != std::string::npos) {
01002                   // check if header already parsed
01003                 if (!headerParsed) {
01004                     sstr.clear();
01005                     sstr <<"line " <<lineNumber
01006                         <<" : saddle present but no header found so far";
01007                     return RETURNTYPE(-2,sstr.str());
01008                 }
01009                 
01010                   // parse the saddle
01011                 RETURNTYPE ret 
01012                     = LandscapeTopology::parseSaddle(   *this, 
01013                                                         line.substr(i), 
01014                                                         templateState, 
01015                                                         idx2min );
01016                 
01017                   // check for parsing errors
01018                 if (ret.first != 0) {
01019                     sstr.clear();
01020                     sstr <<"line " <<lineNumber
01021                         <<" : "<<ret.second;
01022                     return RETURNTYPE(ret.first,sstr.str());
01023                 }
01024             } 
01025 
01026               // garbage collection
01027             if (s != NULL) {
01028                 delete s;
01029                 s = NULL;
01030             }
01031             
01032         }
01033 
01034         if (dim > 0) {
01035             return RETURNTYPE(-3,"LESS minima present than given via DIMENSION");
01036         }
01037         
01038         return RETURNTYPE(0,"");
01039     }
01040     
01042     void
01043     LT_BarrierTree::
01044 	write( std::ostream& out, 
01045             const bool writeGraph ) const
01047     {
01048         const size_t dim = numOfLeaves;
01049 
01052 
01053         const std::string dummyID = "ell::State";
01054         LandscapeTopology::writeHeader(out, LT_ID, dim, (vMinima.size()==0?dummyID:vMinima[0]->getID()));
01055 
01057 
01058           // print barriers
01059         Node2Node_MAP node2firstLeaf;
01060         Node2SizeT_MAP node2idx;
01061         SizeT2Node_MAP idx2node;
01062         size_t internalNodeCount = dim-1;
01063         size_t leafNodeCount = 0;
01064         for (size_t i=0; i<vMinima.size(); i++) {
01065             Node* cur = min2node.find(vMinima[i])->second;
01066               // check if leaf was already handled
01067             if (node2idx.find(cur) != node2idx.end()) {
01068                 continue;
01069             }
01070               // label node
01071             node2idx[cur] = leafNodeCount;
01072             idx2node[leafNodeCount] = cur;
01073               // print smallest minimum stored in this leaf
01074             if (cur->content->next == NULL) {
01075                 LandscapeTopology::writeMinimum( out, cur->content->current, leafNodeCount );
01076             } else {
01077                 std::vector<const State*> minima;
01078                 const StateList* next = cur->content;
01079                 while (next != NULL) {
01080                     minima.push_back(next->current);
01081                     next = next->next;
01082                 }
01083                 LandscapeTopology::writeMinimum( out, minima, leafNodeCount );
01084             }
01085               // increase node counter
01086             leafNodeCount++;
01087               // prepare parent recursion
01088             node2firstLeaf[cur] = cur;
01089             bool nextRecursion = true;
01090             while( nextRecursion && cur->parent != NULL ) {
01091                 if (node2idx.find(cur->parent)==node2idx.end()) {
01092                     internalNodeCount++;
01093                     node2idx[cur->parent] = internalNodeCount;
01094                     idx2node[internalNodeCount] = cur->parent;
01095                     node2firstLeaf[cur->parent] = node2firstLeaf[cur];
01096                 } else {
01097                       // have found a known internal node 
01098                       // --> no recursion needed
01099                     nextRecursion = false;
01100                 }
01101                   // go recursive a level up in the tree
01102                 cur = cur->parent;
01103             }
01104         }
01105         assertbiu(numOfLeaves==leafNodeCount, "not all leaves printed");
01106           // vector that holds the minima connected by a barrier
01107         std::vector<size_t> minConnected;
01108           // write barriers to stream
01109         for (SizeT2Node_MAP::iterator it = idx2node.begin();
01110             it != idx2node.end(); it++)
01111         {
01112 
01113               // check if internal node and no virtual root of a forest
01114             if (it->second->children != NULL && it->second->content != NULL) {
01115                   // reset minima collector
01116                 minConnected.clear();
01117                   // collect connected minima
01118                 NodeList* children = it->second->children;
01119                 while (children != NULL) {
01120                     minConnected.push_back(
01121                             node2idx[ node2firstLeaf[ children->current ] ] );
01122                     children = children->next;
01123                 }
01124                 
01125                   // write barrier to stream
01126                 LandscapeTopology::
01127 					writeBarrier(  out,
01128                                     it->second->content->current,
01129                                     it->first,
01130                                     minConnected );
01131             }
01132         }
01133     
01134         if (writeGraph) {
01135         
01136             out << "\n" << "//GRAPHVIZ"<<"\n";
01137             
01139             out << "digraph BARRIERTREE {"<<"\n";
01140             for (size_t i = 0; i < dim; ++i) {
01141                 out << "\t\tM"<<i<<";\n";
01142             }
01143             
01144               // print internal barrier nodes and edges
01145             for (SizeT2Node_MAP::iterator it = idx2node.begin();
01146                 it != idx2node.end(); it++)
01147             {
01148                 if (it->second == root) {
01149                     out << "\t\tB"<<node2idx[root]<<"; /* root */\n";
01150                 }
01151                   // check if internal node and no virtual root of a forest
01152                 if (it->second->children != NULL && it->second->content != NULL) {
01153                       // print barrier index
01154                     // print connected minima
01155                     NodeList* children = it->second->children;
01156                     while (children != NULL) {
01157                         size_t curIdx = node2idx[children->current];
01158                         out << "\t\tB"<<it->first<<" -> "
01159                             <<(curIdx<dim?"M":"B")<<curIdx<<";\n";
01160                         children = children->next;
01161                     }
01162                 }
01163             }
01164             
01165             out << "label = \"\\n\\nLT_BarrierTree Diagram\\nwith "<<dim
01166                 <<" minima \";\n"
01167                 << "fontsize=20;\n"
01168                 << "}\n";
01169         }
01170         
01171           // flush the output stream
01172         out.flush();
01173         
01174     }
01175     
01177     LT_BarrierTree::
01178     Node*
01179     LT_BarrierTree::
01180 	getHighestParentLEQ( Node* child, const double maxEnergy )
01182     {
01183         assertbiu( child != NULL, "starting node is NULL" );
01184         
01185         Node* ret = child;
01186         
01187           // find (grand)parent node of child that is either root or internal 
01188           // node with energy below or equal to threshold 
01189         while(  ret != root
01190                 && ret->parent->content != NULL
01191                 && ret->parent->content->current->getEnergy() <= maxEnergy ) 
01192         {
01193             ret = ret->parent;
01194         }
01195         
01196         return ret;
01197     }
01198     
01200     const 
01201     LT_BarrierTree::
01202     Node*
01203     LT_BarrierTree::
01204 	getHighestParentLEQ( const Node* child, const double maxEnergy ) const
01206     {
01207         assertbiu( child != NULL, "starting node is NULL" );
01208         
01209         const Node* ret = child;
01210         
01211           // find (grand)parent node of child that is either root or internal 
01212           // node with energy below or equal to threshold 
01213         while(  ret != root
01214                 && ret->parent->content != NULL
01215                 && ret->parent->content->current->getEnergy() <= maxEnergy ) 
01216         {
01217             ret = ret->parent;
01218         }
01219         
01220         return ret;
01221     }
01222     
01224     LT_BarrierTree::
01225     Node*
01226     LT_BarrierTree::
01227 	mergeSubTrees( Node* ta, Node* tb )
01229     {
01230         if (ta == tb) {
01231             return ta;
01232         }
01233           // check if merge is needed
01234         if (    ta->content != NULL
01235                 && tb->content != NULL
01236                 && ta->content->current->getEnergy() 
01237                     == tb->content->current->getEnergy() )
01238         {
01239               // t1 has lower energy than t2
01240             Node* t1 = ta;
01241             Node* t2 = tb;
01242             // same barrier height --> merge nodes
01243               // --> ensure that (t1->current < t2->current)
01244             if (State::less(t2->content->current, t1->content->current)) {
01245                 t1 = tb;
01246                 t2 = ta;
01247             }
01248               // --> merge t2 into t1
01249             assertbiu(t2->children != NULL, "t2 is no internal node");
01250               // list of nodes that are children of t2 --> move to t1
01251             {
01252                 NodeList*& n = t2->children;
01253                 while( n != NULL ) {
01254                       // add all minima that are merged with t2 to t1
01255                     NodeList::addToList( t1->children, n->current );
01256                       // update parent information of new children
01257                     n->current->parent = t1;
01258                       // remove node pointer from list to avoid deletion of
01259                       // moved nodes
01260                     n->current = NULL;
01261                       // go to next minimum merged with t2
01262                     n = n->next;
01263                 }
01264             }
01265             
01266               // --> remove t2 from t2->parent->children
01267             NodeList::remFromList( t2->parent->children, t2 );
01268               // store t2 parent information
01269             Node* pt2 = t2->parent;
01270               // --> delete t2
01271             delete t2;
01272               // --> return merge of t1->parent an t2->parent
01273             return mergeSubTrees(t1->parent,pt2);
01274         }
01275 
01276           // check if nodes are not obsolete
01277         if (ta->children != NULL) {
01278             ta = checkIfObsolete(ta);
01279         }
01280         if (tb->children != NULL) {
01281             tb = checkIfObsolete(tb);
01282         }
01283         
01284           // check if no more merge neccessary
01285         if (ta == tb || ta == tb->parent || ta == root) {
01286             return ta;
01287         } 
01288         if (tb == ta->parent || tb == root) {
01289             return tb;
01290         }
01291         
01292           // t1 has lower energy than t2
01293         Node* t1 = ta;
01294         Node* t2 = tb;
01295         if (    t1->content->current->getEnergy() 
01296                 > t2->content->current->getEnergy() ) 
01297         {
01298             t1 = tb;
01299             t2 = ta;
01300         }
01301         
01302           // store old parents
01303         Node* pt1 = t1->parent;
01304         Node* pt2 = t2->parent;
01305         
01306           // check if t1 has a parent that is still below t2
01307         if (    pt1->content != NULL 
01308                 && State::less(pt1->content->current, t2->content->current)) 
01309         {
01310               // merge parent of t1 with t2
01311             return mergeSubTrees( pt1, t2);
01312         }
01313         
01314           // --> insert t2 between t1 and t2->parent
01315         NodeList::remFromList( pt1->children, t1 );
01316         NodeList::addToList( t2->children, t1 );
01317         t1->parent = t2;
01318         NodeList::addToList( pt1->children, t2 );
01319         t2->parent = pt1;
01320           // --> remove t2 from t2->parent->children
01321         NodeList::remFromList( pt2->children, t2 );
01322         
01323           // recursive call with new joint subtrees
01324         return mergeSubTrees( pt2, pt1 );
01325     }
01326     
01327 
01329     const 
01330     LT_BarrierTree::
01331     Node*
01332     LT_BarrierTree::
01333 	getLCA( const Node* n1, const Node* n2 ) const 
01335     {
01336           // simple checks for LCA
01337         if (n1 == n2 )
01338             return n1;
01339         if (n1->parent == n2->parent)
01340             return n1->parent;
01341         
01342         const Node* lca = root;
01343         
01344           // path from n1/n2 to root node
01345         std::list<const Node*> p1, p2;
01346         
01347           // find path to root from n1
01348         p1.push_back(n1);
01349         while( (*(p1.rbegin())) != root ) {
01350             p1.push_back((*(p1.rbegin()))->parent);
01351         }
01352           // find path to root from n2
01353         p2.push_back(n2);
01354         while( (*(p2.rbegin())) != root ) {
01355             p2.push_back((*(p2.rbegin()))->parent);
01356         }
01357         
01358         std::list<const Node*>::const_reverse_iterator i1 = p1.rbegin();
01359         std::list<const Node*>::const_reverse_iterator i2 = p2.rbegin();
01360         
01361         while(*i1 == *i2) {
01362             lca = *i1;
01363             i1++;
01364             i2++;
01365         }
01366         
01367         return lca;
01368     }
01369     
01371     LT_BarrierTree::
01372     Node*
01373     LT_BarrierTree::
01374 	getLCA( Node* n1, Node* n2 ) 
01375     
01376     {
01377           // simple checks for LCA
01378         if (n1 == n2 )
01379             return n1;
01380         if (n1->parent == n2->parent)
01381             return n1->parent;
01382         Node* lca = root;
01383         
01384           // path from n1/n2 to root node
01385         std::list<Node*> p1, p2;
01386         
01387           // find path to root from n1
01388         p1.push_back(n1);
01389         while( (*(p1.rbegin())) != root ) {
01390             p1.push_back((*(p1.rbegin()))->parent);
01391         }
01392           // find path to root from n2
01393         p2.push_back(n2);
01394         while( (*(p2.rbegin())) != root ) {
01395             p2.push_back((*(p2.rbegin()))->parent);
01396         }
01397         
01398         std::list<Node*>::const_reverse_iterator i1 = p1.rbegin();
01399         std::list<Node*>::const_reverse_iterator i2 = p2.rbegin();
01400         
01401         while(*i1 == *i2) {
01402             lca = *i1;
01403             i1++;
01404             i2++;
01405         }
01406         
01407         return lca;
01408     }
01409     
01410     
01412     const State*
01413     LT_BarrierTree::
01414 	getBarrier( const size_t m1, const size_t m2 ) const 
01416     {
01417         assertbiu(m1 < vMinima.size(), "m1 index out of range (vMinima)");
01418         assertbiu(m2 < vMinima.size(), "m2 index out of range (vMinima)");
01419         
01420           // get LCA node
01421         const Node* lca = getLCA(   min2node.find(vMinima[m1])->second
01422                                     , min2node.find(vMinima[m2])->second );
01423         
01424           // get barrier state or NULL if in non-connected trees of a forest
01425         return lca->content->current;
01426     }
01427     
01428     
01430     const State*
01431     LT_BarrierTree::
01432 	getBarrier( const State* const m1, const State* const m2 ) const 
01434     {
01435         const size_t im1 = getMinIndex(m1);
01436         const size_t im2 = getMinIndex(m2);
01437         
01438         assertbiu(im1 != INVALID_INDEX, "m1 is not part of the topology");
01439         assertbiu(im2 != INVALID_INDEX, "m2 is not part of the topology");
01440 
01441           // calculate barrier
01442         return getBarrier( im1, im2 );
01443     }
01444     
01446     LT_BarrierTree::
01447     Node*
01448     LT_BarrierTree::
01449 	checkIfObsolete( Node* n )
01451     {
01452 //std::cerr <<"###### CHECK IF OBSOLETE ( " <<n <<" )";
01453         assertbiu( n->children != NULL, "node n has no children (NULL)");
01454         assertbiu( n->children->current != NULL, "node n has no valid children (current==NULL)");
01455 
01456           // return value
01457         Node* finalRoot = n;
01458         
01459           // check if only one child present
01460         if (n->children->next == NULL) {
01461             if (n == root) {
01462                   // set root a level lower
01463                 root = n->children->current;
01464                   // update parent information of the new root node
01465                 root->parent = NULL;
01466                   // set final root
01467                 finalRoot =  root;
01468             } else {
01469                   // remove n from parents children list
01470                 NodeList::remFromList(n->parent->children, n);
01471                   // add the only child of n to parents children list
01472                 NodeList::addToList(    n->parent->children
01473                                         , n->children->current);
01474                   // update parent of child of n
01475                 n->children->current->parent = n->parent;
01476                   // set final root
01477                 finalRoot = n->parent;
01478             }
01479               // erase connection of n to tree
01480             n->children->current = NULL;
01481               // delete newRoot
01482             delete n;
01483 //std::cerr <<" = TRUE\n";
01484         } else {
01485 //std::cerr <<" = false\n";
01486         }
01487         
01488         return finalRoot;
01489     }
01490     
01491 
01493     bool
01494     LT_BarrierTree::
01495 	isForest( void ) const
01497     {
01498         return (root!=NULL) && (root->content == NULL);
01499     }
01500 
01501     
01502 
01504     size_t
01505     LT_BarrierTree::
01506 	getNumOfTrees( void ) const
01508     {
01509         size_t trees = 0;
01510         
01511           // check if forest
01512         if (root->content == NULL) {
01513             NodeList* child = root->children;
01514             while (child != NULL) {
01515                 trees++;
01516                 child = child->next;
01517             }
01518         } else {
01519             trees = 1;
01520         }
01521         
01522         return trees;
01523         return (root!=NULL) && (root->content == NULL);
01524     }
01525 
01526     
01528     size_t
01529     LT_BarrierTree::
01530 	getNumOfLeaves( void ) const
01532     {
01533         assertbiu(numOfLeaves <= vMinima.size(), "there is an inconsistency : more leaves than minima present");
01534         
01535         return numOfLeaves;
01536     }
01537 
01538     
01540     void 
01541     LT_BarrierTree::
01542 	write_PStree( std::ostream& out, const size_t maxLeaves2print) 
01543     
01544     {
01545         if(this->isForest()) {
01546 #ifdef DEBUG
01547             std::cerr << "SORRY : this is a forest which is currently not supported for PStree .. ";
01548 #endif
01549             return;
01550         }
01551         
01552           // sort minima
01553         this->sort();
01554           // get maximal number of leaves to print
01555         const size_t max_print = std::min( maxLeaves2print, numOfLeaves);
01556         
01557         std::vector<LT_BarrierTree::nodeT> nodes(max_print);
01558 
01559           // all leaves are attracted by the mfe of the tree
01560         
01561         Node2Int_MAP node2idx;
01562 
01563         int curMin = 0;
01564         for( int addedMin=0; addedMin < (int)max_print; addedMin++ ) {
01565             
01566               // go to next minimum that represents a leaf
01567             while (min2node[vMinima[curMin]]->content->current != vMinima[curMin]) {
01568                 curMin++;
01569             }
01570 
01571             {
01572                 Node* node = min2node[vMinima[curMin]];
01573                 while (node != NULL && node2idx.find(node)==node2idx.end()) {
01574                     node2idx[node] = addedMin;
01575                     node = node->parent;
01576                 }
01577             }
01578             
01579             register int f;
01580             
01581             Node* parent = min2node[vMinima[curMin]]->parent;
01582             assertbiu(parent->content != NULL && parent->content->current != NULL, "is a forest");
01583             double E_saddle = parent->content->current->getEnergy();
01584             
01585             assertbiu(node2idx.find(parent) != node2idx.end(), "father not found");
01586             f = node2idx[parent];
01587 
01588             nodes[addedMin].father = (f==addedMin)?-1:f;
01589             
01590             nodes[addedMin].height = vMinima[curMin]->getEnergy();
01591             nodes[addedMin].saddle_height = E_saddle;
01592             
01593 //          if (print_labels) {
01594 //              char *L;
01595 //              char *s;
01596 //              s = unpack_my_structure(Lmin[ii].structure);
01597 //              if ((POV_size)&&(Lmin[ii].global)) {
01598 //                  L = (char *) space(sizeof(char)*(3+strlen(s)));
01599 //                  strcat(L,s); strcat(L," *");
01600 //                  nodes[s1-1].label = L;
01601 //              }
01602 //              else
01603 //                  nodes[s1-1].label = strdup(s);
01604 //              free(s);
01605 //          }
01606             nodes[addedMin].label = NULL;
01607             curMin++;
01608         }
01609         
01610 //std::cerr<<"\n max_print = "<<max_print <<"\n";       
01611 //for (size_t x=0; x<max_print; x++) {
01612 //  std::cerr <<" node " <<x <<" ( h=" ;
01613 //  std::cerr <<nodes[x].height; 
01614 //  std::cerr <<" s=" ;
01615 //  std::cerr <<nodes[x].saddle_height; 
01616 //  std::cerr <<" f="; 
01617 //  std::cerr <<nodes[x].father <<" )\n";
01618 //}
01619 //std::cerr<<"\n";      
01620         
01621         PS_tree_plot( out, nodes);
01622     }
01623 
01625 
01626 
01627     void
01628     LT_BarrierTree::
01629     PS_tree_plot(   std::ostream& out
01630                     , const std::vector<nodeT> &nodes
01631                     ) 
01632     {
01633 
01634         /* plot tree with leaf-nodes nodes, to file filename (stdout if NULL) */
01635         int i, k, ll, f=0;
01636         linkT *chain, *l;
01637         int bbox[4] = {72, 144, 522, 700};
01638         const int n = (int)nodes.size();
01639 
01640         
01641         /* make index list, sorted by saddle height */
01642         std::vector<int> sindex(n,0);
01643         for (i=0; i<n; i++) sindex[i]=i;
01644         cmp_saddle compare(&nodes);
01645         std::sort(sindex.begin(), sindex.end(), compare);
01646         
01647         /* make order (x-coordinates) of leaves, we use a linked list for this */
01648         chain = new linkT[n];
01649         /* start connecting the links of the chain */
01650         for (i=0; i<n; i++) { /* n-1 merges */
01651             k = sindex[i]; 
01652             f = nodes.at(k).father; /* ith saddle merges k and f */
01653             if (f==-1) f=0;
01654             if (k==f) continue;  /* lowest node doesn't merge */
01655             for (l= &chain[f]; l->next!=NULL; l = l->next); 
01656             l->next=&chain[k]; /* attach child to chain of father */
01657         }
01658         /* chain[f] now starts the ordered chain, next fill in the num field */
01659         for (i=0, l= &chain[f]; l!=NULL; l = l->next) 
01660             l->x = i++;
01661         
01662           // get current time
01663         time_t rawtime;
01664         struct tm * timeinfo;
01665         time ( &rawtime );
01666         timeinfo = localtime ( &rawtime );
01667         
01668         out <<
01669         "%!PS-Adobe-2.0 EPSF-1.2\n"
01670         "%Title: TreePlot\n"
01671         "%Creator: ell::LT_BarrierTree.cc\n"
01672         "%CreationDate: "
01673         <<asctime(timeinfo);
01674         out<<"%%BoundingBox: "
01675         <<bbox[0]<<" " << bbox[1] <<" " << bbox[2] <<" " << bbox[3] <<"\n";
01676         out <<
01677         "%%EndComments\n"
01678         "%%BeginProlog\n"
01679         "/treedict 100 dict def\n"
01680         "treedict begin\n"
01681         "% x y  => min(x,y)\n"
01682         "  /min { 2 copy gt { exch } if pop } bind def\n"
01683         "  /max { 2 copy lt { exch } if pop } bind def\n"
01684         "  /cmtx matrix currentmatrix def\n"
01685         "  /STR 128 string def\n"
01686         "  /NumH 1 def\n"
01687         "% - => -\n"
01688         "  /Init {\n"
01689         "    /LX [\n"
01690         "      LEAF {0 get} forall\n"
01691         "    ] def\n\n"
01692         "    /Helvetica findfont fsize scalefont setfont\n"
01693         "    /Lo [\n"
01694         "      (X) stringwidth pop % width\n"
01695         "      newpath 0 0 moveto\n"
01696         "      (X) true charpath\n"
01697         "      flattenpath pathbbox\n"
01698         "      pop exch pop exch sub neg 2 div % height\n"
01699         "     ] def\n"
01700         "  } def\n"
01701         "% - => -\n"
01702         "  /DrawScale {\n"
01703         "  gsave \n"
01704         "    maxy miny sub 30 div dup maxy add /maxy exch def miny sub /miny def\n"
01705         "    maxy miny sub log 0.9 sub floor 10 exch exp /tick exch def\n"
01706         "    newpath\n"
01707         "    LEAF length 0.5 sub 0 translate 0 miny moveto 0 maxy miny sub rlineto\n"
01708         "    miny tick div ceiling tick mul dup 0 exch moveto \n"
01709         "    maxy exch sub tick div cvi 1 add dup { % draw minor ticks\n"
01710         "      0.15 0 rlineto\n"
01711         "      -0.15 tick rmoveto\n"
01712         "    } repeat\n"
01713         "    % calculate major tick spacing (10, 5, or 2 minor ticks)\n"
01714         "    dup 69 gt { pop 10\n"
01715         "    } {\n"
01716         "      32 gt { 5 }\n"
01717         "      {2} ifelse\n"
01718         "    } ifelse\n"
01719         "    tick mul /mtick exch def\n"
01720         "    miny mtick div ceiling mtick mul dup 0 exch moveto\n"
01721         "    maxy exch sub mtick div cvi 1 add {\n"
01722         "      0.3 0 rlineto \n"
01723         "      gsave currentpoint 10 mul round 10 div cmtx setmatrix\n"
01724         "      STR cvs dup stringwidth pop\n"
01725         "      Lo aload pop 3 1 roll add neg exch rmoveto show pop\n"
01726         "      grestore\n"
01727         "      -0.3 mtick rmoveto\n"
01728         "    } repeat\n"
01729         "    cmtx setmatrix stroke    \n"
01730         "  grestore\n"
01731         "  } def\n"
01732         "% - => -\n"
01733         "  /SetBarFont {\n"
01734         "    matrix currentmatrix cmtx setmatrix\n"
01735         "    /Helvetica findfont fbsize scalefont setfont\n"
01736         "    setmatrix\n"
01737         "  } bind def\n"
01738         "% - => -\n"
01739         "  /SetLabelFont {\n"
01740         "    matrix currentmatrix cmtx setmatrix\n"
01741         "    /Courier findfont fsize scalefont setfont\n"
01742         "    setmatrix\n"
01743         "  } bind def\n"
01744         "% str => -\n"
01745         "  /Rotshow {\n"
01746         "    gsave\n"
01747         "      cmtx setmatrix -90 rotate\n"
01748         "      Lo aload pop\n"
01749         "      rmoveto show\n"
01750         "    grestore\n"
01751         "  } def\n"
01752         "% dy => - \n"
01753         "  /Rlineto {\n"
01754         "    dup abs MinHeight ge { % draw height at middle of line\n"
01755         "      dup gsave\n"
01756         "   dup 2 div 0 exch rmoveto\n"
01757         "   cmtx setmatrix -90 rotate\n"
01758         "   abs STR cvs dup stringwidth pop 2 div neg\n"
01759         "   //NumH rmoveto\n"
01760         "   show\n"
01761         "      grestore\n"
01762         "    } if\n"
01763         "    0 exch rlineto\n"
01764         "  } def\n"
01765         "% - => -\n"
01766         "  /Drawlabels {\n"
01767         "   0 LEAF {\n"
01768         "      aload pop moveto\n"
01769         "      dup LABEL exch get STR cvs Rotshow\n"
01770         "      1 add\n"
01771         "    } forall pop\n"
01772         "  } def\n"
01773         "% n => n'    Detect whether a minimum is connected\n"
01774         "  /MRX {\n"
01775         "     /murxi { true } def\n"
01776         "     dup 0 lt { pop 0 /murxi { false } def } if\n"
01777         "  } def\n"    
01778         "% - => -\n"
01779         "  /Connectlmins {\n"
01780         "    newpath\n"
01781         "    SADDEL {\n"
01782         "      /forest {false} def  %  draw as tree or forest node\n"
01783         "      aload pop exch dup 0 lt { pop 0 /forest {true} def} if"
01784         "   % => c h f\n"
01785         "      dup LX exch get [ exch LX 5 index get add 2 div "
01786         "% => c h f [ nx\n"
01787         "      3 index ]\t\t\t\t         % => c h f [ nx h ]\n"
01788         "      3 -1 roll dup LEAF 6 -1 roll get aload pop "
01789         "% => f [nx h] h h cx cy\n"
01790         "      dup 3 1 roll moveto\t\t         % => f [] h h cy\n"
01791         "      sub Rlineto                                % => f [] h\n"
01792         "      LEAF 3 index get aload pop exch\t\t % => f [] h fy fx\n"
01793         "      2 index forest {moveto} {lineto} ifelse \n"
01794         "      sub neg Rlineto\t\t\t         % => f [] h fy\n"
01795         "      LEAF 3 1 roll put\n"
01796         "    } forall\n"
01797         "    gsave\n"
01798         "      cmtx setmatrix stroke\n"
01799         "    grestore\n"
01800         "  } def\n"
01801         "% data starts here!!!\n"
01802         "  /LABEL [";
01803 
01804         /* print label array */
01805         if(nodes.at(0).label==NULL) 
01806             ll = 8;
01807         else 
01808             ll = 3+strlen(nodes.at(0).label);
01809         if(ll<8) 
01810             ll = 8;
01811         ll = (int) (80/ll);
01812         for (i=0; i<n; i++) {
01813             if (i%ll == 0)  
01814                 out << "\n   ";
01815             if (nodes.at(i).label) 
01816                 out << "(" << nodes.at(i).label <<") ";
01817             else
01818                 out <<std::setw(3) <<(i+1) <<" ";
01819         }
01820         out <<"\n  ] def\n";
01821 
01822         /* print leaf node coordinates */
01823         out <<"% leaf node coordinates\n"
01824             <<"  /LEAF [";
01825         for (i=0; i<n; i++) {
01826             if (i%5 == 0)  out<< "\n   ";
01827             out<< "["<<std::setw(3)<<(chain[i].x)<<" "<<std::setw(10)<<std::fixed<<std::setprecision(3)<<nodes.at(i).height<<"] ";
01828         }
01829         out<< "  \n] def\n";
01830 
01831         /* print internal node coordinates */
01832         out<< "% internal nodes (saddle) coordinates, sorted by height\n"
01833         "  /SADDEL [";
01834         for (i=0; i<n; i++) {
01835             if (i%4 == 0)  out<< "\n   ";
01836             k=sindex[i]; 
01837             if (k==nodes.at(k).father) 
01838                 continue;
01839             int fath = std::max(nodes.at(k).father,0);
01840             out<< "["<<std::setw(3)<<k <<" " <<std::setw(3)<<fath <<" "<<std::setw(10)<<std::fixed<<std::setprecision(3)<<nodes.at(k).saddle_height <<"] ";
01841         }
01842         delete chain;
01843         out <<
01844         "  \n] def\n"
01845         "end\n";
01846         out <<
01847         "%%EndProlog\n"
01848         "treedict begin\n"
01849         "  /fsize 10 def\n"
01850         "  /fbsize 7 def\n"
01851         "  Init\n"
01852         "  "<<(bbox[2]-1)<<" "<<bbox[1]<<" fsize 1.5 mul add translate\n";
01853         out<< "  "<<bbox[0]<<" "<<(bbox[2]-1)<<" sub LEAF length div % x-scale\n";
01854         out<< "  "<<(bbox[3]-1)<<" "<<bbox[1]<<" fsize dup add add sub\n";
01855         out<<
01856         "  SADDEL dup length 1 sub get 2 get /maxy exch def % max height\n"
01857         "  9999999 LEAF { aload pop exch pop min } forall\n"
01858         "  /miny exch def % min height\n"
01859         /* "  LEAF 0 get 1 get /miny exch def % min height\n" */
01860         "  maxy miny sub dup 20 div /MinHeight exch def\n"
01861         "  div scale\n"
01862         "  .5 LEAF 0 get 1 get neg translate\n"
01863         "  SetLabelFont\n"
01864         "  Drawlabels\n"
01865         "  DrawScale\n"
01866         "  SetBarFont\n"
01867         "  Connectlmins\n"
01868         "  showpage\n"
01869         "end\n"
01870         "%%EOF\n";
01871 
01872           // reset static pointer
01873     }
01874 
01875     bool
01876     LT_BarrierTree::cmp_saddle::operator()(int A, int B) 
01877     {
01878         assertbiu(leaves != NULL, "leaves variable not set");
01879         float diff = leaves->at(A).saddle_height - leaves->at(B).saddle_height;
01880         if (diff < -1e-6) 
01881             return true;
01882         else if (diff>1e-6) 
01883             return false;
01884         diff = leaves->at(A).height - leaves->at(B).height;
01885         return (diff<0)?true:false;
01886     }
01887       
01889 
01890 }