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

src/ell/spinglass/S_SG_Ising.cc

Go to the documentation of this file.
00001 #include "ell/spinglass/S_SG_Ising.hh"
00002 #include <biu/assertbiu.hh>
00003 #include "biu/RandomNumberFactory.hh"
00004 
00005 #include <iostream>
00006 
00007 namespace ell
00008 {
00009 
00010     const biu::Alphabet S_SG_Ising::spinAlph = biu::Alphabet("-+",1);
00011     const S_SG_Ising::SpinType S_SG_Ising::SPIN_UP = S_SG_Ising::spinAlph.getElement("+");
00012     const S_SG_Ising::SpinType S_SG_Ising::SPIN_DOWN = S_SG_Ising::spinAlph.getElement("-");
00013     const std::string S_SG_Ising::ID = std::string("ell::S_SG_Ising");
00014 
00015         /* Constructs a spin array of the given size and initializes with 
00016          * SPIN_UP for all spins or a random distribution.
00017          * @param size the size of the spin array
00018          * @param random if true a random initialization is done
00019          */ 
00020     S_SG_Ising::S_SG_Ising(size_t size, bool rand)
00021      :  spin(size,SPIN_UP) 
00022     {
00023         if (rand) {
00024             for (SpinArray::iterator it = spin.begin(); it!=spin.end();it++) {
00025                 *it = ( biu::RNF::getRN(2) == 1 ? SPIN_UP : SPIN_DOWN );
00026             }
00027         }
00028     }
00029     
00030     S_SG_Ising::S_SG_Ising(const std::string & spinStr)
00031      :  spin() 
00032     {
00033         assertbiu(spinAlph.isAlphabetString(spinStr), "given spin string is no +- string");
00034         spin = spinAlph.getSequence(spinStr);
00035     }
00036     
00037     S_SG_Ising::S_SG_Ising(const S_SG_Ising& s2)
00038      : spin(s2.spin)
00039     {
00040     }
00041 
00042     S_SG_Ising::~S_SG_Ising()
00043     {
00044     }
00045     
00046     const std::string & 
00047     S_SG_Ising::getID( void ) const {
00048         return S_SG_Ising::ID; 
00049     }
00050 
00051     bool
00052     S_SG_Ising::operator== (const State& state2) const {
00053         return (this == &state2) || getMinimalDistance(state2) == 0;
00054     }
00055     
00056     bool
00057     S_SG_Ising::operator!= (const State& state2) const {
00058         return (this != &state2) && getMinimalDistance(state2) != 0;
00059     }
00060 
00061     void
00062     S_SG_Ising::operator= (const S_SG_Ising& sg2) {
00063         if (this == &sg2)
00064             return;
00065         spin.resize(sg2.spin.size());
00066         std::copy<SpinArray::const_iterator, SpinArray::iterator>
00067             (   sg2.spin.begin(), sg2.spin.end(), 
00068                 spin.begin());
00069     }
00070 
00071         /* Returns the state specific energy, i.e.
00072          * E = sum ( J(i,j)*spin(i)*spin(j) ) for all 0<=i<j<=spinnumber
00073          * and J(i,j) = 1 iif spin i and j are neighbored and 0 otherwise. */
00074     double  
00075     S_SG_Ising::getEnergy() const {
00076         if (spin.size() == 0)
00077             return 0;
00078         SpinType last = *spin.rbegin();
00079         int e = 0;
00080         for (SpinArray::const_iterator it = spin.begin(); it != spin.end(); it++) {
00081             e += ((*it) == last ? +1 : -1);
00082             last = *it;
00083         }
00084         return -(double)e;
00085     }
00086     
00087         /* Returns the minimal number of steps via valid
00088          *  neighbored states from this to another valid State.
00089          *  @param state2 the State to reach
00090          */
00091     unsigned int
00092     S_SG_Ising::getMinimalDistance(const State& state2) const {
00093         unsigned int minD = UINT_MAX;
00094         const S_SG_Ising* s2 = dynamic_cast<const S_SG_Ising*>(&state2);
00095         if (s2 != NULL && spin.size() == s2->spin.size()) {
00096             minD = 0;
00097             SpinArray::const_iterator is1 = spin.begin(), is2 = s2->spin.begin();
00098             while (is1 != spin.end()) {
00099                 minD += (*is1++ == *is2++ ? 0 : 1); // count different positions
00100             }
00101         }
00102         return minD;
00103     }
00104 
00105         /* Returns a pointer to a clone of the current state. */
00106     S_SG_Ising*
00107     S_SG_Ising::clone(State* toFill) const {
00108         if (toFill == NULL) {
00109             return new S_SG_Ising(*this);
00110         }
00111           // cast toFill
00112         assertbiu( dynamic_cast<S_SG_Ising*>(toFill) != NULL
00113                     , "given State is no S_SG_Ising instance");
00114         S_SG_Ising* s = static_cast<S_SG_Ising*>(toFill);
00115         
00116           // copy data
00117         s->operator=(*this);
00118         
00119         return s;
00120     }
00121     
00124     State* 
00125     S_SG_Ising::fromString(const std::string& stringRep) const {
00126         return new S_SG_Ising(stringRep);
00127     }
00128     
00129         /* Returns a specific std::string representation of this
00130          *  State.
00131          */
00132     std::string 
00133     S_SG_Ising::toString() const {
00134         return spinAlph.getString(spin);
00135     }
00136     
00137     std::string& 
00138     S_SG_Ising::toString( std::string & toFill ) const {
00139         toFill = spinAlph.getString(spin);
00140         return toFill;
00141     }
00142 
00143     // neighborhood
00144         /* Returns a virtual list of all VALID neighbored states in
00145          *  the energy landscape in a specific order.
00146          */
00147     State::NeighborListPtr  
00148     S_SG_Ising::getNeighborList() const {
00149         return NeighborListPtr(new SuccessiveNeighborList(this));
00150     }
00151 
00152         /* Returns a virtual list of all VALID neighbored states in
00153          *  the energy landscape in a random order.
00154          *  If a state is given, this is changed to a neighbor.
00155          */
00156     State::NeighborListPtr  
00157     S_SG_Ising::getRandomNeighborList() const {
00158         return NeighborListPtr(new RandomNeighborList(this));
00159     }
00160     
00161         /* Returns a VALID random neighbored state.
00162          *  If a state is given it is overwritten and changed to a neighbor.
00163          */
00164     State* 
00165     S_SG_Ising::getRandomNeighbor(State* inPlaceNeigh) const {
00166         S_SG_Ising *s2 = NULL;
00167          // copy myself into inPlaceNeigh
00168         if (inPlaceNeigh == NULL) {
00169             s2 = new S_SG_Ising(*this);
00170             inPlaceNeigh = s2;
00171         } else {
00172             s2 = dynamic_cast<S_SG_Ising*>(inPlaceNeigh);
00173             assertbiu(s2 != NULL, "given state is no S_SG_Ising");
00174             *s2 = *this;
00175         }
00176          // get random position to flip
00177         size_t pos = biu::RNF::getRN(spin.size());
00178          // apply spin flip to pos in new state
00179         s2->spin[pos] = flipSpin(spin[pos]);
00180         
00181         return inPlaceNeigh;
00182     }
00183 
00184 
00185       // How many neighbor indices are accessible.
00186       // @return the number of neighbors
00187     size_t 
00188     S_SG_Ising::getNeighborNumber(void) const {
00189         return spin.size();
00190     }
00191     
00192       // Access to a specific neighbor.
00193       // @param index the index of the neighbor in [0, getNeighborNumber())
00194       // @param neigh if != NULL this state should be converted into the 
00195       //              neighbor
00196       // @return the new neighbor state or NULL if the index is >= 
00197       // getNeighborNumber()
00198     State* 
00199     S_SG_Ising::getNeighbor(const size_t index, State* neigh) const {
00200         assertbiu(index < spin.size(), "index out of spin range");
00201         S_SG_Ising* ret = dynamic_cast<S_SG_Ising*>(neigh);
00202         if (ret == NULL) { // create copy
00203             ret = new S_SG_Ising(*this);
00204         } else {
00205             ret->spin = this->spin;
00206         }
00207         ret->spin[index] = flipSpin(spin[index]);
00208         return ret;
00209     }
00210     
00211       // Undo the changes done to this state to generate the given neighbor.
00212       // The goal is to do less operations than doing a full copy like
00213       // (*neigh = *this).
00214       // @param index the neighbor index that was applied last 
00215       //              [ 0, getNeighborNumber() )
00216       // @param neigh the state resulting from the last changes ( != NULL)
00217       // @return the copy of this object via undoing the last changes in 
00218       //         neigh
00219     State* 
00220     S_SG_Ising::undoNeighborChange(const size_t index, State* const neigh) const {
00221         S_SG_Ising* ret = dynamic_cast<S_SG_Ising*>(neigh);
00222         assertbiu(ret != NULL, "given neigh is no S_SG_Ising object");
00223         assertbiu(index < spin.size(), "index out of spin range");
00224         ret->spin[index] = spin[index];
00225         return ret;
00226     }
00227     
00228       // Applies the necessary changes to a given state to get the neighbor.
00229       // Note: neigh is expected to be a copy (i.e. *this == *neigh) and
00230       // therefore direct changes are possible or to be NULL. If 
00231       // (neigh==NULL) a copy of this has to be generated, modified, and
00232       // returned.
00233       // @param index the neighbor to generate
00234       // @param neigh a copy of this the changes should be applied to
00235       // @return the neighbor state of the given index or NULL if the index is
00236       //         out of range
00237     State* 
00238     S_SG_Ising::applyNeighborChange(const size_t index, State* const neigh) const {
00239         assertbiu(index < spin.size(), "index out of spin range");
00240         assertbiu(neigh != NULL, "no state to fill given");
00241         S_SG_Ising* ret = dynamic_cast<S_SG_Ising*>(neigh);
00242         assertbiu(ret != NULL, "given neigh is no S_SG_Ising object");
00243         ret->spin[index] = flipSpin(spin[index]);
00244         return ret;
00245     }
00246     
00247 
00249     
00250         /* Access to a compressed sequence representation of the state.
00251          * @return the compressed sequence representation
00252          */
00253     CSequence  
00254     S_SG_Ising::compress(void) const {
00255         assertbiu(spin.size()>0, "no spins available");
00256         return spinAlph.compress(spin);
00257     }
00258     
00259         /* Access to a compressed sequence representation of the state.
00260          * @param toFill a data structure to write the compressed 
00261          *               representation too
00262          * @return the compressed sequence representation
00263          */
00264     CSequence&  
00265     S_SG_Ising::compress(CSequence& toFill) const {
00266         assertbiu(spin.size()>0, "no spins available");
00267         toFill = spinAlph.compress(spin);
00268         return toFill;
00269     }
00270     
00271         /* Uncompresses a compressed sequencce representation into a new
00272          * State object.
00273          * @param cseq the compressed sequence representation of a state
00274          * @param toFill a state object to uncompress too or NULL if a new 
00275          *               object has to be created
00276          * @return new State object that is encoded in cseq or NULL in error
00277          *         case.
00278          */
00279     State*  
00280     S_SG_Ising::uncompress(const CSequence& cseq, State* toFill) const {
00281         S_SG_Ising* sgi = NULL;
00282         if (toFill == NULL) {
00283             sgi = new S_SG_Ising(*this);
00284         } else {
00285             sgi = dynamic_cast<S_SG_Ising*>(toFill);
00286             assertbiu(sgi != NULL, "given State toFill is no S_SG_Ising instance");
00287         }
00288         sgi->spin = spinAlph.decompress(cseq, spin.size()); 
00289         return sgi;
00290     }
00291     
00292         /* Uncompresses a compressed sequencce representation into a this
00293          * State object.
00294          * @param cseq the compressed sequence representation of a state
00295          * @return this or NULL in error case
00296          */
00297     State*  
00298     S_SG_Ising::uncompress(const CSequence& cseq) {
00299         spin = spinAlph.decompress(cseq, spin.size());
00300         return this;
00301     }
00302     
00303 } // namespace