]> ruin.nu Git - germs.git/blobdiff - src/geneorder.cpp
GeneOrder::reverse implemented
[germs.git] / src / geneorder.cpp
index 31461a1d366abb015cb3815e4376b74a8e77a2b1..23bb9623513e1077b9a937e4a8a0ef48993efd1d 100644 (file)
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
  ***************************************************************************/
 
-#include "geneorder.h"
-
+#include <algorithm>
+#include <stdexcept>
+#include <cstdlib>
 using namespace std;
 
+#include "geneorder.h"
+
 /**
  * \file GeneOrder.cpp
  * Implements the GeneOrder class
@@ -30,11 +33,36 @@ using namespace std;
  */
 
 
-
 GeneOrder::GeneOrder(const GeneOrder& go){
        _geneorder = go._geneorder;
 }
 
+void GeneOrder::pad(){
+       if (_geneorder[0] != 0)
+               _geneorder.insert(_geneorder.begin(),0);
+       if(_geneorder.back() != static_cast<Gene>(_geneorder.size() - 1))
+               _geneorder.push_back(_geneorder.size());
+}
+
+struct Abs{
+       Gene operator()(Gene x) const{
+               return abs(x);
+       }
+};
+
+void GeneOrder::verify(){
+       if(_geneorder[0] != 0)
+               throw invalid_argument("Permutation doesn't start with 0");
+       if ( _geneorder.back() != static_cast<Gene>(_geneorder.size() - 1))
+               throw invalid_argument("Permutation doesn't end with n+1");
+
+       GeneList genes(_geneorder);
+       transform(genes.begin(),genes.end(),genes.begin(),Abs());
+       sort(genes.begin(),genes.end());
+       if (unique(genes.begin(),genes.end()) != genes.end())
+               throw std::invalid_argument("Not all genes are present exactly 1 time");
+}
+
 
 GeneOrder::~GeneOrder(){
 }
@@ -49,14 +77,43 @@ const GeneOrder& GeneOrder::operator=(const GeneOrder& go){
  */
 const Gene& GeneOrder::operator[](size_type i) const{
        if (i < 0 || i >= _geneorder.size())
-               throw out_of_range("Index is not in valid range");
+               throw out_of_range("Indexis not in valid range");
        return _geneorder[i];
 }
 
-int GeneOrder::size() const{
+GeneOrder::size_type GeneOrder::size() const{
        return _geneorder.size();
 }
 
 const GeneOrder::GeneList& GeneOrder::list() const{
        return _geneorder;
 }
+
+
+GeneOrder::iterator GeneOrder::begin() const{
+       return _geneorder.begin();
+}
+
+GeneOrder::iterator GeneOrder::end() const{
+       return _geneorder.end();
+}
+
+struct Sign{
+       Gene operator()(Gene x) const{
+               return x*-1;
+       }
+};
+
+void GeneOrder::reverse(size_type i, size_type j){
+       if (i > j)
+               throw out_of_range("i can't be bigger than j");
+       if (i < 0)
+               throw out_of_range("Index i is not in valid range");
+       if (j >= _geneorder.size())
+               throw out_of_range("Index j is not in valid range");
+       GeneList::iterator begin = _geneorder.begin()+i;
+       GeneList::iterator end = _geneorder.begin()+j+1;
+
+       transform(begin,end,begin,Sign());
+       std::reverse(begin,end);
+}