How to Adapt the Nelder Mead Algorithm for a Custom Function in Java?

  • Context: Java 
  • Thread starter Thread starter a.mlw.walker
  • Start date Start date
  • Tags Tags
    Algorithm Java
Click For Summary
SUMMARY

The discussion focuses on adapting the Nelder-Mead algorithm for a custom function in Java, specifically for minimizing a sum derived from a user-defined function. The user implements the algorithm based on a Java version found at Berkeley and encounters issues with the simplex array structure and convergence to incorrect values. Key insights include the necessity of adjusting the simplex dimensions and starting points to avoid local minima, as well as the recommendation to use a larger initial interval for better convergence results.

PREREQUISITES
  • Understanding of the Nelder-Mead optimization algorithm
  • Familiarity with Java programming and array manipulation
  • Knowledge of numerical methods for function minimization
  • Basic concepts of function evaluation and local minima
NEXT STEPS
  • Research "Nelder-Mead algorithm implementation in Java"
  • Explore "function evaluation techniques in numerical optimization"
  • Learn about "local minima and strategies to avoid them"
  • Investigate "alternative optimization algorithms for 2D functions"
USEFUL FOR

Java developers, data scientists, and mathematicians interested in numerical optimization techniques and those looking to implement or troubleshoot the Nelder-Mead algorithm for custom functions.

a.mlw.walker
Messages
144
Reaction score
0
Hi This is a question somewhere between maths and numerical methods...

I am using the algorithm for Nelder Mead found here:
http://www.ssl.berkeley.edu/~mlampton/neldermead.java

in java. It works nicely with the two example functions - rosen and parab.
I am trying to adjust it to my function:

Code:
	static double myFunction(double p[]) {
		double v0;
		double sum = 0;
		double curve;
		double errorVector;
		int index = 0;
		v0 = (1 + (p[0] / 2) * timings.get(0) * timings.get(0))
				/ timings.get(0);

		for (Double f : timings) {
			index++;
			curve = (v0 * f - (p[0] / 2)) * f * f;
			errorVector = index - rotorCurve;
			sum += errorVector * errorVector;
		}
		System.out.println("p:" + p[0]);
		return sum;
	}
so that I can minimize for the sum and find p[0].
My test data is

timings.add(2.503);
timings.add(5.159);
timings.add(7.899);
timings.add(10.883);
timings.add(17.081);

The problem I think is occurring with my understanding of the 2D array simplex[]. As far as I understand the first two columns are the paramter initial values and the third is storing the value of the function, but I am not sure why there are three rows. I assume its three different values for the paramters or something, but it doesn't seem to make sense to me.

I have attached my version of the algorithm for my function, in the hope that someone can help me get it to solve the problem.
Thanks

EDIT:!
Sorry I made a mistake in my attachment. I had done a couple of undo's that need to be put back.

The array simplex should be:
Code:
        double simplex[][] = // [row][col] = [whichvx][coord,FUNC]
        {{ 0.004, 0.0}};
 

Attachments

Technology news on Phys.org
Is this in the wrong place? Could an admin move it please? Perhaps general engineering would be better?
 
The first two columns of simplex are storing initial points to evaluate your function if your function is over R2, and the third column is storing function values. If it's over R then it looks like the first column is initial points to evaluate at, the second column is storing the value of the function, and the third column is totally superfluous. The point is that you are supposed to evaluate the function on a simplex - in two dimensions that is a triangle with three vertices to keep track of, in 2 dimensions it's a line segment with two vertices to keep track of. So it seems like NPoints should be changed to 2 along with NDims to 1, and you should resize your simplex matrix to be 2x2 (this last part I suppose is not strictly necessary, but there are elements in that matrix that will never be referenced/changed).
 
Thanks Office_Shredder, so now it compiles and converges, however it converges to the wrong value. I have a paper that gets the result as 0.0068 and My MATLAB program also gets that value, however this seems to converge to -0.32
I now have simplex setup as:

{{ 0.006, 0.0}, {0.0, 0.0}};

i.e 2x2. Should the other values all start at 0? Or should they be something else?
Thanks
A
 
It doesn't matter what they start at, the first thing the program does is evaluate your function and fill in (in your case) f(.006) and f(0) into the second column.
That's what
for (int i=0; i<NPTS; i++)
simplex[FUNC] = func(simplex);

is doing.

As to why it's converging to the wrong value, my understanding is that if your starting simplex is too small that you can get stuck in a local search. If the concavity around .0068 is very large, it might be that on the interval [0, .006] the function is sloped so that following the gradient means moving towards negative numbers, in which case the search would do that. You should try starting with a larger interval, like have your first column have a 0 and a 1 in it.
 
The Nelder-Mead simplex method is designed for 3d surfaces. I bet there are better ways to minimize a 2d function. In 3d N-M starts with a simplex of 3pts all on the surface. For minimization it will find a new simplex by reflecting the max valued vertex across the center pt of the line connecting the other 2 vertices. It then repeats this process until your stopping conditions are met.

It seems to me that it really depends upon a 3d surface to work best, not sure how well it will work in 2d. Good luck.
 
which function you used ?
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
Replies
3
Views
4K
  • · Replies 1 ·
Replies
1
Views
3K
Replies
9
Views
2K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 6 ·
Replies
6
Views
10K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 3 ·
Replies
3
Views
9K