/// OPTIMİZASYON
//  Newton-ikiyebölme kök bulma yöntemi (ve türev ) kullanarak optimizasyon 
import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;

class fc extends f_x
{
   public double func(double x)
   {   double x6=x*x*x*x*x*x;
	   return 4.0*(x6*x6-x6);}
}

class fb extends f_x
{
   public double func(double x)
   { 
     double x5=x*x*x*x*x*x;
     double x6=x5*x;
     return 4.0*(12.0*x6*x5-6*x5);}
}

public class OH2O1
{

public static double derivative(f_x df,double x)
{
// türev alt programı	
// df fonksiyonunun türevini hesaplar
double h0=0.256;
int i,m;
int n=7;
//derivative of a simple function
double T[][];
T=new double[n][n];
double h[];
h=new double[n];
//vector<double> h(n,0);
for(i=0;i<n;i++)
{
  h[i]=0;
  for(int j=0;j<n;j++)
    T[i][j]=0;
}
h[0]=h0;
double r=0.5;
for( i=1;i<n;i++)
{
h[i]=h0*Math.pow(r,i);
}

for(i=0;i<n;i++)
{
T[i][0]=( df.func(x + h[i]) - df.func( x - h[i]))/(2.0*h[i]);
}
for(m=1;m<n;m++)
{
  for(i=0;i<n-m;i++)
  {
  T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/
          (h[i]*h[i]- h[i+m]*h[i+m]);
  }
}
double xx=T[0][n-1];
return xx;
}

public static double dfx(f_x f,double x,double h)
{ //Türev hesabı
  double hh=1.0/h; 
  return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh;
}

	
public static double tersinter2Dkok(f_x f,double x1,double x3)
{double x2=(x1+x3)/2.0;
return tersinter2Dkok(f,x1,x2,x3);
}
	
public static double tersinter2Dkok(f_x f,double x1,double x2,double x3)
{
// brent metodu ile kök değerini bulur
double test;
double p=0;
double es,ea;
double f1,f2,f3,fp;
int maxit=500,iter=0;
double tol=1.0e-15;
es=0.0000001;
ea=1.1*es;
f1=f.func(x1);
f2=f.func(x2);
f3=f.func(x3);
if(f1==0) return x1;
else if(f2==0) return x2;
else if(f3==0) return x3; 
if(f1*f3>0) System.out.println("verilen bölgede kök yok");
while((ea>es)&&(iter<maxit))
{	p=-(f2*f3*x1*(f2-f3)+f3*f1*x2*(f3-f1)+f1*f2*x3*(f1-f2))/((f1-f2)*(f2-f3)*(f3-f1));
    fp=f.func(p);
    ea=Math.abs(x3-p);
	if(Math.abs(f3)<tol) return x3;        
    if(p>x3) {x1=x3;f1=f3;x3=p;f3=fp;}
    else if(p<x3) {x2=x3;f2=f3;x3=p;f3=fp;}
    iter++;
} 
if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+
   " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); 
return p;
}

     public static void main (String args[])  
     { 
	 fc  f=new fc();
	 fb df=new fb();  
     double x0,x1;
     x0=Double.parseDouble(JOptionPane.showInputDialog(" alt sınırı giriniz  x0 : "));
     x1=Double.parseDouble(JOptionPane.showInputDialog(" üst sınırı giriniz  x1 : "));
     double r;
     r= tersinter2Dkok(df,x0,x1);
     JOptionPane.showMessageDialog(null," optimizasyon değeri  : "+r+"\nFonksiyon değeri : "+f.func(r),
     "brent kök bulma yöntemiyle optimizasyon : ",JOptionPane.PLAIN_MESSAGE);
     System.exit(0);
     } 
}