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

src/ell/LT_SaddleNet.cc

Go to the documentation of this file.
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     // Calculates the relative 'distance' between landscape topologies.
00031     // On the LandscapeTopology level it is done on the minima only. For each
00032     // minimum m present in only one of the two LTs a value of 
00033     // MISSING_MINIMUM_PENALTY*(e^(-energy(m)/BOLTZMANN_KT)) is summed. The 
00034     // resulting sum is normalized by the number of (unique) minima in both
00035     // topologies.
00036     // For all O(n^2) saddles in the nets the RMSD is calculated and 
00037     // summed to the minima penalty. For each saddle present in one of the
00038     // saddle nets only, the highest saddle of both nets  
00039     // is used in the RMSD calculation for the missing saddles.
00040     // @param lt the saddle net to calculate the distance to
00041     // @return the distance
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           // check if comparing with itself
00050         if (this == lt)
00051             return 0.0;
00052         
00053           // check if lt is an LT_MinimaSet object
00054         const LT_SaddleNet* const sn 
00055             = dynamic_cast<const LT_SaddleNet* const>(lt);
00056         if ( sn == NULL ) { 
00057             // no LT_SaddleNet --> use default function
00058             return LandscapeTopology::getDistance(lt);
00059         }
00060 
00061         double minimaDistance = 0.0;
00062         
00063           // sn1 will be the saddle net with the smaller number of minima
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           // find mapping of this minima to the minima of sn
00078         for (size_t i=sn1->getMinCount(); i-->0; ) {
00079               // try to map the current minimum of sn1
00080             curMatch = sn2->getMinIndex(sn1->getMin(i));
00081               // check if the minimum could be mapped
00082             if (curMatch != INVALID_INDEX) {
00083                   // store mapping
00084                 map2to1[curMatch] = i;
00085             } else {
00086                   // add missing minimum penalty
00087                 minimaDistance += MISSING_MINIMUM_PENALTY 
00088                                     * exp( -(sn1->getMin(i)->getEnergy())
00089                                             / BOLTZMANN_KT );
00090             }
00091         }
00092           // all minima of sn1 are considered to be unique
00093         numOfDifferentMinima += sn1->getMinCount();
00094           // find all minima of sn2 that could not be mapped
00095         for (size_t i=sn2->getMinCount(); i-->0; ) {
00096               // check if minimum of sn2 was not mapped
00097             if (map2to1.find(i) == map2to1.end()) {
00098                   // add missing minimum penalty
00099                 minimaDistance += MISSING_MINIMUM_PENALTY 
00100                                     * exp( -(sn2->getMin(i)->getEnergy())
00101                                             / BOLTZMANN_KT );
00102                   // update number of different minima
00103                 numOfDifferentMinima++;
00104             }
00105         }
00106           // normalize minima penalty by the number of different minima
00107         if (numOfDifferentMinima > 0) {
00108             minimaDistance /= (double)numOfDifferentMinima;
00109         }
00110         
00111         // saddle distance calculation
00112         
00113           // check all saddles
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                   // get the saddle states if existing
00123                 saddleIn1 = sn1->getSaddle( from->second, to->second );
00124                 saddleIn2 = sn2->getSaddle( from->first, to->first );
00125                   // check if there are saddles to compare 
00126                 if ( saddleIn1 == NULL && saddleIn2 == NULL ) {
00127                     continue;
00128                 } else if ( saddleIn1 != NULL && saddleIn2 != NULL ) {
00129                       // calculate square deviation
00130                     squareDeviation 
00131                         += (saddleIn1->getEnergy() - saddleIn2->getEnergy())
00132                             * (saddleIn1->getEnergy() - saddleIn2->getEnergy());
00133                 } else if (saddleIn1 != NULL) {
00134                       // calculate penalty for missing saddle in sn2
00135                     squareDeviation += MISSING_SADDLE_PENALTY
00136                                         * exp( -(saddleIn1->getEnergy())
00137                                                 / BOLTZMANN_KT );
00138                 } else {
00139                       // calculate penalty for missing saddle in sn1
00140                     squareDeviation += MISSING_SADDLE_PENALTY
00141                                         * exp( -(saddleIn2->getEnergy())
00142                                                 / BOLTZMANN_KT );
00143                 }
00144                   // count the contribution to the saddle deviation
00145                 numOfSaddles++;
00146             }
00147         }
00148         
00149           // check if a saddle was found
00150         if (numOfSaddles == 0) {
00151             return minimaDistance;
00152         }
00153           // return minima distance + RMSD on saddles (including penalty)
00154         return minimaDistance + sqrt( squareDeviation / (double)numOfSaddles );
00155     }
00156 
00157 } // namespace ell
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           // copy all states and set mfeState
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                       // make a copy of the stored state
00216                     this->adjacent[m1][m2] = toCopy.adjacent[m1][m2]->clone();
00217                       // create link if not minimum state on diagonal
00218                     if (m1 != m2) {
00219                         this->adjacent[m2][m1] = this->adjacent[m1][m2];
00220                     } else if (toCopy.adjacent[m1][m2] == toCopy.mfeState) {
00221                           // set mfe State
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               // resize matrix if too small or too big
00247             if (    adjacent.numRows() < numOfMin 
00248                     || adjacent.numRows()-MatrixResizeAdd > numOfMin )
00249             {
00250                 this->adjacent.resize(  this->numOfMin
00251                                         , this->numOfMin
00252                                         , NULLpointer);
00253             }
00254               // copy all states and set mfeState
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                           // make a copy of the stored state
00259                         this->adjacent[m1][m2] = toCopy.adjacent[m1][m2]->clone();
00260                           // create link if not minimum state on diagonal
00261                         if (m1 != m2) {
00262                             this->adjacent[m2][m1] = this->adjacent[m1][m2];
00263                         } else if (toCopy.adjacent[m1][m2] == toCopy.mfeState) {
00264                               // set mfe State
00265                             mfeState = this->adjacent[m1][m2];
00266                         }
00267                     } else {
00268                           // overwrite possible old entries
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           // delete all minima and saddles and reset pointer
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           // reset remaining information
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           // check if matrix resize is neccessary
00322         if (numOfMin == adjacent.numRows()) {
00323               // resize matrix and initialize new elements with NULL 
00324             adjacent.resize(    numOfMin+MatrixResizeAdd
00325                                 , numOfMin+MatrixResizeAdd
00326                                 , NULLpointer);
00327         }
00328           // add minimum to adjacency matrix
00329         adjacent[numOfMin][numOfMin] = stateclone;
00330         minAccess.push_back(numOfMin);
00331           // increase minima counter
00332         numOfMin++;
00333         
00334           // check if new minimum is mfe
00335         if( mfeState == NULL || stateclone->operator<( *mfeState ) )
00336         {
00337             mfeState = stateclone;
00338         }
00339         
00340           // update sorted property
00341         sorted = false;
00342 
00343           // return getMinCount()-1 that is the index of the new minimum 
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           // add saddle to adjacency list (but copy only once)
00364         if (adjacent[from][to] == NULLpointer) {
00365             adjacent[from][to] = s->clone();
00366             adjacent[to][from] = adjacent[from][to];
00367               // handle new saddle
00368             saddleNum++;
00369             saddleESum += s->getEnergy();
00370             return true;
00371         } else if (s->operator<( *adjacent[from][to] )) {
00372             // new saddle is lower than known one
00373               // update saddle sum by decrease by old saddle energy
00374             saddleESum -= adjacent[from][to]->getEnergy();
00375               // delete old saddle
00376             delete adjacent[from][to];
00377               // set new saddle in adjacency list (but copy only once)
00378             adjacent[from][to] = s->clone();
00379             adjacent[to][from] = adjacent[from][to];
00380               // update saddle sum by increase with new saddle energy
00381             saddleESum += s->getEnergy();
00382             return true;
00383         }
00384         
00385           // no saddle handling done and therefore no change
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           // get indices of the minima
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           // perform adding via member function
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           // sort only if necessary
00465         if (sorted)
00466             return;
00467           // sort minima
00468         
00469         const State* curState = NULL;
00470         for (size_t curPos=1; curPos<numOfMin; curPos++) {
00471               // get minimum behind sorted range
00472             curState = getMin(minAccess[curPos]);
00473               // find position where to insert the current position
00474             size_t toInsert = curPos;
00475             while (toInsert>0) {
00476                 if (getMin(minAccess[toInsert-1])->operator<(*curState)) {
00477                     break;
00478                 }
00479                 toInsert--;
00480             }
00481               // check if insertion is needed
00482             if (toInsert != curPos) {
00483                   // swap the two entries
00484                 std::swap(minAccess[toInsert], minAccess[curPos]);
00485             }
00486         }
00487         
00488           // set sorted
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           // stores the mapping of the minima indices in the file to the indices
00517           // used in the saddle net to add the saddles
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               // check if next line describes the header information
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                   // parse the minimum
00553                 RETURNTYPE ret 
00554                     = LandscapeTopology::parseHeader(   line.substr(i), 
00555                                                         lt_id,
00556                                                         dim,
00557                                                         stateDescr );
00558                   // check for parsing errors
00559                 if (ret.first != 0) {
00560                     sstr.clear();
00561                     sstr <<"line " <<lineNumber
00562                         <<" : "<<ret.second;
00563                     return RETURNTYPE(ret.first,sstr.str());
00564                 }
00565                   // check for semantical errors
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               // check if next line describes a minimum
00579             i = line.find(OUTPUT_KEY_MINIMUM);
00580             if(i != std::string::npos) {
00581                   // check if header already parsed
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                   // count the new found minimum
00590                 if (dim == 0) {
00591                     return RETURNTYPE(-3
00592                             ,"MORE minima present than given via DIMENSION");
00593                 }
00594                 dim--;
00595                 
00596                   // parse the minimum
00597                 RETURNTYPE ret 
00598                     = LandscapeTopology::parseMinimum(  *this, 
00599                                                         line.substr(i), 
00600                                                         templateState, 
00601                                                         idx2min );
00602                 
00603                   // check for parsing errors
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               // check if next line describes a saddle
00615             i = line.find(OUTPUT_KEY_SADDLE);
00616             if(i != std::string::npos) {
00617                   // check if header already parsed
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                   // parse the saddle
00626                 RETURNTYPE ret 
00627                     = LandscapeTopology::parseSaddle(   *this, 
00628                                                         line.substr(i), 
00629                                                         templateState, 
00630                                                         idx2min );
00631                 
00632                   // check for parsing errors
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               // garbage collection
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           // put all minima in with..
00674           // format : //MINIMUM index toString()
00675         for (size_t i = 0; i < numOfMin; ++i) {
00676             LandscapeTopology::writeMinimum( out, adjacent[i][i], i );
00677         }
00678         
00679           // the minima connected by the current saddle to print
00680         std::vector<size_t> minima;
00681           // the index of the next saddle to print
00682         size_t saddleIdx = numOfMin;
00683           // write all saddle
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                       // write saddle to stream
00690                     LandscapeTopology::writeSaddle( out
00691                                                     , adjacent[m1][m2]
00692                                                     , saddleIdx
00693                                                     , minima );
00694                       // remind the printed saddle
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                           // write saddle to stream
00715                         out << "\t\tM"<<m1<<" -- M" <<m2 <<";"<<"\n";           
00716                           // remind the printed saddle
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           // flush the output stream
00727         out.flush();
00728         
00729     }
00730     
00732       /* Checks if two minima are connected via a direct saddle.
00733        * @param m1 the index of the first minimum
00734        * @param m2 the index of the second minimum
00735        * @return true if there is a direct saddle stored in the topology
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       /* Access to the direct saddle connecting two minima if existing.
00754        * @param m1 the index of the first minimum
00755        * @param m2 the index of the second minimum
00756        * @return the saddle State or NULL if no direct saddle exists
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           // calculate average saddle height
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 } // namespace ell
00792