import visad.*;
import visad.java3d.DisplayImplJ3D;
import visad.java2d.DisplayImplJ2D;
import java.rmi.RemoteException;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class fx extends f_x
{ double beta,a;
	public fx(double ai,double betai)
  {beta=betai;
   a=ai;
  }
  
  public void setbeta(double betai)
  {beta=betai;}
  
  public double func(double x)
 {double y=Math.cos(beta*x)*20*Math.sin(Math.PI*x/a);
  return y;
 }
}

public class HT_EX2_11
{   double beta[];
    double C[];
    double a,b,H;
	public HT_EX2_11(double ai,double bi,double Hi)
	{a=ai;
	 b=bi;
	 H=Hi;
	beta=new double[10];
    C=new double[10];
    for(int n=1;n<=10;n++)
    {beta[n-1]=beta(n);
     C[n-1]=Cm(beta[n-1]);
     }	
	}
public  double fx(double beta)
{return beta*Math.tan(beta*a)-H;}

public  double dfx(double x,double dx)
{ //Türev hesabı
  return (-fx(x+2.0*dx)+8.0*fx(x+dx)-8.0*fx(x-dx)+fx(x-2.0*dx))/(12.0*dx);
}


public  double beta(int n)
{
    //lineer olmayan denklemin kökü : brent metodu
    //referans : Numerical Recipes in C, second edition, William H. Press, 
    //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery
    //cambridge university press	
	 double x1=(n-1)*Math.PI/this.a;
     double x2=	x1+Math.PI/2/this.a-0.00000001;	
    double ITMAX=100;
    double EPS=3.0e-8;
	int iter;
	double a=x1,b=x2,c,d,e,min1,min2;
	double tol=1.0e-5;
	c=0;
	d=0;
	e=0;
	double fa=fx(a),fb=fx(b),fc,p,q,r,s,tol1,xm;
	if (fb*fa > 0.0) JOptionPane.showMessageDialog(null,"Kök sınırları doğru olarak seçilmemiş \n sonuç hatalı olabilir"
	,"KÖK SINIRLARI SEÇİM UYARISI",JOptionPane.WARNING_MESSAGE);
	fc=fb;
	for (iter=1;iter<=ITMAX;iter++) {
		if (fb*fc > 0.0) {
			c=a;
			fc=fa;
			e=d=b-a;
		}
		if (Math.abs(fc) < Math.abs(fb)) {
			a=b;
			b=c;
			c=a;
			fa=fb;
			fb=fc;
			fc=fa;
		}
		tol1=2.0*EPS*Math.abs(b)+0.5*tol;
		xm=0.5*(c-b);
		if (Math.abs(xm) <= tol1 || fb == 0.0) return b;
		if (Math.abs(e) >= tol1 && Math.abs(fa) > Math.abs(fb)) {
			s=fb/fa;
			if (a == c) {
				p=2.0*xm*s;
				q=1.0-s;
			} else {
				q=fa/fc;
				r=fb/fc;
				p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
				q=(q-1.0)*(r-1.0)*(s-1.0);
			}
			if (p > 0.0)  q = -q;
			p=Math.abs(p);
			min1=3.0*xm*q-Math.abs(tol1*q);
			min2=Math.abs(e*q);
			if (2.0*p < (min1 < min2 ? min1 : min2)) {
				e=d;
				d=p/q;
			} else {
				d=xm;
				e=d;
			}
		} else {
			d=xm;
			e=d;
		}
		a=b;
		fa=fb;
		if (Math.abs(d) > tol1)
			b += d;
		else
			b += (xm > 0.0 ? Math.abs(tol1) : -Math.abs(tol1));
		fb=fx(b);
	}
	JOptionPane.showMessageDialog(null,"n="+n+"Uyarı maximum iterasyon sayısı aşıldı \n"+
   " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE);
return b;
}

public double N(double beta)
{double bb=beta*beta+H*H;
 double nn=(a*bb+H)/2.0/bb;
 return nn;
}
public static double[][] gauss_legendre_coefficients(double x1,double x2,int n)
{
	//calculates legendre gauss-coefficients as coefficients of the integral
	//for n terms
	double EPS=3.0e-15;
	int m,j,i;
	double z1,z,xm,xl,pp,p3,p2,p1;
    //double x[]=new double[n];
    //double w[]=new double[n];
    double a[][]=new double[2][n];//a[0][i]=x[i]   a[1][i]=w[i]
	m=(n+1)/2;
	xm=0.5*(x2+x1);
	xl=0.5*(x2-x1);
	for (i=1;i<=m;i++)  {
		z=Math.cos(Math.PI*((i-0.25)/(n+0.5)));
		do {
			p1=1.0;
			p2=0.0;
			for (j=1;j<=n;j++) {
				p3=p2;
				p2=p1;
				p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
			}
			pp=n*(z*p1-p2)/(z*z-1.0);
			z1=z;
			z=z1-p1/pp;
		} while (Math.abs(z-z1) > EPS);
		a[0][i-1]=xm-xl*z;
		a[0][n-i]=xm+xl*z;
		a[1][i-1]=2.0*xl/((1.0-z*z)*pp*pp);
		a[1][n-i]=a[1][i-1];
			}
return a;
}

public static double integral(f_x f_xnt,double x1,double x2,int n)
{
//n : number of integral coefficients
// this routine first generates gauss legendre coefficients
// for [x1,x2] band 
// then calculates gauss legendre integral
double a[][]=new double[2][n];
a=gauss_legendre_coefficients(x1,x2,n);
//Text.print(Text.T(a));
//System.out.println(Matrix.toString(a));
double z=0;
for(int i=0;i<n;i++)
{ z+=a[1][i]*f_xnt.func(a[0][i]);}
return z;
}

public double Cm(double beta)
{   fx f=new fx(a,beta);
	double cc=1.0/N(beta)/Math.cosh(beta*b)*integral(f,0,a,50);
return cc;
}

public double T(double x,double y)
{
double T=0;
for(int n=1;n<=10;n++)
{
 T+=C[n-1]*Math.cosh(beta[n-1]*(b-y))*Math.cos(beta[n-1]*x);
}
return T;	
}


public static void main(String arg[])
{ HT_EX2_11 w=new HT_EX2_11(1.0,1.0,0.5);
  for(int n=1;n<10;n++)
 {System.out.println(w.beta(n));}
}

}