• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/binary/Binary.cpp

00001 #include <cmath>
00002 #include "../ECF_base.h"
00003 #include "Binary.h"
00004 #include<sstream>
00005 
00006 namespace Binary
00007 {
00008 
00009 double Binary::logbase (double a, double base) 
00010 {
00011     return log(a) / log(base);
00012 }
00013 
00014 
00015 double Binary::round(double val, int decimals)
00016 {
00017     double r = val * pow(10., decimals);
00018     r = floor(r + 0.5);
00019     return r / pow(10., decimals);
00020 }
00021 
00022 
00023 void Binary::registerParameters(StateP state)
00024 {
00025     registerParameter(state, "lbound", (voidP) new double(0), ECF::DOUBLE, 
00026         "lower bound for each variable (mandatory)");
00027     registerParameter(state, "ubound", (voidP) new double(10), ECF::DOUBLE,
00028         "upper bound for each variable (mandatory)");
00029     registerParameter(state, "precision", (voidP) new uint(1), ECF::UINT,
00030         "number of digits after the decimal point (mandatory)");
00031     registerParameter(state, "dimension", (voidP) new uint(1), ECF::UINT,
00032         "number of real valued variables (mandatory)");
00033     registerParameter(state, "rounding", (voidP) new uint(0), ECF::UINT,
00034         "should the real value be rounded to the 'precision'-th decimal (default: no)");
00035 }
00036 
00037 
00038 bool Binary::initialize (StateP state)
00039 {
00040     if(!isParameterDefined(state, "lbound") ||
00041         !isParameterDefined(state, "ubound") ||
00042         !isParameterDefined(state, "precision") ||
00043         !isParameterDefined(state, "dimension")) {
00044             ECF_LOG_ERROR(state, "Error: required parameters for Binary genotype not defined (lbound, ubound, precision, dimension)!");
00045             throw("");
00046     }
00047 
00048     voidP genp = getParameterValue(state, "lbound");
00049     minValue_ = *((double*) genp.get());
00050 
00051     genp = getParameterValue(state, "ubound");
00052     maxValue_ = *((double*) genp.get());
00053 
00054     if(minValue_ >= maxValue_) {
00055         ECF_LOG_ERROR(state, "Error: 'lbound' must be smaller than 'ubound' for Binary genotype!");
00056         throw("");
00057     }
00058 
00059     genp = getParameterValue(state, "precision");
00060     nDecimal_ = *((uint*) genp.get());
00061 
00062     if(nDecimal_ > 16) {
00063         ECF_LOG_ERROR(state, "Error: 'precision' too large (> 16) for Binary genotype!");
00064         throw("");
00065     }
00066 
00067     genp = getParameterValue(state, "dimension");
00068     nDimension_ = *((uint*) genp.get());
00069 
00070     if(nDimension_ < 1) {
00071         ECF_LOG_ERROR(state, "Error: 'dimension' must be > 0 for Binary genotype!");
00072         throw("");
00073     }
00074 
00075     genp = getParameterValue(state, "rounding");
00076     bRounding_ = (*((uint*) genp.get())) == 0 ? false : true;
00077 
00078     double numIndividual = ((maxValue_ - minValue_) * pow(10., (int) nDecimal_));
00079     nBits_ = static_cast<int> (logbase(numIndividual, 2) + 1);
00080 
00081     variables.resize(nDimension_);
00082     decValue.resize(nDimension_);
00083     realValue.resize(nDimension_);
00084     vBool_.resize(nBits_); 
00085 
00086     potention_ = static_cast<long> (pow(2., (int) nBits_) - 1);
00087 
00088     // randomly create each dimension
00089     for (uint i = 0; i < nDimension_; i++){
00090         realValue[i] = ( minValue_ + (maxValue_ - minValue_) * state->getRandomizer()->getRandomDouble() );
00091         decValue[i] = static_cast<long int> ((realValue[i] - minValue_) / (maxValue_ - minValue_) * potention_);
00092         if(bRounding_) {
00093             realValue[i] = round(realValue[i], nDecimal_);
00094         }
00095 
00096         long dec = decValue[i];
00097         for (int iBit = nBits_; iBit > 0; dec = dec / 2, iBit--) {
00098             // the bit with index 0 is the most significant bit
00099             vBool_[iBit - 1] = (dec % 2) ? true:false;
00100         }
00101         variables[i] = vBool_;
00102     }
00103 
00104     return true;
00105 }
00106 
00107 
00108 bool Binary::update (void)
00109 {
00110     for (uint iDim = 0; iDim < nDimension_; iDim++) {
00111         long dec = 0;
00112         long weight = 1;
00113         for (int iBit = nBits_ - 1; iBit >= 0; iBit--) {
00114             dec += static_cast<int>(variables[iDim][iBit]) * weight;
00115             weight *= 2;
00116         }
00117 
00118         decValue[iDim] = dec;
00119         realValue[iDim] = minValue_ + (maxValue_ - minValue_) / potention_ * dec;
00120         if(bRounding_) {
00121             realValue[iDim] = round(realValue[iDim], nDecimal_);
00122         }
00123     }
00124 
00125     return true;
00126 }
00127 
00128 
00129 void Binary::write(XMLNode &xBinary)
00130 {
00131     xBinary = XMLNode::createXMLTopNode("Binary");
00132     std::stringstream sValue;
00133     sValue << nDimension_;
00134     xBinary.addAttribute("size", sValue.str().c_str());
00135 
00136     sValue.str("");
00137     for(uint iVar = 0; iVar < nDimension_; iVar++)
00138         sValue << "\t" << realValue[iVar];
00139     xBinary.addText(sValue.str().c_str());
00140 }
00141 
00142 
00143 void Binary::read(XMLNode& xBinary)
00144 {
00145     XMLCSTR values = xBinary.getText();
00146     std::stringstream sValues;
00147     sValues << values;
00148 
00149     for(uint iVar = 0; iVar < nDimension_; iVar++) {
00150         sValues >> realValue[iVar];
00151         decValue[iVar] = static_cast<long int> ((realValue[iVar] - minValue_) / (maxValue_ - minValue_) * potention_);
00152 
00153         long dec = decValue[iVar];
00154         for (int iBit = nBits_; iBit > 0; dec = dec/2, iBit--) {
00155             vBool_[iBit - 1] = (dec % 2) ? true:false;
00156         }
00157         variables[iVar] = vBool_;
00158     }
00159 
00160 }
00161 
00162 }

Generated on Tue Nov 4 2014 13:04:30 for ECF by  doxygen 1.7.1