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:
swaits committed 2007-08-10 23:43:15 +00:00
1 parent 6f03c0b106
commit aac0b98ba9
4 files changed
+91 -34

No files matched your search

+24 -1
View File
@@ -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
+51 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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();
} }
}; };