🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: sci.math.num-analysis
3 messages
3 total messages Started by Matt Austern Sun, 10 Jan 1993 15:25
Wanted: minimization routine
#1112
Author: Matt Austern
Date: Sun, 10 Jan 1993 15:25
15 lines
1133 bytes
Does anybody out there have a recommendation for a minimization
routine?  I'll be using it to minimize a function of two or three
variables; the function is reasonably well behaved, but I am not able
to calculate the derivatives very easily.

Code in C or C++ would be preferable.  

Thanks!


--
Matthew Austern                   Just keep yelling until you attract a
(510) 644-2618                    crowd, then a constituency, a movement, a
austern@lbl.bitnet                faction, an army!  If you don't have any
matt@physics.berkeley.edu         solutions, become a part of the problem!
Re: Wanted: minimization routine
#1116
Author: Eduardo Lucero
Date: Mon, 11 Jan 1993 04:59
11 lines
1026 bytes
In article <MATT.93Jan10152553@physics2.berkeley.edu> matt@physics2.berkeley.edu (Matt Austern) writes:
>From: matt@physics2.berkeley.edu (Matt Austern)
>Subject: Wanted: minimization routine
>Date: 10 Jan 93 15:25:53
>Does anybody out there have a recommendation for a minimization
>routine?  I'll be using it to minimize a function of two or three
>variables; the function is reasonably well behaved, but I am not able
>to calculate the derivatives very easily.
Try the Nelder's simplex method.
(Computer Journal, vol. 7, pp 308-313, 1964)
Eduardo Lucero
(Contains) source code for minimization
#1135
Author: Mark Johnson
Date: Mon, 11 Jan 1993 15:16
342 lines
7847 bytes
In article <MATT.93Jan10152553@physics2.berkeley.edu> matt@physics2.berkeley.edu (Matt Austern) writes:
   > Does anybody out there have a recommendation for a minimization
   > routine?  I'll be using it to minimize a function of two or three
   > variables; the function is reasonably well behaved, but I am not able
   > to calculate the derivatives very easily.
   > Code in C or C++ would be preferable.  


For a few variables (N<12), I have had good luck with
Hooke and Jeeves.  It will minimize discontinuous functions,
and/or functions whose derivatives are discontinuous.

Hooke and Jeeves does not use derivatives.

It is a heuristic method, from 1963, and has fallen VERY MUCH
into disfavour among academics because no proof exists of
its convergence properties.  (Whereas other methods, notably
those of quasi-Newton parentage like Huangs class of Variable
Metric algos, have provably quadratic convergence given
certain assumptions -- assumptions that include a damn good
starting point for the optimization search).

Pragmatically speaking, to quote Fred Dryer, "It works for me."
And because it doesn't need or use derivatives, it is usually
(again, pragmatically speaking) quicker to get a problem up and
running on H&J.

If it works for you too, great.  If not, you are entitled to
a full refund of your purchase price.


#include <stdio.h>
#include <math.h>

#define		VARS		(100)    /* max # of variables */
#define		RBEGIN		(0.6)    /* stepsize geometric shrink   */
#define		DBEGIN		(0.6)    /* delta is a fraction of coord */
#define		EPSMIN		(1E-7)   /* ending value of stepsize */
#define		IMAX		(5000)   /* max # of iterations */


#define		ONETHIRD	(1.0/3.0)    /* used in one of the f() */


/* global variables */
/* global variables */

int	funevals = 0;





/* a few test functions -- to use one, change its name to f() */
/* a few test functions -- to use one, change its name to f() */
/* a few test functions -- to use one, change its name to f() */






/* Powells quartic function */
double	f(x, n)
	double	x[VARS] ;
	int	n ;
{
	double	a, b, c, d, t1, t2 ;

	funevals++;
	a = x[0] ;  b = x[1] ;  c = x[2] ;  d = x[3] ;

	t1  = (a + (10.0*b)) * (a + (10.0*b)) ;
	t1 += 5.0 * (c - d) * (c - d) ;
	t1 += (b - (2.0*c)) * (b - (2.0*c)) * (b - (2.0*c)) * (b - (2.0*c)) ;
	t1 += 10.0 * (a-d) * (a-d) * (a-d) * (a-d) ;

	return( t1 );
}






/* Rosenbrocks parabolic (banana) function */
double	rosen(x, n)
	double	x[VARS] ;
	int	n ;
{
	double	a, b, c ;

	funevals++;
	a = x[0] ;  b = x[1] ;
	c = 100.0 * (b - (a*a)) * (b - (a*a)) ;
	return(c + ( (1.0-a) * (1.0-a) ) ) ;
}







/* Schittowski problem 210: very difficult banana function */
double	prob210(x, n)
	double	x[VARS] ;
	int	n ;
{
	double	a, b, c ;

	funevals++;
	a = x[0] ;  b = x[1] ;
	c = 1.0e6 * (b - (a*a)) * (b - (a*a)) ;
	return(c + ( (1.0-a) * (1.0-a) ) ) ;
}







/* Schittowski problem 281: summation of ten cubics */
double	prob281(x, n)
	double	x[VARS] ;
	int	n ;
{
	double	summ, index ;
	int	i ;

	funevals++;

	summ = 0.0 ;
	for(i=0; i<n; i++)
	{
		index = (double) (1 + i) ;
		summ += (index * index * index) * (x[i] - 1.0) * (x[i] - 1.0) ;
	}

	summ = pow( summ, ONETHIRD ) ;
	return( summ );
}






