/// OPTIMİZASYON
//  Newton 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 r)
   {   double q=50;
   double a=5e-3;
   double k=0.2;
   double h=30;
   double Ts=300;
   
	   return q/(2*Math.PI)*(Math.log(r/a)/k+(1/(h*r)))+Ts;}
}

class fb extends f_x
{
   public double func(double r)
   { double k=0.2;
      double h=30;
     return r-(k/h);}
}

public class FOPO3CEM2
{

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 newton(f_x df,double x)
{
// df ile verilen türev fonksiyonunun köklerini bulur

int nmax=500;
double tolerance=1.0e-15;
double fx,dfx;
for(int i=0;i<nmax;i++)
{
fx=df.func(x);
dfx=derivative(df,x);
x-=fx/dfx;
if(Math.abs(fx)<tolerance)
{
return x;
}
}
return x;
}


public static double newton_2nd_derivative(f_x df,double x)
{
// df ile verilen türev fonksiyonunun köklerini bulur
int nmax=500;
double dx=1e-3;
double x1m;
double tolerance=1.0e-15;
double fx,fxm,dfx,dfxm,d2fx;
for(int i=0;i<nmax;i++)
{
fx=df.func(x);
fxm=df.func(x-dx);
dfx=derivative(df,x);
dfxm=derivative(df,(x-dx));
d2fx=-6.0/dx/dx*(fx-fxm)+2.0/dx*(2.0*dfx+dfxm);
x-=(fx/dfx+.5*fx*fx/(dfx*dfx*dfx)*d2fx);
if(Math.abs(fx)<tolerance)
{ return x; }
}
return x;
}	

     public static void main (String args[])  
     { 
	 fc  f=new fc();
	 fb df=new fb();  
     double x0;
     x0=Double.parseDouble(JOptionPane.showInputDialog(" optimum nokta tahmini giriniz  x0 : "));
     double r;
     r= newton(df,x0);
     JOptionPane.showMessageDialog(null," optimizasyon değeri  : "+r+"\nFonksiyon değeri : "+f.func(r),
     "Newton optimizasyon : ",JOptionPane.PLAIN_MESSAGE);
     System.exit(0);
     } 
}