/// OPTIMİZASYON
//  2 derece polinom interpolasyon kullanarak optimizasyon 
import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.io.*;

class f_B_Spline extends f_x
{
  double a[];
  double ti[];
  
  public f_B_Spline(String s1)
  {	  
  double yi[];
  double ai[][]=Text.readDoubleT(s1);
  ti=ai[0];
  yi=ai[1];
  a=B_Spline(ti,yi);
  }
  
  public double func(double x)
  {
  double h[]=hi(ti);
  int i;
  int n=ti.length-1;
  double nn=n+2;
  double d,e;
  for(i=(n-1);i>=1;i--)
    {if((x-ti[i])>=0) break;}
  i++;
  d=(a[i+1]*(x-ti[i-1])+a[i]*(ti[i]-x+h[i+1]))/(h[i]+h[i+1]);
  e=(a[i]*(x-ti[i-1]+h[i-1])+a[i-1]*(ti[i-1]-x+h[i]))/(h[i-1]+h[i]);
  double bs=(d*(x-ti[i-1])+e*(ti[i]-x))/h[i];
  return bs;
  }
   
  public static double[] hi(double ti[])
  {int n=ti.length-1;//ti 0..n
  int nn=n+2;
  double h[]=new double[nn];
  for(int i=1;i<=n;i++)
     {h[i]=ti[i]-ti[i-1];
     }
  h[0]=h[1];
  h[n+1]=h[n];
  return h;
  }
  
  public static double [] B_Spline(double ti[],double yi[])
  {
  int n=ti.length-1;
  int nn=n+2;
  int i;
  double delta,gamma,p,q,r;
  double a[]=new double[nn];
  double h[]=new double[nn];
  h=hi(ti);
  delta=-1;
  gamma=2.0*yi[0];
  p=delta*gamma;
  q=2.0;
  for(i=1;i<=n;i++)
  {r=h[i+1]/h[i];
  delta=-r*delta;
  gamma=-r*gamma+(r+1)*yi[i];
  p=p+gamma*delta;
  q=q+delta*delta;
  }
  a[0]=-p/q;
  for(i=1;i<=(n+1);i++)
  {a[i]=((h[i-1]+h[i])*yi[i-1]-h[i]*a[i-1])/h[i-1];}
  return a;
 }
      
}

public class FOPO1BSpline
{
public static double golden(f_x f,double a,double b,double epsilon)
{return golden(f,a,b,epsilon,1.0e-10,0);}
public static double golden(f_x f,double a,double b)
{return golden(f,a,b,1.0e-10,1.0e-10,0);}
public static double golden(f_x f,double a,double b,double epsilon,double delta,int print)
{
//  f fonksiyonunun minimumunu bulur
// not  maximum f(x) = minimum (-f(x))
    double r1 = (Math.sqrt(5.0)-1.0)/2.0; // golden ratio
    double r2 = r1*r1;
    double h = b - a;
    double ya = f.func(a);
    double yb = f.func(b);
    double c = a + r2*h;
    double d = a + r1*h;
    double yc = f.func(c);
    double yd = f.func(d);
    int k = 1;
    double dp,dy,p,yp;
    while ((Math.abs(yb-ya)>epsilon) || (h>delta))
    {
      k++;
      if (yc<yd)
        {
        b = d;
        yb = yd;
        d = c;
        yd = yc;
        h = b - a;
        c = a + r2 * h;
        yc = f.func(c);
        }
      else
       {
         a = c;
         ya = yc;
         c = d;
         yc = yd;
         h = b - a;
         d = a + r1 * h;
         yd = f.func(d);
       }//end of if
    }//end of while
    dp = Math.abs(b-a);
    dy = Math.abs(yb-ya);
    p = a;
    yp = ya;
    if (yb<ya)
    {
      p = b;
      yp = yb;
    }
    if(print==1)
    {System.out.println("x min = "+p+"ymin = "+yp+"error of x ="+dp+"error of y"+dy); }
    return p;
}

     public static void main (String args[]) throws java.io.IOException
     { 
	 f_B_Spline f=new f_B_Spline("in.txt");    
     
	 f_x f1=f;
	 double a,b;
     a=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz a : "));
     b=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz b : "));
     double r;
     r= golden(f,a,b,1.0e-10,1.0e-5,0);
     JOptionPane.showMessageDialog(null," optimizasyon değeri  : "+r+"\nFonksiyon değeri : "+f.func(r),
     "B-Şerit interpolasyonlu Fibonacchi optimizasyon : ",JOptionPane.PLAIN_MESSAGE);
     Plot pp=new Plot(f,-4.0,5.0,10);
     pp.addData("in.txt");
     pp.setPlotType(0,38);  //veriyi beşköşe yıldız olarak çiz
     pp.setColor(0,0,0,250); 
     pp.plot();
     } 
}
