renamed DE::Engine::CalculateError to DE::Engine::TestFitness
added ErrorAccumulator to aid in calculating RMSE converted piecewiseapprox.cpp and polyapprox.cpp to use new pure virtual method name and ErrorAccumulator
This commit is contained in:
1 parent
6f03c0b106
commit
aac0b98ba9
4 files changed
+91
-34
No files matched your search
@@ -23,12 +23,35 @@ namespace DE
|
|||||||
void SetRange(unsigned int i, double minimum, double maximum);
|
void SetRange(unsigned int i, double minimum, double maximum);
|
||||||
void SetRange(const Vector<DIM>& minimum, const Vector<DIM>& maximum);
|
void SetRange(const Vector<DIM>& minimum, const Vector<DIM>& maximum);
|
||||||
|
|
||||||
virtual double CalculateError(const double testcase[DIM], bool& stop) = 0;
|
virtual double TestFitness(const double testcase[DIM], bool& stop) = 0;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
bool Solve(unsigned int maxgenerations = 1000000000);
|
bool Solve(unsigned int maxgenerations = 1000000000);
|
||||||
bool RunOneGeneration();
|
bool RunOneGeneration();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// helper class for accumulating error and calculating
|
||||||
|
// root mean square error
|
||||||
|
class ErrorAccumulator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ErrorAccumulator();
|
||||||
|
virtual ~ErrorAccumulator();
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
void AddTestCase(double expected, double actual);
|
||||||
|
double GetRMSE();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void CalculateError();
|
||||||
|
|
||||||
|
unsigned int num_tests; // # of test cases
|
||||||
|
double sum_error_squared; // sum of error^2
|
||||||
|
double error_rmse; // root mean square error (-1 == "dirty" flag)
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// randomly select unique individuals
|
// randomly select unique individuals
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ bool DE::Engine<DIM,POPSIZE>::RunOneGeneration()
|
|||||||
MakeTrial_randtobest1exp(candidate,trial);
|
MakeTrial_randtobest1exp(candidate,trial);
|
||||||
|
|
||||||
// determine fitness of trial individual
|
// determine fitness of trial individual
|
||||||
double trialfitness = CalculateError(trial,success);
|
double trialfitness = TestFitness(trial,success);
|
||||||
|
|
||||||
// see if the trial improved current candidate in population
|
// see if the trial improved current candidate in population
|
||||||
if ( trialfitness < fitness[candidate] )
|
if ( trialfitness < fitness[candidate] )
|
||||||
@@ -448,5 +448,55 @@ inline void DE::Engine<DIM,POPSIZE>::MakeTrial_rand2bin(unsigned int candidate,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline DE::Engine<DIM,POPSIZE>::ErrorAccumulator::ErrorAccumulator()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline DE::Engine<DIM,POPSIZE>::ErrorAccumulator::~ErrorAccumulator()
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline void DE::Engine<DIM,POPSIZE>::ErrorAccumulator::Clear()
|
||||||
|
{
|
||||||
|
num_tests = 0;
|
||||||
|
sum_error_squared = 0.0;
|
||||||
|
error_rmse = 0.0; // initial error == zero
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline void DE::Engine<DIM,POPSIZE>::ErrorAccumulator::AddTestCase(double expected, double actual)
|
||||||
|
{
|
||||||
|
double e = expected - actual; // compute error
|
||||||
|
sum_error_squared += e * e; // add to sum of error^2
|
||||||
|
num_tests += 1; // increment total test count
|
||||||
|
error_rmse = -1.0; // mark as dirty
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline double DE::Engine<DIM,POPSIZE>::ErrorAccumulator::GetRMSE()
|
||||||
|
{
|
||||||
|
if ( error_rmse < 0.0 ) // recalculate if set to "dirty"
|
||||||
|
CalculateError();
|
||||||
|
|
||||||
|
return error_rmse;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int DIM, unsigned int POPSIZE>
|
||||||
|
inline void DE::Engine<DIM,POPSIZE>::ErrorAccumulator::CalculateError()
|
||||||
|
{
|
||||||
|
// convert squared error to root mean squared error
|
||||||
|
error_rmse = sqrt(sum_error_squared / (double)num_tests);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __de_inl__
|
#endif // __de_inl__
|
||||||
|
|
||||||
+8
-16
@@ -39,37 +39,29 @@ class PolySearch: public DE::Engine<NUM_COEFFICIENTS>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// this method is called by the DE::Engine::Solve() to test a single DE individual
|
// this method is called by the DE::Engine::Solve() to test a single DE individual
|
||||||
double CalculateError(const double testcase[NUM_COEFFICIENTS], bool& stop)
|
double TestFitness(const double testcase[NUM_COEFFICIENTS], bool& stop)
|
||||||
{
|
{
|
||||||
double error = 0.0;
|
ErrorAccumulator e;
|
||||||
unsigned int test_count = 0;
|
|
||||||
|
|
||||||
// accumulate squared error
|
// accumulate squared error
|
||||||
for ( double i=-2.5;i<=2.5;i+=0.01 )
|
for ( double i=-2.5;i<=2.5;i+=0.01 )
|
||||||
{
|
{
|
||||||
// test
|
// test
|
||||||
double test = CalculatePiecewise(i,NUM_COEFFICIENTS,testcase);
|
double actual = CalculatePiecewise(i,NUM_COEFFICIENTS,testcase);
|
||||||
double actual = TargetFunction(i);
|
double expected = TargetFunction(i);
|
||||||
|
|
||||||
// accumulate error^2
|
// accumulate error
|
||||||
double e = test - actual;
|
e.AddTestCase(expected,actual);
|
||||||
error += e * e;
|
|
||||||
|
|
||||||
// inc test count (divisor to get from SE to MSE)
|
|
||||||
test_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert SE to RMSE
|
|
||||||
error = sqrt(error / (double)test_count);
|
|
||||||
|
|
||||||
// set stop flag if the error is really low
|
// set stop flag if the error is really low
|
||||||
if ( error < 0.0000001 )
|
if ( e.GetRMSE() < 0.0000001 )
|
||||||
{
|
{
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return error;
|
return e.GetRMSE();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+8
-16
@@ -39,37 +39,29 @@ class PolySearch: public DE::Engine<NUM_COEFFICIENTS>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// this method is called by the DE::Engine::Solve() to test a single DE individual
|
// this method is called by the DE::Engine::Solve() to test a single DE individual
|
||||||
double CalculateError(const double testcase[NUM_COEFFICIENTS], bool& stop)
|
double TestFitness(const double testcase[NUM_COEFFICIENTS], bool& stop)
|
||||||
{
|
{
|
||||||
double error = 0.0;
|
ErrorAccumulator e;
|
||||||
unsigned int test_count = 0;
|
|
||||||
|
|
||||||
// accumulate squared error
|
// accumulate squared error
|
||||||
for ( double i=-1.25;i<=1.25;i+=0.001 )
|
for ( double i=-1.25;i<=1.25;i+=0.001 )
|
||||||
{
|
{
|
||||||
// test
|
// test
|
||||||
double test = CalculatePolynomial(i,NUM_COEFFICIENTS,testcase);
|
double actual = CalculatePolynomial(i,NUM_COEFFICIENTS,testcase);
|
||||||
double actual = TargetFunction(i);
|
double expected = TargetFunction(i);
|
||||||
|
|
||||||
// accumulate error^2
|
// accumulate error
|
||||||
double e = test - actual;
|
e.AddTestCase(expected, actual);
|
||||||
error += e * e;
|
|
||||||
|
|
||||||
// inc test count (divisor to get from SE to MSE)
|
|
||||||
test_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert SE to RMSE
|
|
||||||
error = sqrt(error / (double)test_count);
|
|
||||||
|
|
||||||
// set stop flag if the error is really low
|
// set stop flag if the error is really low
|
||||||
if ( error < 0.0000001 )
|
if ( e.GetRMSE() < 0.0000001 )
|
||||||
{
|
{
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return error;
|
return e.GetRMSE();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user