// 
//  
// kompleks Lequerre yöntemi ile polinomun kökünü bulmak 
//  
//  

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

public class SCO4H
{	
  static complex func(double a[],complex x)
  {  //complex polynomial
  int n=a.length;	  
  complex y=new complex(a[n-1]);
  for(int i=n-2;i>=0;i--)
  {y=complex.add(complex.multiply(y,x),a[i]);}
  return y;
  }
  
  static complex dfunc(double a[],complex x)
  {//complex numeric derivative of a polynomial
   double hh=0.001;
   complex h=new complex(hh,0.0);
   complex he=new complex(-hh,0.0);
   complex h2=new complex(2.0*hh,0.0);
   complex he2=new complex(-2.0*hh,0.0);
   complex xah=complex.add(x,h);
   complex xa2h=complex.add(x,h2);
   complex xeh=complex.add(x,he);
   complex xe2h=complex.add(x,he2);
   complex fe2h=complex.multiply(func(a,xe2h),(1.0/12.0));
   complex feh=complex.multiply(func(a,xeh),(-8.0/12.0));
   complex fah=complex.multiply(func(a,xah),(8.0/12.0));
   complex fa2h=complex.multiply(func(a,xa2h),(-1.0/12.0));
   complex df=complex.add(fe2h,complex.add(feh,complex.add(fah,fa2h)));
   df=complex.divide(df,h);
   return df;
  }
  
  static complex d2func(double a[],complex x)
  {//complex second numeric derivative of a polynomial
   double hh=0.001;
   complex h=new complex(hh,hh);
   complex hkare=complex.pow(h,2);
   complex he=new complex(-hh,-hh);
   complex h2=new complex(2.0*hh,2.0*hh);
   complex he2=new complex(-2.0*hh,-2.0*hh);
   complex xah=complex.add(x,h);
   complex xa2h=complex.add(x,h2);
   complex xeh=complex.add(x,he);
   complex xe2h=complex.add(x,he2);
   complex fe2h=complex.multiply(func(a,xe2h),(-1.0/12.0));
   complex feh=complex.multiply(func(a,xeh),(4.0/3.0));
   complex ff=complex.multiply(func(a,x),(-5.0/2.0));
   complex fah=complex.multiply(func(a,xah),(4.0/3.0));
   complex fa2h=complex.multiply(func(a,xa2h),(-1.0/12.0));
   complex d2f=complex.add(fe2h,complex.add(feh,complex.add(ff,complex.add(fah,fa2h))));
   d2f=complex.divide(d2f,hkare);
   return d2f;
  }


public static complex Leguerre(double a[],complex x)
{
int n=a.length-1;
double eps=1.0e-8;
int m=50;
int k=0;
complex f0=func(a,x);
complex f1=new complex();
complex f2=new complex();
complex g=new complex();
complex d1=new complex();
complex d2=new complex();
complex x0=x;
complex x1=new complex((-a[0]/a[1]),0.0);
do{
  f1=dfunc(a,x0);
  f2=d2func(a,x0);
  g=complex.add(complex.multiply(f1,f1),complex.multiply(complex.multiply(f0,f2),(-(double)n/(double)(n-1))));
  d1=complex.add(f1,complex.multiply(complex.pow(g,0.5),(double)(n-1)));
  d2=complex.add(f1,complex.multiply(complex.pow(g,0.5),(double)(1-n)));
if(complex.abs(d1)>=complex.abs(d2)) x1=complex.add(x0,complex.multiply(complex.divide(f0,d1),(double)(-n)));
else                                 x1=complex.add(x0,complex.multiply(complex.divide(f0,d2),(double)(-n)));
  x0=complex.add(x1,0.0);
  f0=func(a,x0);
  k++;
}while(complex.abs(f0)>eps && k<m);	

if(complex.abs(f0)<eps) { return x1;}
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 x1;
}


     public static double[] verigir(String s)
     {
     String s1=JOptionPane.showInputDialog(s);        
     StringTokenizer token=new StringTokenizer(s1);
     int n=token.countTokens()-1;
     int m=n+1;
     double a[]=new double[m];
     int j=0;           
     while(token.hasMoreTokens())
     {
     Double ax=new Double(token.nextToken());
     a[j++]=ax.doubleValue();
     }
     return a; 
     }

     public static void main (String args[])  
     {
	 double a[]={-75,-5,4,-4,-1,1};  
	 int n=a.length-1;
     double x0[]=verigir(" Fonksiyon değeri için ilk tahmin : ");
     complex x=new complex(x0[0],x0[1]);
     complex r=Leguerre(a,x);
     complex ff=func(a,r);
     String s="kök = "+r.toString()+"\n"+"Fonksiyon = "+ff.toString();
     JOptionPane.showMessageDialog(null,s,
     "Leguerre yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE);
     System.exit(0);
     } 
}