/* given a point, look for a better one nearby, one coord at a time */

double	best_nearby(delta, point, prevbest, nvars)

	double	delta[VARS], point[VARS] ;
	double	prevbest ;
	int	nvars ;
{
	double	z[VARS] ;
	double	minf, ftmp ;
	int	i ;

	minf = prevbest ;
	for(i=0; i<nvars; i++) z[i] = point[i] ;

	for(i=0; i<nvars; i++)
	{
		z[i] = point[i] + delta[i] ;
		ftmp = f(z, nvars);
		if(ftmp < minf) minf = ftmp ;
		else
		{
			delta[i] = 0.0 - delta[i] ;
			z[i] = point[i] + delta[i] ;
			ftmp = f(z, nvars);
			if(ftmp < minf) minf = ftmp ;
			else z[i] = point[i] ;
		}
	}
	for(i=0; i<nvars; i++) point[i] = z[i] ;
	return(minf);
}







int	hooke(nvars, startpt, endpt, rho, epsilon, itermax)

	double	startpt[VARS], endpt[VARS] ;
	int	nvars, itermax ;
	double	rho, epsilon ;
{

	double	delta[VARS] ;
	double	newf, fbefore, steplength, tmp ;
	double	xbefore[VARS], newx[VARS] ;

	int	i, j, keep ;
	int	iters, iadj ;

	for(i=0; i<nvars; i++)
	{
		newx[i] = xbefore[i] = startpt[i] ;
		delta[i] = fabs(startpt[i] * DBEGIN) ;
		if(delta[i] == 0.0) delta[i] = DBEGIN ;
	}

	iadj = 0 ;
	steplength = rho ;
	iters = 0;
	fbefore = f(newx, nvars);
	newf = fbefore ;

	while( (iters < itermax) && (steplength > epsilon))
	{
		iters++;
		iadj++;


printf("\nAfter %5d funevals, f(x) =  %.4le at\n", funevals, fbefore);
for(j=0; j<nvars; j++) printf("   x[%2d] = %.4le\n", j, xbefore[j]) ;

		/* find best new point, one coord at a time */
		for(i=0; i<nvars; i++) { newx[i] = xbefore[i]; }
		newf = best_nearby(delta, newx, fbefore, nvars);


		/* if we made some improvements, pursue that direction */
		keep = 1 ;
		while( (newf < fbefore)  && (keep == 1) )
		{
			iadj = 0;

			for(i=0; i<nvars; i++)
			{
				/* firstly, arrange the sign of delta[] */
				if(newx[i] <= xbefore[i])
					delta[i] = 0.0 - fabs(delta[i]) ;
				else	delta[i] = fabs(delta[i]);

				/* now, move further in this direction */
				tmp = xbefore[i] ;
				xbefore[i] = newx[i] ;
				newx[i] = newx[i] + newx[i] - tmp ;
			}
			fbefore = newf ;
			newf = best_nearby(delta, newx, fbefore, nvars);


			/* if the further (optimistic) move was bad.... */
			if(newf >= fbefore) break ;


			/* make sure that the differences between the new */
			/* and the old points are due to actual */
			/* displacements; beware of roundoff errors that */
			/* might cause newf < fbefore */
			keep = 0;
			for(i=0; i<nvars; i++)
			{
				keep = 1 ;
				if(fabs(newx[i] - xbefore[i]) >
					(0.5 * fabs(delta[i])) ) break ;
				else keep = 0;
			}
		}

		if((steplength >= epsilon) && (newf >= fbefore) )
		{
			steplength = steplength * rho ;
			for(i=0; i<nvars; i++) { delta[i] *= rho ; }
		}

	}


	for(i=0; i<nvars; i++) endpt[i] = xbefore[i] ;
	return(iters);

}






main()
{

	double	startpt[VARS], endpt[VARS] ;
	int	nvars, itermax ;

	double	rho, epsilon ;
	int	i, jj ;



	/* test function problem 281 */
	/* starting guess */
	nvars = 10;

	startpt[0] =    1.7528323e-02 ;
	startpt[1] =   -2.2503207e+00 ;
	startpt[2] =   -1.0325044e+00 ;
	startpt[3] =    1.1047138e+00 ;
	startpt[4] =    6.7813668e-01 ;
	startpt[5] =    8.6220218e-01 ;
	startpt[6] =    9.6336051e-01 ;
	startpt[7] =    9.3734542e-01 ;
	startpt[8] =    9.9586705e-01 ;
	startpt[9] =    9.5568268e-01 ;


	/* rosenbrock test function   also prob 210 */
	/* starting guess */
	nvars = 2;
	startpt[0] = -1.2 ;
	startpt[1] =  1.0 ;



	/* powell test function */
	/* starting guess */
	nvars = 4;
	startpt[0] =  3.0 ;
	startpt[1] = -1.0 ;
	startpt[2] =  0.0 ;
	startpt[3] =  1.0 ;


	itermax = IMAX ;
	rho = RBEGIN;
	epsilon = EPSMIN ;

	jj = hooke(nvars, startpt, endpt, rho, epsilon, itermax) ;

	printf("\n\n\nHOOKE RETURNED\n");
	for(i=0; i<nvars; i++) printf("x[%3d] = %15.7le \n", i, endpt[i]);

}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads