view src/samer/maths/opt/CubicLineSearch.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
line wrap: on
line source
/*
 *	Copyright (c) 2000, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS iS and WITHOUT ANY WARRANTY; 
 *	without even the implied warranty of MERCHANTABILITY or 
 *	FITNESS FOR A PARTICULAR PURPOSE.
 */

package samer.maths.opt;
import  samer.maths.*;
import  samer.core.*;


public class CubicLineSearch
{
	double	ZETA=0.0625;	// factor for safeguarding
	State		S;
	
	public CubicLineSearch(State s) { S=s; }

	public void setSafeguardFactor( double z) { ZETA=z; }	

	protected final double extrapolate()
	{
		double beta=S.cubic()-S.alpha;

		if (Double.isInfinite(beta) || Double.isNaN(beta)) {
			return S.alpha*1.6;	
		} else if (beta>0) {
			if (beta<0.5*S.alpha) beta=S.alpha*0.5;
			else if (beta>2*S.alpha) beta=2*S.alpha;
			return beta;
		} else {
			return S.alpha*1.6;	
			// if (beta>8) beta=8;
		}
	}

	protected final double interpolate()
	{
		if (S.P2.s>0) {
			double beta=S.cubic();
			double safe=ZETA*S.alpha;
			if (Double.isNaN(beta) || Double.isInfinite(beta)) {
				beta=S.alpha/2; // bisect
			} else if (beta<=safe || beta>=(S.alpha-safe)) {
				beta=S.alpha/2; // bisect
			} 
			if (S.alpha<0.1) beta/=2; //	adust
			return beta;
		} else {
			return S.alpha/2;
		}
	}

	public void run(Condition convergence)
	{
		while (!convergence.test()) {
			if (S.P2.f<S.P1.f && S.P2.s<0) {
				double beta=extrapolate();
				S.move();
				S.step(beta);
			} else
				S.step(interpolate());
		}
	}
}