package mmc; /** * This class provides routines for calculating roots by the combination of the Newton-Raphson method and bisection. * Include the function to be integrated in a class that implements the interface FunctionOfx (defined below). * Methods contained here are based on the Numerical Recipes (W. H. Press et al.). *
 * interface DFunctionOfx extends FunctionOfx{
 *     double dFunction(double x);
 * }
 * 
* For the definition of interface FunctionOfx see the manual page for class Integral. * @author Dmitry Chirkin */ public class FindRoot extends MathModel{ private double precision; private int maxSteps; private DFunctionOfx function2use; //----------------------------------------------------------------------------------------------------// /** * initializes class - this constructor uses default settings */ public FindRoot(){ this(20, 1.e-6); } //----------------------------------------------------------------------------------------------------// /** * initializes class - this is the main constructor */ public FindRoot(int maxSteps, double precision){ if(maxSteps<=0){ Output.err.println("Warning (in Integral/Integral/1): maxSteps = "+maxSteps+" must be > 0, setting to 1"); maxSteps=1; } if(precision<=0){ Output.err.println("Warning (in Integral/Integral/2): precision = "+precision+" must be > 0, setting to 1.e-6"); precision=1.e-6; } this.maxSteps=maxSteps; this.precision=precision; } //----------------------------------------------------------------------------------------------------// /* * function */ private double function(double x){ return function2use.function(x); } //----------------------------------------------------------------------------------------------------// /* * derivative of the function */ private double dFunction(double x){ return function2use.dFunction(x); } //----------------------------------------------------------------------------------------------------// /** * returns the value of the root bracketed between min and max. Starting value of x is determined by 0<=startX<=1 */ public double findRoot(double min, double max, double startX, DFunctionOfx function2use, double rightSide){ int i; double deltaX, deltaOld, currentX, aux; double f, df, fmin, fmax, result, xdiff; this.function2use=function2use; fmin=function(min)-rightSide; fmax=function(max)-rightSide; if(fmin==0) return min; if(fmax==0) return max; if(fmin*fmax>0){ Output.err.println("Error (in FindRoot/findRoot): Root must be bracketed"); return min; } if(fmin>0){ aux=min; min=max; max=aux; aux=fmin; fmin=fmax; fmax=aux; } result=fmax-fmin; xdiff=Math.abs(max-min); deltaX=deltaOld=xdiff; if(startX>1 || startX<0) startX=0.5; currentX=min*(1-startX)+max*startX; f=function(currentX)-rightSide; df=dFunction(currentX); for(i=0;i