// 
//   
// root findings in a given region
// Dr. M. Turhan Çoban

import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;

class fx extends f_x
{
public double func(double x)
{return x*x*x-6.0*x*x+11.0*x-6.0;}

}

public class NA13B
{

public static double[] enlarge(f_x f,double x1)
{return enlarge(f,x1,(x1+0.1));}


public static double[] enlarge(f_x f,double x1,double x2)
{
	//kök olan bir bölge bulana kadar verilen sınırı genişletir
	int NTRY=50;
	double a[]=new double[2];
	double FACTOR=1.6;
	int j;
	double f1,f2;
	if (x1 == x2) System.out.println("Bad initial range in ZBRAC");
	f1=f.func(x1);
	f2=f.func(x2);
	for (j=1;j<=NTRY;j++) {
		if (f1*f2 < 0.0) {a[0]=x1;a[1]=x2;return a;}
		if (Math.abs(f1) < Math.abs(f2))
			f1=f.func(x1 += FACTOR*(x1-x2));
		else
			f2=f.func(x2 += FACTOR*(x2-x1));
	}
	{a[0]=x1;a[1]=x2;return a;}
}

public static double[][] rootlimits(f_x f,double x1,double x2,int n,int nbb)
{
	// find root limits 
	// n : number of subdivisions
	// x1,x2 : limit values of the root
	// nbb = number of roots in the serched region
	//  
	int nb;
	int i;
	double x,fp,fc,dx;
	double xb[][]=new double[2][nbb];
	nb=0;
	dx=(x2-x1)/n;
	x=x1;
	fp=f.func(x1);
	for (i=1;i<=n;i++) 
	{
		x+=dx;
		fc=f.func(x);
		// eğer kök olan bölge bulunduysa.....
		if (fc*fp < 0.0 || fp==0) {
			xb[0][nb]=x-dx;
			xb[1][nb]=x;
			nb++;
		}
		fp=fc;
		if (nbb == nb) return xb;
	}	
if( nb == 0)
	JOptionPane.showMessageDialog(null,"search is completed no root is found"
    ,"SEARCH RESULT WARNING",JOptionPane.WARNING_MESSAGE);	
else if(nb<nbb)
  {	JOptionPane.showMessageDialog(null,"search is completed "+nb+" root is found \n"+
    "You searched for  "+nbb+" root","SEARCH RESULT WARNING",JOptionPane.WARNING_MESSAGE);	
   double xc[][]=new double[2][nb];
   for (i=0;i<nb;i++) {xc[0][i]=xb[0][i];xc[1][i]=xb[1][i];}
   return xc;
  }
return xb;
}
     public static void main (String args[])  
     { 
     double a[],x0,r;
     double dx=0.1;
     fx f=new fx();
     a=enlarge(f,Double.parseDouble(JOptionPane.showInputDialog(" first guess x0 : ")));
     System.out.println(a[0]+" "+a[1]);
     r= NA13.brent(f,a[0],a[1]);
     JOptionPane.showMessageDialog(null," root value x  : "+r+"\nfunction value f(x) : "+f.func(r)+"\nroot limits: a="+a[0]+" b="+a[1],
     "root finding with brent method : ",JOptionPane.PLAIN_MESSAGE);
     double b[][]=rootlimits(f,0.0,10.0,10,4);
     System.out.println(Matrix.toString(b));
     b=rootlimits(f,b[0][0],b[1][0],10,4);
     System.out.println(Matrix.toString(b));
     System.exit(0);
     } 
}
