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