## ~swaits/differential-evolution

eedade5b63a2502c47173dca576c85004143e3ee — swaits 17 years ago
```convert example.cpp into polyapprox.cpp - made it a bit more of a generic polynomial approximator program
tweaked default range in DE::Engine
```
```3 files changed, 82 insertions(+), 45 deletions(-)

M de.inl
D example.cpp
A polyapprox.cpp
```
`M de.inl => de.inl +1 -1`
```@@ 17,7 17,7 @@ template <unsigned int DIM, unsigned int POP>
const double DE::Engine<DIM,POP>::DEFAULTCROSSOVER = 1.0;

template <unsigned int DIM, unsigned int POP>
-const double DE::Engine<DIM,POP>::DEFAULTRANGE= 1000000.0;
+const double DE::Engine<DIM,POP>::DEFAULTRANGE= 10.0;

template <unsigned int DIM, unsigned int POP>
const double DE::Engine<DIM,POP>::BIGDOUBLE = 1.79e308; // close to max double

```
`D example.cpp => example.cpp +0 -44`
```@@ 1,44 0,0 @@
-#include <cstdio>
-
-#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;
-}

```
`A polyapprox.cpp => polyapprox.cpp +81 -0`
```@@ 0,0 1,81 @@
+#include <cstdio>
+#include <cmath>
+
+#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<NUM_COEFFICIENTS>
+{
+	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;
+}

```