Biorithm  1.1
 All Classes Functions Variables Typedefs Friends
gain-state.h
00001 /**************************************************************************
00002  * Copyright (c) 2001-2011 T. M. Murali                                   *
00003  * Copyright (c) 2011 Phillip Whisenhunt                                  *
00004  * Copyright (c) 2011 David Badger                                        *
00005  * Copyright (c) 2010 Jacqueline Addesa                                   *
00006  *                                                                        *
00007  * This file is part of Biorithm.                                         *
00008  *                                                                        *
00009  * Biorithm is free software: you can redistribute it and/or modify       *
00010  * it under the terms of the GNU General Public License as published by   *
00011  * the Free Software Foundation, either version 3 of the License, or      *
00012  * (at your option) any later version.                                    *
00013  *                                                                        *
00014  * Biorithm is distributed in the hope that it will be useful,            *
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
00017  * GNU General Public License for more details.                           *
00018  *                                                                        *
00019  * You should have received a copy of the GNU General Public License      *
00020  * along with Biorithm.  If not, see <http://www.gnu.org/licenses/>.      *
00021  *                                                                        *
00022  **************************************************************************/
00023 
00030 // Purpose: classes to represent the state of a node in GAIN.
00031 
00032 #ifndef _GAIN_STATE_H
00033 #define _GAIN_STATE_H
00034 
00035 #include <fstream>
00036 #include <map>
00037 using namespace std;
00038 
00039 #include "old-annotations.h"
00040 
00041 // enum MyGainTriState { NOT_ANNOTATED_STATE = -1, HYPOTHETICAL_STATE,
00042 //                              ANNOTATED_STATE};
00043 typedef MyGainAnnotationType MyGainTriStateType;
00044 // allow only two states. i must distinguish MyGainBiStateType from
00045 // MyGainTriStateType because the template specialisations
00046 // MyGainState< MyGainBiStateType >::collapse() and MyGainState<
00047 // MyGainTriStateType >::collapse() must do different things.
00048 enum MyGainBiStateType { BI_HYPOTHETICAL_STATE = 0, BI_ANNOTATED_STATE};
00049 //typedef MyGainTriStateType MyGainBiStateType;
00050 // class MyGainBiStateType : public MyGainTriStateType
00051 // {};
00052 
00053 // how much uglier can my code get? i need this conversion in MyOneVersusNoneGainAlgo::computeCrossValidationResults().
00054 inline MyGainTriStateType convertState(MyGainBiStateType in)
00055 {
00056   if (BI_HYPOTHETICAL_STATE == in)
00057     return(HYPOTHETICAL_STATE);
00058   if (BI_ANNOTATED_STATE == in)
00059     return(ANNOTATED_STATE);
00060 }
00061 
00062 
00070 // class hierarchy of states.
00071 template < typename StateType >
00072 class MyGainState
00073 {
00074 private:
00075   // the weight associated with each state.
00076   map< StateType, MyNT > _stateWeights;
00077 public:
00078   MyGainState()
00079       : _stateWeights()
00080     {}
00090   MyGainState(StateType state, MyNT w = 1)
00091       : _stateWeights()
00092     {
00093       //_stateWeights[state] = 1;
00094       _stateWeights[state] = w;
00095       this->_sanityCheck();
00096     }
00097   virtual ~MyGainState()
00098     {}
00099 
00102   virtual const MyGainState &operator+=(const MyGainState &rhs)
00103     {
00104       typename map< StateType, MyNT >::const_iterator itr;
00105       for (itr = rhs._stateWeights.begin(); itr != rhs._stateWeights.end(); itr++)
00106         _stateWeights[itr->first] += itr->second;
00107       this->_sanityCheck();
00108       return(*this);
00109     }
00110 
00112   virtual const MyGainState &operator*(MyNT weight)
00113     {
00114       typename map< StateType, MyNT >::const_iterator itr;
00115       for (itr = _stateWeights.begin(); itr != _stateWeights.end(); itr++)
00116         _stateWeights[itr->first] *= weight;
00117       this->_sanityCheck();
00118       return(*this);
00119     } 
00120 
00121   virtual bool operator==(const MyGainState &rhs) const
00122     {
00123       return(isEqual(rhs));
00124     }
00125 
00126   virtual bool isEqual(const MyGainState &rhs) const
00127     {
00128       typename map< StateType, MyNT >::const_iterator itr;
00129       for (itr = rhs._stateWeights.begin(); itr != rhs._stateWeights.end(); itr++)
00130         if (_stateWeights.find(itr->first)->second != itr->second)
00131           return(false);
00132       return(true);
00133     }
00134 
00135   virtual bool isEqual(const MyGainState &rhs, MyNT epsilon) const
00136     {
00137       typename map< StateType, MyNT >::const_iterator itr;
00138       for (itr = rhs._stateWeights.begin(); itr != rhs._stateWeights.end(); itr++)
00139         if (fabs(_stateWeights.find(itr->first)->second - itr->second) > epsilon)
00140           return(false);
00141       return(true);
00142     }
00143 
00148   MyNT getWeight(StateType state) const
00149     {
00150       typename map< StateType, MyNT >::const_iterator itr;
00151       itr = _stateWeights.find(state);
00152       if (_stateWeights.end() == itr)
00153         return(0);
00154       return(itr->second);
00155     }
00156   
00164   StateType collapse(MyNT threshold = 0);
00165   
00168   ostream &print(ostream &str) const
00169     {
00170       typename map< StateType, MyNT >::const_iterator itr;
00171       for (itr = _stateWeights.begin(); itr != _stateWeights.end(); itr++)
00172         str << itr->first << ": " << itr->second << "\t";
00173 //      str << endl;
00174       return(str);
00175     }
00176     
00177   void _sanityCheck() const
00178     {
00179       typename map< StateType, MyNT >::const_iterator itr;
00180       for (itr = _stateWeights.begin(); itr != _stateWeights.end(); itr++)
00181         {
00182           if (itr->second < 0)
00183             cerr << "MyGainState::_sanityCheck: negative weight for state " << itr->first << endl;
00184         }
00185     }
00186 };
00187 
00190 template< typename StateType >
00191 class MyGainStateInfo
00192 {
00193 
00194 private:
00195 
00196   string id;
00197   // initial state.
00198   StateType initialState;
00199   // state in the current iteration.
00200   StateType currentState;
00201   // state in the last iteration.
00202   StateType previousState;
00203   // what is the distinction between all these states? realState is
00204   // the *real* state of the orf. it will never change. initialState
00205   // is the initial state of the orf, at the beginning of
00206   // runGainNet(). for hypothetical proteins, realState always
00207   // equals initialState. the equality holds for all other proteins
00208   // too, except for those that are being cross-validated. for them
00209   // initialState will be HYPOTHETICAL_STATE. currentState is the
00210   // current state in runGainNet() and previousState is the
00211   // previous value of currentState (the value before currentState
00212   // changed or the value of initialState).
00213   //StateType realState;
00214   
00215   bool clamped;
00216 
00217 //   // input is the weighted sum of neighbour states.
00218 //   MyNT currentInput;
00219 //   MyNT previousInput;
00220   
00221 //   // output is contribution to neighbours' input from this org. input
00222 //   // and output may not be the same when i am dividing by the degree.
00223 //   MyNT currentOutput;
00224 //   MyNT previousOutput;
00225   
00226 public:
00227 
00228   string getId() const
00229   {
00230     return(id);
00231   }
00232 
00233   void setId(string _id)
00234   {
00235     id = _id;
00236   }
00237 
00238   StateType getInitialState() const
00239   {
00240     return(initialState);
00241   }
00242   
00243   StateType getCurrentState() const
00244   {
00245     return(currentState);
00246   }
00247   
00248   StateType getPreviousState() const
00249   {
00250     return(previousState);
00251   }
00252   
00253   /*StateType getRealState() const
00254   {
00255     return(realState);
00256   }*/
00257 //   // given an input and a theshold, compute the corr. state.
00258 //   static StateType computeState(MyNT input, MyNT threshold)
00259 //     {
00260 //       if (input < threshold)
00261 //         return(NOT_ANNOTATED_STATE);
00262 //       // this policy is better than not checking if input and
00263 //       // threshold are equal since it makes solitary nodes and nodes
00264 //       // all of whose neighbours are in HYPOTHETICAL_STATE also to be
00265 //       // in HYPOTHETICAL_STATE.
00266 //       if (input == threshold)
00267 //         return(HYPOTHETICAL_STATE);
00268       
00269 //       // i don't allow a node to go into HYPOTHETICAL_STATE. it can be
00270 //       // in that state only at the beginning. NOT A GOOD POLICY. see
00271 //       // the comment above.
00272 //       return(ANNOTATED_STATE);
00273 //     }
00274   
00275   // compute the current state given the current input.
00276 //   StateType computeCurrentState(MyNT threshold) const
00277 //     {
00278 //       return(computeState(currentInput, threshold));
00279 //     }
00280   
00281   
00282 //   // flip state from ANNOTATED_STATE to NOT_ANNOTATED_STATE or vice-versa.
00283 //   void flipState()
00284 //     {
00285 //       previousState = currentState;
00286 //       if (ANNOTATED_STATE == currentState)
00287 //         currentState = NOT_ANNOTATED_STATE;
00288 //       else 
00289 //         currentState = ANNOTATED_STATE;
00290 //     }
00291   
00292   StateType getState() const
00293   {
00294     return(currentState);
00295   }
00296 
00297 
00298   // set the state to be newState.
00299   void setState(StateType newState)
00300     {
00301       previousState = currentState;
00302       currentState = newState;
00303     }
00304 
00305   void initialiseState(StateType state)
00306   {
00307     //realState = initialState = state;
00308     initialState = state;
00309     currentState = previousState = initialState;
00310 #ifdef DEBUG
00311 //    state.print(cout);
00312 #endif// DEBUG    
00313   }
00314   
00315   /*void setRealState(StateType state)
00316   {
00317         realState = state;
00318   }*/
00319 
00320   
00321   // update the state based on the threshold (if need be).
00322 //   void updateState(MyNT threshold)
00323 //     {
00324 //       previousState = currentState;
00325 //       currentState = computeCurrentState(threshold);
00326 //     }
00327   
00328 //   // a node has flipped if the sign of (energy - threshold) is
00329 //   // different from the the sign of currentState, i.e., if the product
00330 //   // of these two numbers is negative.
00331 //   bool checkIfFlipped(MyNT threshold) const
00332 //     {
00333 //       // if currentInput equals threshold, then the rhs is always 0 so
00334 //       // the test returns false, which is incorrect, since i want
00335 //       // ANNOTATED_STATE $\equiv$ (currentInput >= threshold).
00336 //       //
00337 //       if (currentInput >= threshold)
00338 //         // new state will be ANNOTATED_STATE so i return true if the
00339 //         // currentState is NOT_ANNOTATED_STATE.
00340 //         return(NOT_ANNOTATED_STATE == currentState);
00341 //       // currentInput < threshold, so i return true if the current
00342 //       // state is ANNOTATED_STATE.
00343 //       return(ANNOTATED_STATE == currentState);
00344 //     }
00345   
00346 
00347   
00348   // in the version of the algorithm where the node can have any
00349   // state, it is better to check if the node has a "changed" state
00350   // rather than a "flipped" state.
00351 //   bool checkIfChanged(MyNT threshold, StateType *newState = NULL) const
00352 //     {
00353 //       StateType state = computeCurrentState(threshold);
00354 //       if (newState)
00355 //         *newState = state;
00356 //       return(state != currentState);
00357 //     }
00358 
00368   bool hasConverged()
00369     {
00370       return(currentState.collapse() == previousState.collapse());
00371     }
00372   
00373   
00380   bool hasConvergedApproximately(MyNT epsilon = 1e-03) const
00381     {
00382       return(currentState.isEqual(previousState, epsilon));
00383     }
00384   
00385   
00386   bool isClamped() const
00387   {
00388     return(clamped);
00389   }
00390 
00391   void clamp()
00392   {
00393     clamped = true;
00394   }
00395 
00396   void unclamp()
00397   {
00398     clamped = false;
00399   }
00400   
00401 };
00402 
00403 // each value of MyGainBiState is a map whose keys can take the two
00404 // legal values of MyGainBiStateType.
00405 typedef MyGainState< MyGainBiStateType > MyGainBiState;
00406 // notice that the template parameter is the type i just defined. 
00407 typedef MyGainStateInfo< MyGainBiState > MyGainBiStateInfo;
00408 
00409 // each value of MyGainTriState is a map whose keys can take the three
00410 // legal values of MyGainTriStateType.
00411 typedef MyGainState< MyGainTriStateType > MyGainTriState;
00412 // notice that the template parameter is the type i just defined. 
00413 typedef MyGainStateInfo< MyGainTriState > MyGainTriStateInfo;
00414 
00415 // template specialisation.
00416 
00417 #endif // _GAIN-STATE_H
00418 
 All Classes Functions Variables Typedefs Friends