Generated on Mon Jun 23 17:17:53 2008 for ell-2.3.0 by doxygen 1.5.1

src/ell/rna/S_RNAfe_SingleM.cc

Go to the documentation of this file.
00001 #include "ell/rna/S_RNAfe_SingleM.hh"
00002 #include <cmath>    // for getFitness()
00003 #include <biu/assertbiu.hh>
00004 #include "biu/RandomNumberFactory.hh"
00005 
00006 
00007 namespace ell
00008 {
00009 
00010     const size_t 
00011         S_RNAfe_SingleM::RandomNeighborList::ItState::SWITCH_MODE_THRESHOLD = 20;
00012         
00014 // S_RNAfe_SingleM
00016 
00017     S_RNAfe_SingleM::S_RNAfe_SingleM(
00018                 const std::string& rnaSeqStr, 
00019                 const std::string& rnaStructBracketNotStr)
00020      :  rnaFreeEnergy(rnaSeqStr, rnaStructBracketNotStr)
00021     {
00022         assertbiu(rnaFreeEnergy.isValid(),
00023          "S_RNAfe_SingleM has to be a valid state.");
00024          
00025     }
00026 
00027     S_RNAfe_SingleM::S_RNAfe_SingleM(const RNAFreeEnergy& rna)
00028      :  rnaFreeEnergy(rna)
00029     {
00030         assertbiu(rnaFreeEnergy.isValid(),
00031          "S_RNAfe_SingleM has to be a valid state.");
00032          
00033     }
00034 
00035     S_RNAfe_SingleM::S_RNAfe_SingleM(
00036                 const S_RNAfe_SingleM& rnaFESMS)
00037      : rnaFreeEnergy(rnaFESMS.rnaFreeEnergy)
00038     {
00039     }
00040 
00041     S_RNAfe_SingleM::~S_RNAfe_SingleM() {
00042     }
00043 
00044     S_RNAfe_SingleM::SingleMove 
00045     S_RNAfe_SingleM::firstValidSingleMove() const {
00046         return searchForNextValidSingleMove(0,1);
00047     }
00048 
00049     S_RNAfe_SingleM::SingleMove 
00050     S_RNAfe_SingleM::nextValidSingleMove( 
00051             const SingleMove lastSingleMove) const 
00052     {
00053         // if lastSingleMove.first is an opening bond, this bond was already
00054         // modified in the last move
00055         // closing bonds at lastSingleMove.first are not for interest
00056         if (rnaFreeEnergy.getStructureRef().at(lastSingleMove.first) != biu::RNAStructure::STRUCT_UNBOUND ) {
00057             return searchForNextValidSingleMove(lastSingleMove.first+1,
00058                 lastSingleMove.first+2);
00059         }
00060         else {
00061             return searchForNextValidSingleMove(lastSingleMove.first,
00062                 lastSingleMove.second+1);
00063         }
00064     }
00065 
00066     S_RNAfe_SingleM::SingleMove 
00067     S_RNAfe_SingleM:: searchForNextValidSingleMove( size_t pos1, 
00068                                 size_t pos2) const 
00069     {
00070         assertbiu(pos1 < pos2,
00071          "RNA single move search pos 1 has to be less than pos 2");
00072         
00073 
00074     if (pos2==rnaFreeEnergy.getLength() && pos1 == 0) {
00075         pos1++;
00076         pos2 = pos1+1;
00077     }
00078 //          // no next valid single move found
00079 //          return SingleMove(0,biu::RNAStructure::INVALID_INDEX);
00080             
00081         
00082         // distance between pos1 and pos2 has to be at least
00083         //  MIN_LOOP_LENGTH
00084         while ( (pos1+rnaFreeEnergy.getMinLoopLength())
00085                  < rnaFreeEnergy.getLength()) 
00086         {
00087             if ( rnaFreeEnergy.getStructureRef().at(pos1) == biu::RNAStructure::STRUCT_UNBOUND )
00088             {
00089                 for(pos2 = rnaFreeEnergy.nextCompatibleSingleMovePos(pos2-1);
00090                     pos2 < rnaFreeEnergy.getLength();
00091                     pos2 = rnaFreeEnergy.nextCompatibleSingleMovePos(pos2))
00092                 {
00093                     if ((pos2 - pos1) > rnaFreeEnergy.getMinLoopLength() &&
00094                          rnaFreeEnergy.isAllowedBasePair(pos1, pos2)) {
00095                             // found bases which are able to pair
00096                             // -> exit loop
00097                         return SingleMove(pos1,pos2);
00098                         break;
00099                     }
00100                 }
00101             }
00102             else if ( rnaFreeEnergy.getStructureRef().at(pos1) == biu::RNAStructure::STRUCT_BND_OPEN )
00103             {
00104                 pos2 = rnaFreeEnergy.getClosingBond(pos1);
00105                     // existing bond found -> exit loop
00106                 return SingleMove(pos1,pos2);
00107             }
00108                 // loop wasn't exited since no next valid single move was found
00109             pos1++;
00110             pos2 = pos1;
00111         }
00112         // no next valid single move found
00113         return SingleMove(0,biu::RNAStructure::INVALID_INDEX);
00114     }
00115 
00116     bool    
00117     S_RNAfe_SingleM::operator== (const State& state2) const {
00118         return rnaFreeEnergy == (dynamic_cast<
00119             const S_RNAfe_SingleM&>(state2)).rnaFreeEnergy;
00120     }
00121 
00122     bool
00123     S_RNAfe_SingleM::operator!= (const State& state2) const {
00124         return rnaFreeEnergy != (dynamic_cast<
00125             const S_RNAfe_SingleM&>(state2)).rnaFreeEnergy;
00126     }
00127 
00128     int 
00129     S_RNAfe_SingleM::getFitness() const {
00130             // rounds energy and multiplies it with 100, then negate it
00131         double energy = 100 * rnaFreeEnergy.getEnergy();
00132         if (energy >= 0)
00133             return - static_cast<int>(floor(energy + 0.5));
00134         else
00135             return - static_cast<int>(ceil(energy - 0.5));
00136     }
00137 
00138     double  
00139     S_RNAfe_SingleM::getEnergy(void) const {
00140         return rnaFreeEnergy.getEnergy();
00141     }
00142 
00143     unsigned int    
00144     S_RNAfe_SingleM::getMinimalDistance(
00145          const State& _state2) const {
00146         S_RNAfe_SingleM state2 = 
00147          dynamic_cast<const S_RNAfe_SingleM&>(_state2);
00148 
00149         const biu::Structure& state1Struct = rnaFreeEnergy.getStructureRef();
00150         const biu::Structure& state2Struct = state2.rnaFreeEnergy.getStructureRef();
00151 
00152         assertbiu(state2Struct.size() == state1Struct.size(),
00153         "Length of both RNA has to be equal to compute the distance.");
00154             
00155         unsigned int distance = 0;
00156         for (size_t i = 0; i < state1Struct.size(); i++){
00157             // bond maintained or bond opened and replaced by another one
00158             if (state1Struct[i] == biu::RNAStructure::STRUCT_BND_OPEN &&
00159                state2Struct[i] == biu::RNAStructure::STRUCT_BND_OPEN ) {
00160                 // bond opened and replaced by another one
00161                 if (rnaFreeEnergy.getClosingBond(i) !=
00162                      state2.rnaFreeEnergy.getClosingBond(i)) {
00163                     distance += 2;
00164                 }
00165             }
00166             // bond opened or closed
00167             else if (state1Struct[i] == biu::RNAStructure::STRUCT_BND_OPEN  ||
00168                       state2Struct[i] == biu::RNAStructure::STRUCT_BND_OPEN ) {
00169                 distance += 1;
00170             }
00171         }
00172         return distance;
00173     }
00174 
00175     S_RNAfe_SingleM* 
00176     S_RNAfe_SingleM::clone() const {
00177         return new S_RNAfe_SingleM(*this);
00178     }
00179     
00180     State*
00181     S_RNAfe_SingleM::fromString(const std::string& stringRep) const {
00182         std::string backboneRep = ".()";
00183         size_t pos = stringRep.find_first_not_of(backboneRep);
00184         std::cout << pos << std::endl;
00185         const std::string rnaStructBracketNotStr = stringRep.substr(0, pos-1);
00186         const std::string rnaSeqStr = stringRep.substr(pos, stringRep.size()-pos-1);
00187         return new S_RNAfe_SingleM(rnaSeqStr, rnaStructBracketNotStr);
00188     }
00189     
00190     std::string 
00191     S_RNAfe_SingleM::toString()
00192              const{
00193         return rnaFreeEnergy.getStringRepresentation();
00194     }
00195 
00196     State::NeighborListPtr 
00197     S_RNAfe_SingleM::getNeighborList() const {
00198         return NeighborListPtr(new NeighborList(this));
00199     }
00200 
00201     State::NeighborListPtr
00202     S_RNAfe_SingleM::getRandomNeighborList() const 
00203     {
00204         return NeighborListPtr(new RandomNeighborList(this));
00205     }
00206 
00207     // NeighborList
00208     S_RNAfe_SingleM::NeighborList::NeighborList(
00209                 const S_RNAfe_SingleM* _origin) 
00210      : origin(_origin) 
00211     {
00212     }
00213 
00214     S_RNAfe_SingleM::NeighborList::~NeighborList() {
00215     }
00216 
00217     State* 
00218     S_RNAfe_SingleM::NeighborList::first(
00219               State::NeighborList::ItState** itstate) const {
00220         if (*itstate != NULL) delete *itstate;
00221 
00222         ItState* myitstate = new ItState();
00223         *itstate = myitstate;
00224         
00225         S_RNAfe_SingleM* rnaState = NULL;
00226 
00227         SingleMove firstMove = origin->firstValidSingleMove();
00228         
00229 
00230         if (firstMove != SingleMove(0,biu::RNAStructure::INVALID_INDEX)) {
00231             rnaState = new S_RNAfe_SingleM(*origin);
00232             rnaState->rnaFreeEnergy.applySingleMoveInPlace(firstMove);
00233             myitstate->lastMove = firstMove;
00234         }
00235         return rnaState;
00236     }
00237 
00238     State* 
00239     S_RNAfe_SingleM::NeighborList::next(
00240               State::NeighborList::ItState* itstate, State* elem) const {
00241         assertbiu(elem != NULL, "Elem is not allowed to be NULL");
00242 
00243         ItState* myitstate = static_cast<ItState*>(itstate);
00244 
00245         // find next move
00246         SingleMove nextMove = origin->nextValidSingleMove(myitstate->lastMove);
00247         // no more moves possible
00248         if (nextMove == SingleMove(0,biu::RNAStructure::INVALID_INDEX)) {
00249             return NULL;
00250         }
00251         else {
00252             S_RNAfe_SingleM* rnaState =
00253              dynamic_cast<S_RNAfe_SingleM*>(elem);
00254             // undo last move
00255             rnaState->rnaFreeEnergy.applySingleMoveInPlace(myitstate->lastMove);
00256             // perform next move
00257             rnaState->rnaFreeEnergy.applySingleMoveInPlace(nextMove);
00258             myitstate->lastMove = nextMove;
00259             return rnaState;
00260         }
00261     }
00262 
00263     // RandomNeighborList
00264     S_RNAfe_SingleM::RandomNeighborList::RandomNeighborList(
00265             const S_RNAfe_SingleM* _origin)
00266      :  origin(_origin)
00267     {
00268     }
00269 
00270     S_RNAfe_SingleM::RandomNeighborList::~RandomNeighborList() {
00271     }
00272 
00273     void 
00274     S_RNAfe_SingleM::RandomNeighborList::switchMode(
00275             ItState* itstate) const 
00276     {
00277 
00278         ItState* myitstate = static_cast<ItState*>(itstate);
00279 
00280         SingleMove nextMove = origin->firstValidSingleMove();
00281 
00282         // loop while valid moves exist
00283         while (nextMove != SingleMove(0,biu::RNAStructure::INVALID_INDEX)) {
00284             // add all valid and unchosen moves to unchosenValidMoves
00285             if (myitstate->chosenMoves.find(nextMove) == 
00286                  myitstate->chosenMoves.end()) {
00287                 myitstate->unchosenValidMoves.push_back(nextMove);
00288             }
00289             nextMove = origin->nextValidSingleMove(nextMove);
00290         }
00291     }
00292 
00293     State* 
00294     S_RNAfe_SingleM::RandomNeighborList::first(
00295               State::NeighborList::ItState** itstate) const 
00296     {
00297         if (*itstate != NULL) delete *itstate;
00298 
00299         *itstate = new ItState();
00300         S_RNAfe_SingleM* rnaState = 
00301          new S_RNAfe_SingleM(*origin);
00302 
00303         return next(*itstate, rnaState);
00304     }
00305 
00306     State* 
00307     S_RNAfe_SingleM::RandomNeighborList::next(
00308               State::NeighborList::ItState* itstate, State* elem) const 
00309     {
00310         assertbiu(elem != NULL, "Elem is not allowed to be NULL");
00311 
00312         ItState* myitstate = static_cast<ItState*>(itstate);
00313         S_RNAfe_SingleM* rnaState =
00314          dynamic_cast<S_RNAfe_SingleM*>(elem);
00315 
00316         if (myitstate->switchModeValue > 0) {
00317             // positions the move will be applied to
00318             size_t pos1, pos2;
00319             SingleMove nextMove;
00320             bool foundValidMove = false;
00321 
00322             while (!foundValidMove) {
00323                 pos1 = biu::RNF::getRN() % origin->rnaFreeEnergy.getLength();
00324                 pos2 = biu::RNF::getRN() % origin->rnaFreeEnergy.getLength();
00325                 if (pos1 == pos2) {
00326                     continue;
00327                 }
00328                 nextMove = (pos1 < pos2) ? SingleMove(pos1, pos2) : SingleMove(pos2, pos1);
00329         
00330                 if (origin->rnaFreeEnergy.isValidSingleMove(nextMove)) {
00331                     if (!(myitstate->chosenMoves.insert(nextMove).second)) {
00332                         // move has already been chosen --> try next
00333                         myitstate->switchModeValue--;
00334                         if (myitstate->switchModeValue == 0) {
00335                             switchMode(myitstate);
00336                             break;
00337                         }
00338                     }
00339                         // move hasn't been chosen yet and is valid
00340                         // set rnaState to the state of origin of the neighbors
00341                     rnaState->rnaFreeEnergy = origin->rnaFreeEnergy;
00342                     rnaState->rnaFreeEnergy.applySingleMoveInPlace(
00343                      nextMove);
00344                     foundValidMove = true;
00345                 }   
00346             }
00347         } 
00348         if (myitstate->switchModeValue == 0) {
00349             size_t n = myitstate->unchosenValidMoves.size();
00350             if (n == 0) {
00351                 return NULL;
00352             }
00353             else {
00354                 size_t i = biu::RNF::getRN() % n;
00355                     // set rnaState to the state of origin of the neighbors
00356                 rnaState->rnaFreeEnergy = origin->rnaFreeEnergy;
00357                 rnaState->rnaFreeEnergy.applySingleMoveInPlace(
00358                  myitstate->unchosenValidMoves[i]);
00359                 myitstate->unchosenValidMoves[i] =
00360                  myitstate->unchosenValidMoves[n-1];
00361                 myitstate->unchosenValidMoves.resize(n-1);
00362             }
00363         }
00364         return rnaState;
00365     }
00366     
00367     State*  
00368     S_RNAfe_SingleM::getRandomNeighbor(State* inPlaceNeigh) const 
00369     {
00370         S_RNAfe_SingleM* neigh = NULL;
00371             // copy this state
00372         if (inPlaceNeigh != NULL) {
00373             neigh = dynamic_cast<S_RNAfe_SingleM*>(inPlaceNeigh);
00374             assertbiu(neigh != NULL, "inPlaceNeigh is no S_RNAfe_SingleM"); 
00375             (*neigh) = (*this); 
00376         } else {
00377             neigh = new S_RNAfe_SingleM(*this);
00378         }
00379         
00380         size_t pos1, pos2;
00381         SingleMove nextMove;
00382 
00383         while (true) {
00384             pos1 = biu::RNF::getRN() % rnaFreeEnergy.getLength();
00385             pos2 = biu::RNF::getRN() % rnaFreeEnergy.getLength();
00386             if (pos1 == pos2) {
00387                 continue;
00388             }
00389             nextMove = (pos1 < pos2) ? SingleMove(pos1, pos2) : SingleMove(pos2, pos1);
00390             // move has already been chosen
00391             if (rnaFreeEnergy.isValidSingleMove(nextMove)) {
00392                     // set rnaState to the state of origin of the neighbors
00393                 neigh->rnaFreeEnergy.applySingleMoveInPlace( nextMove );
00394                 break;
00395             }   
00396         }
00397         return neigh;
00398     }
00399 
00400     
00401 
00403     
00404         /* Access to a compressed sequence representation of the state.
00405          * @return the compressed sequence representation
00406          */
00407     CSequence  
00408     S_RNAfe_SingleM::compress(void) const {
00409         return rnaFreeEnergy.getStructureAlphabet()->compress(rnaFreeEnergy.getStructureRef());
00410     }
00411     
00412         /* Access to a compressed sequence representation of the state.
00413          * @param toFill a data structure to write the compressed 
00414          *               representation too
00415          * @return the compressed sequence representation
00416          */
00417     CSequence&  
00418     S_RNAfe_SingleM::compress(CSequence& toFill) const {
00419         toFill = rnaFreeEnergy.getStructureAlphabet()->compress(rnaFreeEnergy.getStructureRef());
00420         return toFill;
00421     }
00422     
00423         /* Uncompresses a compressed sequencce representation into a new
00424          * State object.
00425          * @param cseq the compressed sequence representation of a state
00426          * @param toFill a state object to uncompress too or NULL if a new 
00427          *               object has to be created
00428          * @return new State object that is encoded in cseq or NULL in error
00429          *         case.
00430          */
00431     State*  
00432     S_RNAfe_SingleM::uncompress(const CSequence& cseq, State* toFill) const {
00433 
00434         biu::Structure str = rnaFreeEnergy.getStructureAlphabet()->decompress(cseq,rnaFreeEnergy.getStructureRef().size());
00435           // error case
00436         if (str.size() != rnaFreeEnergy.getStructureRef().size())
00437             return NULL;
00438 
00439         S_RNAfe_SingleM* ret = NULL;
00440             // use second function
00441         if (toFill == NULL) {
00442             ret = this->clone();
00443         } else {
00444             ret = dynamic_cast<S_RNAfe_SingleM*>(toFill);
00445         }
00446         assertbiu(ret != NULL, "given State toFill is no S_RNAfe_SingleM object.");
00447             
00448         ret->rnaFreeEnergy.setStructure(str);
00449         
00450         return ret;
00451     }
00452     
00453         /* Uncompresses a compressed sequencce representation into a this
00454          * State object.
00455          * @param cseq the compressed sequence representation of a state
00456          * @return this or NULL in error case
00457          */
00458     State*  
00459     S_RNAfe_SingleM::uncompress(const CSequence& cseq) {
00460         
00461         biu::Structure str = rnaFreeEnergy.getStructureAlphabet()->decompress(cseq,rnaFreeEnergy.getStructureRef().size());
00462         
00463         if (str.size() != rnaFreeEnergy.getStructureRef().size())
00464             return NULL;
00465         
00466         rnaFreeEnergy.setStructure(str);
00467         
00468         return this;
00469     }
00470     
00471 
00472 } // namespace ell