samer@0: /* samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London. samer@0: * All rights reserved. samer@0: * samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY; samer@0: * without even the implied warranty of MERCHANTABILITY or samer@0: * FITNESS FOR A PARTICULAR PURPOSE. samer@0: */ samer@0: samer@0: package samer.maths.opt; samer@0: import samer.maths.*; samer@0: import samer.core.*; samer@0: samer@0: samer@0: public class CubicLineSearch samer@0: { samer@0: double ZETA=0.0625; // factor for safeguarding samer@0: State S; samer@0: samer@0: public CubicLineSearch(State s) { S=s; } samer@0: samer@0: public void setSafeguardFactor( double z) { ZETA=z; } samer@0: samer@0: protected final double extrapolate() samer@0: { samer@0: double beta=S.cubic()-S.alpha; samer@0: samer@0: if (Double.isInfinite(beta) || Double.isNaN(beta)) { samer@0: return S.alpha*1.6; samer@0: } else if (beta>0) { samer@0: if (beta<0.5*S.alpha) beta=S.alpha*0.5; samer@0: else if (beta>2*S.alpha) beta=2*S.alpha; samer@0: return beta; samer@0: } else { samer@0: return S.alpha*1.6; samer@0: // if (beta>8) beta=8; samer@0: } samer@0: } samer@0: samer@0: protected final double interpolate() samer@0: { samer@0: if (S.P2.s>0) { samer@0: double beta=S.cubic(); samer@0: double safe=ZETA*S.alpha; samer@0: if (Double.isNaN(beta) || Double.isInfinite(beta)) { samer@0: beta=S.alpha/2; // bisect samer@0: } else if (beta<=safe || beta>=(S.alpha-safe)) { samer@0: beta=S.alpha/2; // bisect samer@0: } samer@0: if (S.alpha<0.1) beta/=2; // adust samer@0: return beta; samer@0: } else { samer@0: return S.alpha/2; samer@0: } samer@0: } samer@0: samer@0: public void run(Condition convergence) samer@0: { samer@0: while (!convergence.test()) { samer@0: if (S.P2.f