diff --git a/de.inl b/de.inl index ace26e9..72dda58 100644 --- a/de.inl +++ b/de.inl @@ -17,7 +17,7 @@ template const double DE::Engine::DEFAULTCROSSOVER = 1.0; template -const double DE::Engine::DEFAULTRANGE= 1000000.0; +const double DE::Engine::DEFAULTRANGE= 10.0; template const double DE::Engine::BIGDOUBLE = 1.79e308; // close to max double diff --git a/example.cpp b/example.cpp deleted file mode 100644 index e3b674e..0000000 --- a/example.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#include "de.h" - -// just a helper function used in calculating the polynomails -double Polynomial(double x, double a, double b, double c, double d) -{ - return a*(x*x*x) + b*(x*x) + c*x + d; -} - -// the function we're searching for -double TargetFunction(double input) -{ - return Polynomial(input,17.0,321.0,-2.0,324.0); -} - -// our DE implementation -class PolySearch: public DE::Engine<4> -{ - public: - double CalculateError(const double testcase[4], bool& stop) - { - double error = 0.0; - for ( int i=-100;i<=100;i++ ) - { - double test = Polynomial((double)i,testcase[0],testcase[1],testcase[2],testcase[3]); - double actual = TargetFunction((double)i); - error += (test-actual)*(test-actual); - } - if ( error < 0.00000000000001 ) - { - stop = true; - } - return error; - } -}; - -// main program -int main() -{ - PolySearch de; - de.Solve(); - return 0; -} diff --git a/polyapprox.cpp b/polyapprox.cpp new file mode 100644 index 0000000..418e756 --- /dev/null +++ b/polyapprox.cpp @@ -0,0 +1,81 @@ +#include +#include + +#include "de.h" + +// the order of the polynomial (actually the number of coefficients, i.e. 1 = constant, 2 = line, etc.) +#define NUM_COEFFICIENTS 3 + +// the function we're searching for +double TargetFunction(double x) +{ + //return 1.0 / (1.0 + exp(-4.9*x)); // Ken Stanley's NEAT activation + //return (1.0 / (1.0 + exp(-4.9*x)) - 0.5) * 2.0; // " " (signed version) + //return (1.0 / (1.0 + exp(-x)) - 0.5) * 2.0; // signed sigmoid + //return exp(-x*x); // gaussian + //return tanh(x); // tanh + //return (2.0/(1.0+exp(-x))-1.0); // tanh approximation + return (x<0.0 ? -1.0 : 1.0) * sqrt(abs(x)); // signed root +} + + +// a helper function used in calculating the polynomials +double CalculatePolynomial(double x, int n_coeffs, const double coeffs[]) +{ + double accum = 0.0; + double xmul = 1.0; + for (int i = n_coeffs-1; i>=0; --i) + { + accum += xmul * coeffs[i]; + xmul *= x; + } + return accum; +} + + +// our DE implementation +class PolySearch: public DE::Engine +{ + public: + // 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 error = 0.0; + unsigned int test_count = 0; + + // accumulate squared error + for ( double i=-1.5;i<=1.5;i+=0.01 ) + { + // test + double test = CalculatePolynomial(i,NUM_COEFFICIENTS,testcase); + double actual = TargetFunction(i); + + // accumulate error^2 + error += (test-actual)*(test-actual); + + // 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 + if ( error < 0.0000001 ) + { + stop = true; + } + + // done + return error; + } +}; + + +// main program +int main() +{ + PolySearch de; + de.Solve(1000); + return 0; +}