00001
00002 #include "ell/LT_SaddleNet.hh"
00003 #include "ell/LT_MinimaSet.hh"
00004
00005 #include <map>
00006 #include <cmath>
00007
00008 namespace ell {
00009
00011 const std::string LT_SaddleNet::LT_ID = "SN";
00013
00014
00015
00017 double LT_SaddleNet::MISSING_SADDLE_PENALTY = 5.0;
00019
00020
00021
00023 LT_SaddleNet::
00024 ~LT_SaddleNet()
00026 {}
00027
00028
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 double
00043 LT_SaddleNet::
00044 getDistance(const LandscapeTopology* const lt) const
00046 {
00047 assertbiu(lt!=NULL, "given LandscapeTopology to compare to is NULL!");
00048
00049
00050 if (this == lt)
00051 return 0.0;
00052
00053
00054 const LT_SaddleNet* const sn
00055 = dynamic_cast<const LT_SaddleNet* const>(lt);
00056 if ( sn == NULL ) {
00057
00058 return LandscapeTopology::getDistance(lt);
00059 }
00060
00061 double minimaDistance = 0.0;
00062
00063
00064 const LT_SaddleNet* sn1 = this;
00065 const LT_SaddleNet* sn2 = sn;
00066 if (this->getMinCount() > sn->getMinCount()) {
00067 sn1 = sn;
00068 sn2 = this;
00069 }
00070
00071
00072 std::map<size_t, size_t> map2to1;
00073
00074
00075 size_t numOfDifferentMinima = 0;
00076 size_t curMatch = INVALID_INDEX;
00077
00078 for (size_t i=sn1->getMinCount(); i-->0; ) {
00079
00080 curMatch = sn2->getMinIndex(sn1->getMin(i));
00081
00082 if (curMatch != INVALID_INDEX) {
00083
00084 map2to1[curMatch] = i;
00085 } else {
00086
00087 minimaDistance += MISSING_MINIMUM_PENALTY
00088 * exp( -(sn1->getMin(i)->getEnergy())
00089 / BOLTZMANN_KT );
00090 }
00091 }
00092
00093 numOfDifferentMinima += sn1->getMinCount();
00094
00095 for (size_t i=sn2->getMinCount(); i-->0; ) {
00096
00097 if (map2to1.find(i) == map2to1.end()) {
00098
00099 minimaDistance += MISSING_MINIMUM_PENALTY
00100 * exp( -(sn2->getMin(i)->getEnergy())
00101 / BOLTZMANN_KT );
00102
00103 numOfDifferentMinima++;
00104 }
00105 }
00106
00107 if (numOfDifferentMinima > 0) {
00108 minimaDistance /= (double)numOfDifferentMinima;
00109 }
00110
00111
00112
00113
00114 double squareDeviation = 0.0;
00115 size_t numOfSaddles = 0;
00116 std::map<size_t,size_t>::const_iterator from = map2to1.begin();
00117 std::map<size_t,size_t>::const_iterator to = from;
00118 const State* saddleIn1 = NULL;
00119 const State* saddleIn2 = NULL;
00120 for ( from = map2to1.begin(); from != map2to1.end(); from++ ) {
00121 for ( ++(to = from); to != map2to1.end(); to++ ) {
00122
00123 saddleIn1 = sn1->getSaddle( from->second, to->second );
00124 saddleIn2 = sn2->getSaddle( from->first, to->first );
00125
00126 if ( saddleIn1 == NULL && saddleIn2 == NULL ) {
00127 continue;
00128 } else if ( saddleIn1 != NULL && saddleIn2 != NULL ) {
00129
00130 squareDeviation
00131 += (saddleIn1->getEnergy() - saddleIn2->getEnergy())
00132 * (saddleIn1->getEnergy() - saddleIn2->getEnergy());
00133 } else if (saddleIn1 != NULL) {
00134
00135 squareDeviation += MISSING_SADDLE_PENALTY
00136 * exp( -(saddleIn1->getEnergy())
00137 / BOLTZMANN_KT );
00138 } else {
00139
00140 squareDeviation += MISSING_SADDLE_PENALTY
00141 * exp( -(saddleIn2->getEnergy())
00142 / BOLTZMANN_KT );
00143 }
00144
00145 numOfSaddles++;
00146 }
00147 }
00148
00149
00150 if (numOfSaddles == 0) {
00151 return minimaDistance;
00152 }
00153
00154 return minimaDistance + sqrt( squareDeviation / (double)numOfSaddles );
00155 }
00156
00157 }
00158
00159
00160 #include <sstream>
00161 #include "ell/LT_MinimaSet.hh"
00162
00163 namespace ell {
00164
00166 size_t LT_SaddleNet_AM::MatrixResizeAdd = 10;
00168 const State* const LT_SaddleNet_AM::NULLpointer = NULL;
00170
00171
00173 LT_SaddleNet_AM::
00174 ~LT_SaddleNet_AM()
00176 {
00177 this->clear();
00178 }
00179
00180
00182 LT_SaddleNet_AM::
00183 LT_SaddleNet_AM( const size_t matrixDim )
00185 : adjacent(matrixDim, matrixDim, NULLpointer)
00186 , numOfMin(0)
00187 , minAccess()
00188 , mfeState(NULL)
00189 , sorted(true)
00190 , sortedEnd(0)
00191 , saddleESum(0.0)
00192 , saddleNum(0)
00193 {
00194
00195 }
00196
00197
00199 LT_SaddleNet_AM::
00200 LT_SaddleNet_AM( const LT_SaddleNet_AM & toCopy )
00202 : adjacent(toCopy.numOfMin, toCopy.numOfMin, NULLpointer)
00203 , numOfMin(toCopy.numOfMin)
00204 , minAccess(toCopy.minAccess)
00205 , mfeState(NULL)
00206 , sorted(toCopy.sorted)
00207 , sortedEnd(toCopy.sortedEnd)
00208 , saddleESum(toCopy.saddleESum)
00209 , saddleNum(toCopy.saddleNum)
00210 {
00211
00212 for (size_t m1=0; m1<numOfMin; m1++) {
00213 for (size_t m2=m1; m2<numOfMin; m2++) {
00214 if (toCopy.adjacent[m1][m2] != NULLpointer) {
00215
00216 this->adjacent[m1][m2] = toCopy.adjacent[m1][m2]->clone();
00217
00218 if (m1 != m2) {
00219 this->adjacent[m2][m1] = this->adjacent[m1][m2];
00220 } else if (toCopy.adjacent[m1][m2] == toCopy.mfeState) {
00221
00222 mfeState = this->adjacent[m1][m2];
00223 }
00224 }
00225 }
00226 }
00227 }
00228
00230 LT_SaddleNet_AM&
00231 LT_SaddleNet_AM::
00232 operator = (const LT_SaddleNet_AM & toCopy )
00233
00234 {
00235 if (this != &toCopy) {
00236 this->numOfMin = toCopy.numOfMin;
00237 this->minAccess.resize( toCopy.minAccess.size(), 0 );
00238 std::copy( toCopy.minAccess.begin()
00239 , toCopy.minAccess.end()
00240 , this->minAccess.begin() );
00241 this->sorted = toCopy.sorted;
00242 this->sortedEnd = toCopy.sortedEnd;
00243 this->saddleESum = toCopy.saddleESum;
00244 this->saddleNum = toCopy.saddleNum;
00245
00246
00247 if ( adjacent.numRows() < numOfMin
00248 || adjacent.numRows()-MatrixResizeAdd > numOfMin )
00249 {
00250 this->adjacent.resize( this->numOfMin
00251 , this->numOfMin
00252 , NULLpointer);
00253 }
00254
00255 for (size_t m1=0; m1<numOfMin; m1++) {
00256 for (size_t m2=m1; m2<numOfMin; m2++) {
00257 if (toCopy.adjacent[m1][m2] != NULLpointer) {
00258
00259 this->adjacent[m1][m2] = toCopy.adjacent[m1][m2]->clone();
00260
00261 if (m1 != m2) {
00262 this->adjacent[m2][m1] = this->adjacent[m1][m2];
00263 } else if (toCopy.adjacent[m1][m2] == toCopy.mfeState) {
00264
00265 mfeState = this->adjacent[m1][m2];
00266 }
00267 } else {
00268
00269 this->adjacent[m1][m2] = NULLpointer;
00270 this->adjacent[m2][m1] = NULLpointer;
00271 }
00272 }
00273 }
00274
00275 }
00276 return *this;
00277 }
00278
00279
00281 void
00282 LT_SaddleNet_AM::
00283 clear()
00285 {
00286 assertbiu(numOfMin <= adjacent.numRows(), "numOfMin does not correlate with adjacency matrix (>size)");
00287
00288
00289 for (size_t from=0; from<numOfMin; from++) {
00290 for (size_t to=from; to<numOfMin; to++) {
00291 if (adjacent[from][to] != NULLpointer) {
00292 delete adjacent[from][to];
00293 adjacent[from][to] = NULLpointer;
00294 adjacent[to][from] = NULLpointer;
00295 }
00296 }
00297 }
00298
00299 numOfMin = 0;
00300 minAccess.clear();
00301 mfeState = NULL;
00302 sorted = true;
00303 sortedEnd = 0;
00304 saddleESum = 0.0;
00305 saddleNum = 0;
00306 }
00307
00308
00310 const size_t
00311 LT_SaddleNet_AM::
00312 addMin(const State* const s)
00313
00314 {
00315 assertbiu(s != NULL, "no minimum given (s is NULL)");
00316 assertbiu(getMinIndex(s) == LandscapeTopology::INVALID_INDEX
00317 , "given minimum is known and already part of the landscape");
00318
00319 State* stateclone = s->clone();
00320
00321
00322 if (numOfMin == adjacent.numRows()) {
00323
00324 adjacent.resize( numOfMin+MatrixResizeAdd
00325 , numOfMin+MatrixResizeAdd
00326 , NULLpointer);
00327 }
00328
00329 adjacent[numOfMin][numOfMin] = stateclone;
00330 minAccess.push_back(numOfMin);
00331
00332 numOfMin++;
00333
00334
00335 if( mfeState == NULL || stateclone->operator<( *mfeState ) )
00336 {
00337 mfeState = stateclone;
00338 }
00339
00340
00341 sorted = false;
00342
00343
00344 return (numOfMin-1);
00345 }
00346
00348 bool
00349 LT_SaddleNet_AM::
00350 addSaddle(const size_t m1, const size_t m2, const State* const s)
00351
00352 {
00353 assertbiu(m1<numOfMin, "m1 out of range");
00354 assertbiu(m2<numOfMin, "m2 out of range");
00355 assertbiu(m1!=m2, "m1 and m2 are equal --> saddle to itself");
00356
00357 size_t from = m1, to = m2;
00358 if (m1>m2) {
00359 from = m2;
00360 to = m1;
00361 }
00362
00363
00364 if (adjacent[from][to] == NULLpointer) {
00365 adjacent[from][to] = s->clone();
00366 adjacent[to][from] = adjacent[from][to];
00367
00368 saddleNum++;
00369 saddleESum += s->getEnergy();
00370 return true;
00371 } else if (s->operator<( *adjacent[from][to] )) {
00372
00373
00374 saddleESum -= adjacent[from][to]->getEnergy();
00375
00376 delete adjacent[from][to];
00377
00378 adjacent[from][to] = s->clone();
00379 adjacent[to][from] = adjacent[from][to];
00380
00381 saddleESum += s->getEnergy();
00382 return true;
00383 }
00384
00385
00386 return false;
00387 }
00388
00390 bool
00391 LT_SaddleNet_AM::
00392 addSaddle(const State* const m1, const State* const m2, const State* const s)
00393
00394 {
00395 assertbiu( m1!=NULL, "no minimum m1 given (==NULL)");
00396 assertbiu( m2!=NULL, "no minimum m2 given (==NULL)");
00397 assertbiu( s!=NULL, "no saddle s given (==NULL)");
00398
00399
00400 size_t im1 = getMinIndex( m1 );
00401 size_t im2 = getMinIndex( m2 );
00402
00403 assertbiu( im1 != INVALID_INDEX, "m1 is no know minimum");
00404 assertbiu( im2 != INVALID_INDEX, "m2 is no know minimum");
00405
00406
00407 return addSaddle( im1, im2, s );
00408 }
00409
00411 const State* const
00412 LT_SaddleNet_AM::
00413 getMin(size_t i) const
00415 {
00416 assertbiu(i < numOfMin, "minimum index i out of bound!");
00417
00418 return adjacent[minAccess[i]][minAccess[i]];
00419 }
00420
00421
00423 const size_t
00424 LT_SaddleNet_AM::
00425 getMinIndex(const State* const s) const
00427 {
00428 assertbiu(s != NULL, "given minimum State to get index of is NULL");
00429
00430 for (size_t i = 0; i < numOfMin; ++i)
00431 if(adjacent[minAccess[i]][minAccess[i]]->operator==(*s))
00432 return i;
00433
00434 return LandscapeTopology::INVALID_INDEX;
00435 }
00436
00438 const size_t
00439 LT_SaddleNet_AM::
00440 getMinCount() const
00442 {
00443 return numOfMin;
00444 }
00445
00447 const State* const
00448 LT_SaddleNet_AM::
00449 getMFEState() const
00451 {
00452 assertbiu(numOfMin != 0
00453 , "no minimum present and therefore no mfe state too");
00454 return mfeState;
00455 }
00456
00457
00459 void
00460 LT_SaddleNet_AM::
00461 sort()
00462
00463 {
00464
00465 if (sorted)
00466 return;
00467
00468
00469 const State* curState = NULL;
00470 for (size_t curPos=1; curPos<numOfMin; curPos++) {
00471
00472 curState = getMin(minAccess[curPos]);
00473
00474 size_t toInsert = curPos;
00475 while (toInsert>0) {
00476 if (getMin(minAccess[toInsert-1])->operator<(*curState)) {
00477 break;
00478 }
00479 toInsert--;
00480 }
00481
00482 if (toInsert != curPos) {
00483
00484 std::swap(minAccess[toInsert], minAccess[curPos]);
00485 }
00486 }
00487
00488
00489 sorted = true;
00490 }
00491
00492
00493
00495 bool
00496 LT_SaddleNet_AM::
00497 isSorted() const
00499 {
00500 return sorted;
00501 }
00502
00503
00505 std::pair<int,std::string>
00506 LT_SaddleNet_AM::
00507 read( std::istream & in,
00508 const State * const templateState )
00510 {
00511
00512
00513 typedef std::pair<int,std::string> RETURNTYPE;
00514 State* s;
00515
00516
00517
00518 Int2SizeT_MAP idx2min;
00519
00520 std::string line;
00521 std::stringstream sstr;
00522
00523 bool headerParsed = false;
00524 size_t dim = 0;
00525 size_t lineNumber = 0;
00526
00527 std::string::size_type i;
00528
00532
00533 while( std::getline(in, line) ) {
00534 ++lineNumber;
00535 s = NULL;
00536
00538 if(line.find("GRAPHVIZ") != std::string::npos) {
00539 break;
00540 }
00541
00543
00545 i = line.find(OUTPUT_KEY_ELL_HEAD);
00546 if(i != std::string::npos) {
00547
00548 std::string lt_id("");
00549 dim = 0;
00550 std::string stateDescr("");
00551
00552
00553 RETURNTYPE ret
00554 = LandscapeTopology::parseHeader( line.substr(i),
00555 lt_id,
00556 dim,
00557 stateDescr );
00558
00559 if (ret.first != 0) {
00560 sstr.clear();
00561 sstr <<"line " <<lineNumber
00562 <<" : "<<ret.second;
00563 return RETURNTYPE(ret.first,sstr.str());
00564 }
00565
00566 if ( lt_id.compare(LT_SaddleNet::LT_ID) != 0
00567 && lt_id.compare(LT_MinimaSet::LT_ID) != 0 ) {
00568 return RETURNTYPE(-1,"ELL-LT-TYPE not supported");
00569 }
00570 if (stateDescr.compare(templateState->getID()) != 0 ) {
00571 return RETURNTYPE(-2,"STATETYPE differs from given type");
00572 }
00573 headerParsed = true;
00574 }
00575
00577
00579 i = line.find(OUTPUT_KEY_MINIMUM);
00580 if(i != std::string::npos) {
00581
00582 if (!headerParsed) {
00583 sstr.clear();
00584 sstr <<"line " <<lineNumber
00585 <<" : minimum present but no header found so far";
00586 return RETURNTYPE(-2,sstr.str());
00587 }
00588
00589
00590 if (dim == 0) {
00591 return RETURNTYPE(-3
00592 ,"MORE minima present than given via DIMENSION");
00593 }
00594 dim--;
00595
00596
00597 RETURNTYPE ret
00598 = LandscapeTopology::parseMinimum( *this,
00599 line.substr(i),
00600 templateState,
00601 idx2min );
00602
00603
00604 if (ret.first != 0) {
00605 sstr.clear();
00606 sstr <<"line " <<lineNumber
00607 <<" : "<<ret.second;
00608 return RETURNTYPE(ret.first,sstr.str());
00609 }
00610 }
00611
00613
00615 i = line.find(OUTPUT_KEY_SADDLE);
00616 if(i != std::string::npos) {
00617
00618 if (!headerParsed) {
00619 sstr.clear();
00620 sstr <<"line " <<lineNumber
00621 <<" : saddle present but no header found so far";
00622 return RETURNTYPE(-2,sstr.str());
00623 }
00624
00625
00626 RETURNTYPE ret
00627 = LandscapeTopology::parseSaddle( *this,
00628 line.substr(i),
00629 templateState,
00630 idx2min );
00631
00632
00633 if (ret.first != 0) {
00634 sstr.clear();
00635 sstr <<"line " <<lineNumber
00636 <<" : "<<ret.second;
00637 return RETURNTYPE(ret.first,sstr.str());
00638 }
00639 }
00640
00641
00642 if (s != NULL) {
00643 delete s;
00644 s = NULL;
00645 }
00646
00647 }
00648
00649 if (dim > 0) {
00650 return RETURNTYPE(-3,"LESS minima present than given via DIMENSION");
00651 }
00652
00653 return RETURNTYPE(0,std::string(""));
00654 }
00655
00656
00658 void
00659 LT_SaddleNet_AM::
00660 write( std::ostream& out,
00661 const bool writeGraph ) const
00663 {
00666
00667 const std::string dummyID = "ell::State";
00668 LandscapeTopology::writeHeader( out
00669 , LT_SaddleNet::LT_ID
00670 , numOfMin
00671 , (numOfMin==0?dummyID:adjacent[0][0]->getID()));
00672
00673
00674
00675 for (size_t i = 0; i < numOfMin; ++i) {
00676 LandscapeTopology::writeMinimum( out, adjacent[i][i], i );
00677 }
00678
00679
00680 std::vector<size_t> minima;
00681
00682 size_t saddleIdx = numOfMin;
00683
00684 for (size_t m1=0; m1<numOfMin; m1++) {
00685 minima.push_back(m1);
00686 for (size_t m2=m1+1; m2<numOfMin; m2++) {
00687 if (adjacent[m1][m2] != NULLpointer) {
00688 minima.push_back(m2);
00689
00690 LandscapeTopology::writeSaddle( out
00691 , adjacent[m1][m2]
00692 , saddleIdx
00693 , minima );
00694
00695 saddleIdx++;
00696 minima.pop_back();
00697 }
00698 }
00699 minima.pop_back();
00700 }
00701
00702 if (writeGraph) {
00703 out << "\n" << "//GRAPHVIZ"<<"\n";
00704
00706 out << "graph SADDLENET {"<<"\n";
00707 for (size_t i = 0; i < numOfMin; ++i) {
00708 out << "\t\tM"<<i<<";"<<"\n";
00709 }
00710 size_t saddleIdx = numOfMin;
00711 for (size_t m1=0; m1<numOfMin; m1++) {
00712 for (size_t m2=m1+1; m2<numOfMin; m2++) {
00713 if (adjacent[m1][m2] != NULLpointer) {
00714
00715 out << "\t\tM"<<m1<<" -- M" <<m2 <<";"<<"\n";
00716
00717 saddleIdx++;
00718 }
00719 }
00720 }
00721 out << "label = \"\\n\\nLT_SaddleNet Diagram\\nwith "<<numOfMin<<" minima \";"<<"\n";
00722 out << "fontsize=20;"<<"\n";
00723 out << "} "<<"\n";
00724 }
00725
00726
00727 out.flush();
00728
00729 }
00730
00732
00733
00734
00735
00736
00737 bool
00738 LT_SaddleNet_AM::
00739 isSaddle( const size_t m1, const size_t m2 ) const
00741 {
00742 assertbiu(m1<numOfMin, "m1 out of range");
00743 assertbiu(m2<numOfMin, "m2 out of range");
00744
00745 if (m1!=m2)
00746 return adjacent[m1][m2] != NULLpointer;
00747
00748 return false;
00749 }
00750
00751
00753
00754
00755
00756
00757
00758 const State*
00759 LT_SaddleNet_AM::
00760 getSaddle( const size_t m1, const size_t m2 ) const
00762 {
00763 assertbiu(m1<numOfMin, "m1 out of range");
00764 assertbiu(m2<numOfMin, "m2 out of range");
00765
00766 return adjacent[m1][m2];
00767 }
00768
00770 double
00771 LT_SaddleNet_AM::
00772 getAvgSaddleEnergy( void ) const
00774 {
00775 if (saddleNum == 0)
00776 return 0.0;
00777
00778 return saddleESum / (double)saddleNum;
00779 }
00780
00782 size_t
00783 LT_SaddleNet_AM::
00784 getSaddleNumber( void ) const
00786 {
00787 return saddleNum;
00788 }
00789
00790
00791 }
00792