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
00048 if (this == &toCopy) {
00049 return *this;
00050 }
00051
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
00059 this->clear();
00060
00061 maxMergeBarrier = oldMaxMergeBarrier;
00062
00063 for (size_t i=0; i<toCopy.getMinCount(); i++) {
00064
00065 this->addMin(toCopy.getMin(i));
00066 }
00067
00068 mfeIndex = getMinIndex(toCopy.getMFEState());
00069
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
00084 if (this == &toCopy) {
00085 return *this;
00086 }
00087
00088 this->clear();
00089
00090
00091 maxMergeBarrier = toCopy.maxMergeBarrier;
00092
00093
00094 if (toCopy.root != NULL) {
00095 root = new Node(NULL,NULL,NULL,true);
00096 } else {
00097 return *this;
00098 }
00099
00100
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
00110 NP n = nodes.front();
00111 nodes.pop_front();
00112
00113 if (n.first != NULL) {
00114
00115 if (n.first->children != NULL) {
00116
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
00123 Node* child = new Node(n.second,NULL,NULL,true);
00124 (*myChildren)->current = child;
00125
00126 nodes.push_back(NP(children->current,child));
00127
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
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
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
00150 numOfLeaves++;
00151
00152
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
00160 State* s = states->current->clone();
00161 myStates->current = s;
00162
00163 vMinima.push_back(s);
00164
00165 min2node[s] = n.second;
00166
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 }
00177 delete dummyState;
00178 assertbiu(numOfLeaves == toCopy.numOfLeaves
00179 , "different number of leaves after copying");
00180
00181
00182 mfeIndex = getMinIndex( toCopy.getMFEState() );
00183 assertbiu(mfeIndex != INVALID_INDEX
00184 , "mfe structure not found after copying");
00185
00186 sorted = false;
00187
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
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
00235 Node* nm1 = min2node[ vMinima[i] ];
00236 Node* nm2 = min2node[ vMinima[j] ];
00237
00238
00239 if (nm1 == nm2) {
00240 return false;
00241 }
00242
00243
00244 const State* m1 = nm1->content->current;
00245 const State* m2 = nm2->content->current;
00246
00247
00248 if (State::less(m2,m1)) {
00249 std::swap(m1,m2);
00250 std::swap(nm1,nm2);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 const double eDiff = s->getEnergy() - m2->getEnergy();
00274
00275 if ( eDiff <= maxMergeBarrier)
00276 {
00277
00278
00279 {
00280 StateList* l = nm2->content;
00281 while (l != NULL) {
00282
00283 min2node[ l->current ] = nm1;
00284
00285 StateList::addToList( nm1->content, l->current );
00286
00287
00288 l->current = NULL;
00289
00290 l = l->next;
00291 }
00292 }
00293
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
00305 NodeList::remFromList( nm2->parent->children, nm2 );
00306
00307
00308 Node* newRoot = mergeSubTrees( m1MergeParent, nm2->parent );
00309
00310
00311 delete nm2;
00312
00313 numOfLeaves--;
00314
00315
00316 checkIfObsolete( newRoot );
00317
00318
00319 return true;
00320 }
00321
00322
00323
00324 Node* knownBarrier = getLCA( nm1, nm2 );
00325 if ( knownBarrier->content == NULL
00326 || State::less( s, knownBarrier->content->current )
00327 )
00328 {
00329
00330
00331
00332 if (knownBarrier->content != NULL
00333 && knownBarrier->content->current->getEnergy() == s->getEnergy())
00334 {
00335
00336
00337
00338
00339 knownBarrier->content->current = s->clone(knownBarrier->content->current);
00340
00341 return true;
00342 }
00343
00344
00345
00346 Node* t1 = getHighestParentLEQ( nm1, s->getEnergy());
00347 Node* t2 = getHighestParentLEQ( nm2, s->getEnergy());
00348
00349 Node* pt1 = t1->parent;
00350 Node* pt2 = t2->parent;
00351
00352
00353 Node* newNode = NULL;
00354
00355
00356 if (t1->content->current->getEnergy() == s->getEnergy()) {
00357
00358 newNode = t1;
00359
00360
00361 if (State::less(s,newNode->content->current))
00362 {
00363
00364
00365
00366 newNode->content->current = s->clone(newNode->content->current);
00367 }
00368
00369 } else {
00370
00371 newNode = new Node( root
00372 , new NodeList(t1,NULL)
00373 , new StateList(s->clone(), NULL )
00374 );
00375 }
00376
00377
00378 NodeList::remFromList( pt1->children, t1 );
00379 NodeList::remFromList( pt2->children, t2 );
00380 t1->parent = newNode;
00381 t2->parent = newNode;
00382
00383
00384 if (t2->content->current->getEnergy()
00385 < newNode->content->current->getEnergy()
00386 || t2->children == NULL )
00387 {
00388
00389 NodeList::addToList( newNode->children, t2 );
00390 } else {
00391
00392
00393
00394
00395
00396
00397
00398 if (State::less( t2->content->current
00399 , newNode->content->current))
00400 {
00401
00402 delete newNode->content->current;
00403
00404 newNode->content->current = t2->content->current;
00405
00406 t2->content->current = NULL;
00407 }
00408
00409
00410 NodeList* n = t2->children;
00411 while (n != NULL) {
00412
00413 NodeList::addToList( newNode->children, n->current );
00414
00415 n->current->parent = newNode;
00416
00417
00418 n->current = NULL;
00419
00420 n = n->next;
00421 }
00422
00423
00424 delete t2;
00425 }
00426
00427
00428
00429 if (pt1 == pt2) {
00430
00431 NodeList::addToList( pt1->children, newNode );
00432
00433 newNode->parent = pt1;
00434
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 {
00443
00444 NodeList::addToList( pt1->children, newNode );
00445
00446 newNode->parent = pt1;
00447
00448
00449 Node* newRoot = mergeSubTrees( pt1, pt2 );
00450
00451 newRoot = checkIfObsolete( newRoot );
00452 } else {
00453
00454
00455 NodeList::addToList( pt2->children, newNode );
00456
00457 newNode->parent = pt2;
00458
00459 Node* newRoot = mergeSubTrees( pt2, pt1 );
00460
00461 newRoot = checkIfObsolete( newRoot );
00462 }
00463 }
00464
00465
00466 return true;
00467
00468 }
00469
00470
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
00485 size_t idx_i = getMinIndex(si);
00486
00487 if (idx_i == LandscapeTopology::INVALID_INDEX ) {
00488 idx_i = addMin(si);
00489 hasChanged = true;
00490 }
00491
00492 size_t idx_j = getMinIndex(sj);
00493
00494 if (idx_j == LandscapeTopology::INVALID_INDEX ) {
00495 idx_j = addMin(sj);
00496 hasChanged = true;
00497 }
00498
00499
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
00514 State* newMin = s->clone();
00515
00516
00517 vMinima.push_back(newMin);
00518
00519
00520 Node* newNode = new Node( NULL, NULL, new StateList(newMin,NULL) );
00521
00522 min2node[newMin] = newNode;
00523
00524
00525 if (root == NULL) {
00526
00527 root = newNode;
00528 newNode->parent = NULL;
00529 } else {
00530 if (root->content != NULL) {
00531
00532
00533 Node* newRoot
00534 = new Node(NULL, new NodeList(root,NULL), NULL, true);
00535 root->parent = newRoot;
00536 root = newRoot;
00537 }
00538
00539 NodeList::addToList(root->children, newNode);
00540 newNode->parent = root;
00541 }
00542
00543
00544 if (vMinima.size() == 1) {
00545 mfeIndex = 0;
00546 } else {
00547 if (State::less( s, vMinima[mfeIndex])) {
00548
00549
00550 mfeIndex = vMinima.size()-1;
00551
00552 sorted = false;
00553 } else if (sorted) {
00554
00555 sorted = State::less( vMinima[vMinima.size()-2], s );
00556 }
00557 }
00558
00559
00560 numOfLeaves++;
00561
00562 return vMinima.size()-1;
00563 }
00564
00565
00566
00567
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
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
00592
00593
00594
00595
00596 Node2Node_MAP minMap1to2;
00597 Node2Node_MAP minMap2to1;
00598
00599 std::stack<const NodeList*> childStack;
00600
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
00609 childStack.pop();
00610 } else {
00611
00612 childStack.top() = nextChild->next;
00613
00614 assertbiu( nextChild->current != NULL
00615 , "child information has no node link");
00616
00617
00618 if (nextChild->current->children != NULL) {
00619
00620 childStack.push( nextChild->current->children );
00621 } else {
00622
00623
00624
00625 StateList* s = nextChild->current->content;
00626 while( s != NULL ) {
00627
00628
00629 size_t to = bt->getMinIndex(s->current);
00630
00631 if (to != INVALID_INDEX) {
00632
00633 const Node* toNode = bt->min2node.find(
00634 bt->vMinima[to])->second;
00635
00636 minMap1to2[nextChild->current] = toNode;
00637 minMap2to1[toNode] = nextChild->current;
00638
00639 break;
00640 }
00641
00642 s = s->next;
00643 }
00644 if (minMap1to2.find(nextChild->current) != minMap1to2.end())
00645 {
00646 numOfDifferentMinima++;
00647 minimaDistance += MISSING_MINIMUM_PENALTY
00648 * exp( -(nextChild->current->content
00649 ->current->getEnergy())
00650 / BOLTZMANN_KT );
00651 }
00652 }
00653 }
00654 }
00655
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
00663 childStack.pop();
00664 } else {
00665
00666 childStack.top() = nextChild->next;
00667
00668
00669 if (nextChild->current->children != NULL) {
00670
00671 childStack.push( nextChild->current->children );
00672 } else {
00673
00674 if (minMap2to1.find(nextChild->current) != minMap2to1.end())
00675 {
00676
00677
00678 StateList* s = nextChild->current->content;
00679 while( s != NULL )
00680 {
00681
00682
00683 size_t to = this->getMinIndex(s->current);
00684
00685 if (to != INVALID_INDEX) {
00686
00687 const Node* toNode = this->min2node.find(
00688 this->vMinima[to])->second;
00689
00690 minMap2to1[nextChild->current] = toNode;
00691
00692 break;
00693 }
00694
00695 s = s->next;
00696 }
00697 }
00698 if (minMap2to1.find(nextChild->current) != minMap2to1.end())
00699 {
00700 numOfDifferentMinima++;
00701 minimaDistance += MISSING_MINIMUM_PENALTY
00702 * exp( -(nextChild->current->content
00703 ->current->getEnergy())
00704 / BOLTZMANN_KT );
00705 }
00706 }
00707 }
00708 }
00709
00710
00711 minimaDistance /= (double)numOfDifferentMinima;
00712
00713
00714
00715
00716
00717 double maxBarrierHeight = 0.0;
00718 {
00719
00720
00721
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) {
00727 maxBarrierHeight = mfeRoot->content->current->getEnergy()
00728 - this->getMFEState()->getEnergy();
00729 }
00730
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) {
00736
00737 maxBarrierHeight = std::max( maxBarrierHeight
00738 , mfeRoot->content->current->getEnergy()
00739 - bt->getMFEState()->getEnergy());
00740 }
00741 }
00742
00743 maxBarrierHeight *= maxBarrierHeight;
00744
00745
00746
00747
00748 std::set<const Node*> mappedFrom1;
00749
00750 typedef Node2Node_MAP::const_iterator MapIter;
00751 for (MapIter from=minMap1to2.begin(); from != minMap1to2.end(); from++)
00752 {
00753
00754 mappedFrom1.insert(from->second);
00755
00756 for (MapIter to = from; ++to != minMap1to2.end(); )
00757 {
00758
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
00763
00764
00765 double bDiff = from->first->content->current->getEnergy()
00766 - lca1->content->current->getEnergy();
00767
00768 bDiff -= from->second->content->current->getEnergy()
00769 - lca2->content->current->getEnergy();
00770
00771 squareDeviation += (bDiff * bDiff);
00772 } else
00773 if ( (lca1->content != NULL && lca2->content == NULL)
00774 || (lca1->content == NULL && lca2->content != NULL) )
00775 {
00776
00777 squareDeviation += maxBarrierHeight;
00778
00779
00780
00781 }
00782
00783 numOfDeviations++;
00784 }
00785 }
00786
00787 for (MapIter from=minMap2to1.begin(); from != minMap2to1.end(); from++)
00788 {
00789
00790 if (mappedFrom1.find(from->first) != mappedFrom1.end()) {
00791 continue;
00792 }
00793
00794 for (MapIter to = minMap2to1.begin(); to != minMap2to1.end(); to++)
00795 {
00796
00797 if (to->first == from->first) {
00798 continue;
00799 }
00800
00801
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
00806
00807
00808 double bDiff = from->first->content->current->getEnergy()
00809 - lca1->content->current->getEnergy();
00810
00811 bDiff -= from->second->content->current->getEnergy()
00812 - lca2->content->current->getEnergy();
00813
00814 squareDeviation += (bDiff * bDiff);
00815 } else
00816 if ( (lca1->content != NULL && lca2->content == NULL)
00817 || (lca1->content == NULL && lca2->content != NULL))
00818 {
00819
00820 squareDeviation += maxBarrierHeight;
00821
00822
00823
00824 }
00825
00826 numOfDeviations++;
00827 }
00828 }
00829
00830
00831
00832 if (numOfDeviations == 0) {
00833 return minimaDistance;
00834 }
00835
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
00852
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
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
00888 RETURNTYPE ret
00889 = LandscapeTopology::parseHeader( line.substr(i),
00890 lt_id,
00891 dim,
00892 stateDescr );
00893
00894 if (ret.first != 0) {
00895 sstr.clear();
00896 sstr <<"line " <<lineNumber
00897 <<" : "<<ret.second;
00898 return RETURNTYPE(ret.first,sstr.str());
00899 }
00900
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
00916 i = line.find(OUTPUT_KEY_MINIMUM);
00917 if(i != std::string::npos) {
00918
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
00927 if (dim == 0) {
00928 return RETURNTYPE(-3,"MORE minima present than given via DIMENSION");
00929 }
00930 dim--;
00931
00932
00933 RETURNTYPE ret
00934 = LandscapeTopology::parseMinimum( *this,
00935 line.substr(i),
00936 templateState,
00937 idx2min );
00938
00939
00940 if (ret.first != 0) {
00941 sstr.clear();
00942 sstr <<"line " <<lineNumber
00943 <<" : "<<ret.second;
00944 return RETURNTYPE(ret.first,sstr.str());
00945 }
00946
00947 if (ret.second.size() > 0) {
00948
00949 Node* lastAddedNode = min2node[vMinima[vMinima.size()-1]];
00950
00951 size_t start = ret.second.find_first_not_of(' ',0);
00952 while (start < ret.second.size()) {
00953
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
00958 StateList::addToList( lastAddedNode->content, subMin);
00959
00960 vMinima.push_back(subMin);
00961 min2node[subMin] = lastAddedNode;
00962
00963 start = ret.second.find_first_not_of(' ',end);
00964 }
00965 }
00966 }
00967
00969
00971 i = line.find(OUTPUT_KEY_BARRIER);
00972 if(i != std::string::npos) {
00973
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
00982 RETURNTYPE ret
00983 = LandscapeTopology::parseBarrier( *this,
00984 line.substr(i),
00985 templateState,
00986 idx2min );
00987
00988
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
01000 i = line.find(OUTPUT_KEY_SADDLE);
01001 if(i != std::string::npos) {
01002
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
01011 RETURNTYPE ret
01012 = LandscapeTopology::parseSaddle( *this,
01013 line.substr(i),
01014 templateState,
01015 idx2min );
01016
01017
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
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
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
01067 if (node2idx.find(cur) != node2idx.end()) {
01068 continue;
01069 }
01070
01071 node2idx[cur] = leafNodeCount;
01072 idx2node[leafNodeCount] = cur;
01073
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
01086 leafNodeCount++;
01087
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
01098
01099 nextRecursion = false;
01100 }
01101
01102 cur = cur->parent;
01103 }
01104 }
01105 assertbiu(numOfLeaves==leafNodeCount, "not all leaves printed");
01106
01107 std::vector<size_t> minConnected;
01108
01109 for (SizeT2Node_MAP::iterator it = idx2node.begin();
01110 it != idx2node.end(); it++)
01111 {
01112
01113
01114 if (it->second->children != NULL && it->second->content != NULL) {
01115
01116 minConnected.clear();
01117
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
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
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
01152 if (it->second->children != NULL && it->second->content != NULL) {
01153
01154
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
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
01188
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
01212
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
01234 if ( ta->content != NULL
01235 && tb->content != NULL
01236 && ta->content->current->getEnergy()
01237 == tb->content->current->getEnergy() )
01238 {
01239
01240 Node* t1 = ta;
01241 Node* t2 = tb;
01242
01243
01244 if (State::less(t2->content->current, t1->content->current)) {
01245 t1 = tb;
01246 t2 = ta;
01247 }
01248
01249 assertbiu(t2->children != NULL, "t2 is no internal node");
01250
01251 {
01252 NodeList*& n = t2->children;
01253 while( n != NULL ) {
01254
01255 NodeList::addToList( t1->children, n->current );
01256
01257 n->current->parent = t1;
01258
01259
01260 n->current = NULL;
01261
01262 n = n->next;
01263 }
01264 }
01265
01266
01267 NodeList::remFromList( t2->parent->children, t2 );
01268
01269 Node* pt2 = t2->parent;
01270
01271 delete t2;
01272
01273 return mergeSubTrees(t1->parent,pt2);
01274 }
01275
01276
01277 if (ta->children != NULL) {
01278 ta = checkIfObsolete(ta);
01279 }
01280 if (tb->children != NULL) {
01281 tb = checkIfObsolete(tb);
01282 }
01283
01284
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
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
01303 Node* pt1 = t1->parent;
01304 Node* pt2 = t2->parent;
01305
01306
01307 if ( pt1->content != NULL
01308 && State::less(pt1->content->current, t2->content->current))
01309 {
01310
01311 return mergeSubTrees( pt1, t2);
01312 }
01313
01314
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
01321 NodeList::remFromList( pt2->children, t2 );
01322
01323
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
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
01345 std::list<const Node*> p1, p2;
01346
01347
01348 p1.push_back(n1);
01349 while( (*(p1.rbegin())) != root ) {
01350 p1.push_back((*(p1.rbegin()))->parent);
01351 }
01352
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
01378 if (n1 == n2 )
01379 return n1;
01380 if (n1->parent == n2->parent)
01381 return n1->parent;
01382 Node* lca = root;
01383
01384
01385 std::list<Node*> p1, p2;
01386
01387
01388 p1.push_back(n1);
01389 while( (*(p1.rbegin())) != root ) {
01390 p1.push_back((*(p1.rbegin()))->parent);
01391 }
01392
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
01421 const Node* lca = getLCA( min2node.find(vMinima[m1])->second
01422 , min2node.find(vMinima[m2])->second );
01423
01424
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
01442 return getBarrier( im1, im2 );
01443 }
01444
01446 LT_BarrierTree::
01447 Node*
01448 LT_BarrierTree::
01449 checkIfObsolete( Node* n )
01451 {
01452
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
01457 Node* finalRoot = n;
01458
01459
01460 if (n->children->next == NULL) {
01461 if (n == root) {
01462
01463 root = n->children->current;
01464
01465 root->parent = NULL;
01466
01467 finalRoot = root;
01468 } else {
01469
01470 NodeList::remFromList(n->parent->children, n);
01471
01472 NodeList::addToList( n->parent->children
01473 , n->children->current);
01474
01475 n->children->current->parent = n->parent;
01476
01477 finalRoot = n->parent;
01478 }
01479
01480 n->children->current = NULL;
01481
01482 delete n;
01483
01484 } else {
01485
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
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
01553 this->sort();
01554
01555 const size_t max_print = std::min( maxLeaves2print, numOfLeaves);
01556
01557 std::vector<LT_BarrierTree::nodeT> nodes(max_print);
01558
01559
01560
01561 Node2Int_MAP node2idx;
01562
01563 int curMin = 0;
01564 for( int addedMin=0; addedMin < (int)max_print; addedMin++ ) {
01565
01566
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
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606 nodes[addedMin].label = NULL;
01607 curMin++;
01608 }
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
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
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
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
01648 chain = new linkT[n];
01649
01650 for (i=0; i<n; i++) {
01651 k = sindex[i];
01652 f = nodes.at(k).father;
01653 if (f==-1) f=0;
01654 if (k==f) continue;
01655 for (l= &chain[f]; l->next!=NULL; l = l->next);
01656 l->next=&chain[k];
01657 }
01658
01659 for (i=0, l= &chain[f]; l!=NULL; l = l->next)
01660 l->x = i++;
01661
01662
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
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
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
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
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
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 }