⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hjmin.cc

📁 basic linear algebra classes and applications (SVD,interpolation, multivariate optimization)
💻 CC
字号:
// This may look like C code, but it is really -*- C++ -*-/* ************************************************************************ * *			  Numerical Math Package *		Hooke-Jeeves multidimensional minimization * * Synopsis *	double hjmin(b,h,funct) *	Vector& b 			An initial guess as to the *					location of the minimum. *					On return, it contains the location *					of the minimum the function has found *	Vector& h			Initial values for steps along *					each direction *					On exit contains the actual steps *					right before the termination *	MultivariateFunctor& f		A function being optimized * * The hjmin function returns the value of the minimized function f() at the * point of the found minimum. * * An alternative "double hjmin(b,h0,funct)" where h0 is a "double const" * uses the same initial steps along each direction. No final steps are * reported, though. * * Algorithm *	Hooke-Jeeves method of direct search for a function minimum *	The method is of the 0. order (i.e. requiring no gradient computation) *	See *	B.Bondi. Methods of optimization. An Introduction - M., *	"Radio i sviaz", 1988 - 127 p. (in Russian) * * $Id: hjmin.cc,v 4.2 1998/12/01 17:27:15 oleg Exp oleg $ * ************************************************************************ */#include "LAStreams.h"#include "math_num.h"#include "std.h"/* *------------------------------------------------------------------------ *		Class to operate on points in a space (x,f(x)) */class FPoint{  Vector& x;				// A point in the function's domain  double fval;				// Function value at the point  MultivariateFunctor& fproc;		// Procedure to compute that value  const bool free_x_on_destructing;	// The flag telling if this FPoint 					// "owns" x, and has to dispose of					// its dynamic memory on destructionpublic:  FPoint(Vector& b, MultivariateFunctor& f);  FPoint(const FPoint& fp);  ~FPoint(void);  FPoint& operator = (const FPoint& fp);  double f(void) const			{ return fval; }  double fiddle_around(LAStreamIn h);// Examine the function in the					// neighborhood of the current point.					// h defines the radius of the region					// Proceed in the direction the function					// seems to decline  friend void update_in_direction(FPoint& from, FPoint& to);					// Decide whether the region embracing					// the local min is small enough  bool is_step_relatively_small(LAStreamIn hs, const double tau);};				// Construct FPoint from array binline FPoint::FPoint(Vector& b, MultivariateFunctor& f)	: x(b), fval(f(b)), fproc(f), free_x_on_destructing(false){}				// Constructor by exampleFPoint::FPoint(const FPoint& fp)	: x(*(new Vector(fp.x))), 	  fval(fp.fval), fproc(fp.fproc),	  free_x_on_destructing(true){}				// DestructorFPoint::~FPoint(void){  if( free_x_on_destructing )    delete &x;}				// Assignment; fproc is assumed the same and				// is not copiedinline FPoint& FPoint::operator = (const FPoint& fp){  x = fp.x;  fval = fp.fval;  return *this;}/* * Examine the function f in the vicinity of the current point x * by making tentative steps fro/back along each coordinate. * Should the function decrease, x is updated to pinpoint thus * found new local min. * The procedure returns the minimal function value found in * the region. * */double FPoint::fiddle_around(LAStreamIn hs){			// Perform a step along each coordinate  for(LAStreamOut xs(x); !xs.eof(); xs.get() )  {    const double hi = hs.get();    register const double xi_old = xs.peek();  	// Old value of x[i]    register double fnew;    if( xs.peek() = xi_old + hi, (fnew = fproc(x)) < fval )      fval = fnew;			// Step caused f to decrease, OK    else if( xs.peek() = xi_old - hi, (fnew = fproc(x)) < fval )      fval = fnew;    else					// No function decline has been      xs.peek() = xi_old;	// found along this coord, back up  }  return fval;}                                                				// Proceed in the direction the function				// seems to decline				// to_new = (to - from) + to				// from = to (before modification)void update_in_direction(FPoint& from, FPoint& to){  for(LAStreamOut tos(to.x), froms(from.x); !tos.eof(); )  {    register const double t = tos.peek();    tos.get()  += (t - froms.peek());    froms.get() = t;  }  from.fval = to.fval;  to.fval = (to.fproc)(to.x);}				// Check to see if the point of minimum has				// been located accurately enoughbool FPoint::is_step_relatively_small(LAStreamIn hs, const double tau){  for(LAStreamIn xs(x); !hs.eof(); )    if( !(hs.get() /(1 + abs(xs.get())) < tau) )     return false;  return true;}/* *------------------------------------------------------------------------ *			    Root module */double hjmin(Vector& b, Vector& h, MultivariateFunctor& ff){				// Function Parameters  const double tau = 10*DBL_EPSILON;    // Termination criterion  const double threshold = 1e-8;        // Threshold for the function                                        // decay to be treated as                                        // significant  const double step_reduce_factor = 10;     are_compatible(b,h);  FPoint pmin(b,ff);			// Point of min  FPoint pbase(pmin);			// Base point  for(;;)			// Main iteration loop  {                     	// pmin is the approximation to min so far    if( pbase.fiddle_around(h) < pmin.f() - threshold )    {   			      	// Function value dropped significantly      do                              	// from pmin to the point pbase	    update_in_direction(pmin,pbase);// Keep going in the same direction      while( pbase.fiddle_around(h) < pmin.f() - threshold ); // while it works      pbase = pmin;			// Save the best approx found    }    else                               	// Function didn't fall significantly      if(                               // upon wandering around pbas	      h *= 1/step_reduce_factor,	// Try to reduce the step then	      pbase.is_step_relatively_small(h,tau) )	return pmin.f();  }}	    		// The same as above with the only difference	    		// initial steps are given to be the same	    		// along every direction. The final steps	    		// aren't reported back thoughdouble hjmin(Vector& b,	const double h0, MultivariateFunctor& f){  Vector h(b.q_lwb(),b.q_upb()); h = h0;  return hjmin(b,h,f);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -