ECF 1.5
Binary.cpp
1#include <cmath>
2#include "../ECF_base.h"
3#include "Binary.h"
4#include<sstream>
5
6namespace Binary
7{
8
9double Binary::logbase (double a, double base)
10{
11 return log(a) / log(base);
12}
13
14
15double Binary::round(double val, int decimals)
16{
17 double r = val * pow(10., decimals);
18 r = floor(r + 0.5);
19 return r / pow(10., decimals);
20}
21
22
23void Binary::registerParameters(StateP state)
24{
25 registerParameter(state, "lbound", (voidP) new double(0), ECF::DOUBLE,
26 "lower bound for each variable (mandatory)");
27 registerParameter(state, "ubound", (voidP) new double(10), ECF::DOUBLE,
28 "upper bound for each variable (mandatory)");
29 registerParameter(state, "precision", (voidP) new uint(1), ECF::UINT,
30 "number of digits after the decimal point (mandatory)");
31 registerParameter(state, "dimension", (voidP) new uint(1), ECF::UINT,
32 "number of real valued variables (mandatory)");
33 registerParameter(state, "rounding", (voidP) new uint(0), ECF::UINT,
34 "should the real value be rounded to the 'precision'-th decimal (default: no)");
35}
36
37
38bool Binary::initialize (StateP state)
39{
40 if(!isParameterDefined(state, "lbound") ||
41 !isParameterDefined(state, "ubound") ||
42 !isParameterDefined(state, "precision") ||
43 !isParameterDefined(state, "dimension")) {
44 ECF_LOG_ERROR(state, "Error: required parameters for Binary genotype not defined (lbound, ubound, precision, dimension)!");
45 throw("");
46 }
47
48 voidP genp = getParameterValue(state, "lbound");
49 minValue_ = *((double*) genp.get());
50
51 genp = getParameterValue(state, "ubound");
52 maxValue_ = *((double*) genp.get());
53
54 if(minValue_ >= maxValue_) {
55 ECF_LOG_ERROR(state, "Error: 'lbound' must be smaller than 'ubound' for Binary genotype!");
56 throw("");
57 }
58
59 genp = getParameterValue(state, "precision");
60 nDecimal_ = *((uint*) genp.get());
61
62 if(nDecimal_ > 16) {
63 ECF_LOG_ERROR(state, "Error: 'precision' too large (> 16) for Binary genotype!");
64 throw("");
65 }
66
67 genp = getParameterValue(state, "dimension");
68 nDimension_ = *((uint*) genp.get());
69
70 if(nDimension_ < 1) {
71 ECF_LOG_ERROR(state, "Error: 'dimension' must be > 0 for Binary genotype!");
72 throw("");
73 }
74
75 genp = getParameterValue(state, "rounding");
76 bRounding_ = (*((uint*) genp.get())) == 0 ? false : true;
77
78 double numIndividual = ((maxValue_ - minValue_) * pow(10., (int) nDecimal_));
79 nBits_ = static_cast<int> (logbase(numIndividual, 2) + 1);
80
81 variables.resize(nDimension_);
82 decValue.resize(nDimension_);
83 realValue.resize(nDimension_);
84 vBool_.resize(nBits_);
85
86 potention_ = static_cast<long> (pow(2., (int) nBits_) - 1);
87
88 // randomly create each dimension
89 for (uint i = 0; i < nDimension_; i++){
90 realValue[i] = ( minValue_ + (maxValue_ - minValue_) * state->getRandomizer()->getRandomDouble() );
91 decValue[i] = static_cast<long int> ((realValue[i] - minValue_) / (maxValue_ - minValue_) * potention_);
92 if(bRounding_) {
93 realValue[i] = round(realValue[i], (int)nDecimal_);
94 }
95
96 long dec = decValue[i];
97 for (uint iBit = nBits_; iBit > 0; dec = dec / 2, iBit--) {
98 // the bit with index 0 is the most significant bit
99 vBool_[iBit - 1] = (dec % 2) ? true:false;
100 }
101 variables[i] = vBool_;
102 }
103
104 return true;
105}
106
107
108bool Binary::update (void)
109{
110 for (uint iDim = 0; iDim < nDimension_; iDim++) {
111 long dec = 0;
112 long weight = 1;
113 for (uint iBit = nBits_ - 1; iBit >= 0; iBit--) {
114 dec += static_cast<int>(variables[iDim][iBit]) * weight;
115 weight *= 2;
116 }
117
118 decValue[iDim] = dec;
119 realValue[iDim] = minValue_ + (maxValue_ - minValue_) / potention_ * dec;
120 if(bRounding_) {
121 realValue[iDim] = round(realValue[iDim], (int)nDecimal_);
122 }
123 }
124
125 return true;
126}
127
128
129void Binary::write(XMLNode &xBinary)
130{
131 xBinary = XMLNode::createXMLTopNode("Binary");
132 std::stringstream sValue;
133 sValue << nDimension_;
134 xBinary.addAttribute("size", sValue.str().c_str());
135
136 sValue.str("");
137 for(uint iVar = 0; iVar < nDimension_; iVar++)
138 sValue << "\t" << realValue[iVar];
139 xBinary.addText(sValue.str().c_str());
140}
141
142
143void Binary::read(XMLNode& xBinary)
144{
145 XMLCSTR values = xBinary.getText();
146 std::stringstream sValues;
147 sValues << values;
148
149 for(uint iVar = 0; iVar < nDimension_; iVar++) {
150 sValues >> realValue[iVar];
151 decValue[iVar] = static_cast<long int> ((realValue[iVar] - minValue_) / (maxValue_ - minValue_) * potention_);
152
153 long dec = decValue[iVar];
154 for (uint iBit = nBits_; iBit > 0; dec = dec/2, iBit--) {
155 vBool_[iBit - 1] = (dec % 2) ? true:false;
156 }
157 variables[iVar] = vBool_;
158 }
159
160}
161
162}