using System; using System.Collections; namespace Science.Mathematics.SpecialFunction { /// /// Hypergeometric /// public class Hypergeometric { public Hypergeometric() { } private static Complex aa,bb,cc,z0,dz; public static Complex Hypergeometric2F1(Complex a, Complex b, Complex c, Complex z) { double EPS = 1.0e-6; Complex ans; Complex[] y = new Complex[2]; double[] yy= new Double[4]; if (z.Real*z.Real+z.Imaginary*z.Imaginary <= 0.25) { hypser(a,b,c,z); ans = series; y[1] = deriv; return ans; } else if (z.Real < 0.0) z0=new Complex(-0.5,0.0); else if (z.Real <= 1.0) z0=new Complex(0.5,0.0); else z0=new Complex(0.0,z.Imaginary >= 0.0 ? 0.5 : -0.5); aa=a; bb=b; cc=c; dz=(z - z0); hypser(aa,bb,cc,z0); y[0]=series; y[1]=deriv; yy[0]=y[0].Real; yy[1]=y[0].Imaginary; yy[2]=y[1].Real; yy[3]=y[1].Imaginary; Function der = new Function(hypdrv); odeint(yy,4,0.0,1.0,EPS,0.1,0.0001,der); y[0]=new Complex(yy[0],yy[1]); return y[0]; } private static double[] hypdrv(double s, double[] yy) { Complex ONE = new Complex(1.0,0.0); double[] dyyds = new Double[4]; Complex z; Complex[] y = new Complex[2]; Complex[] dyds = new Complex[2]; y[0]=new Complex(yy[0],yy[1]); y[1]=new Complex(yy[2],yy[3]); z=(z0 + (s * dz)); dyds[0]=(y[1] * dz); dyds[1]=((((aa*bb)*y[0]) - ((cc - (((aa + bb) + ONE) * z)) * y[1])) * (dz / (z * (ONE - z)))); dyyds[0]=dyds[0].Real; dyyds[1]=dyds[0].Imaginary; dyyds[2]=dyds[1].Real; dyyds[3]=dyds[1].Imaginary; return dyyds; } private static Complex series, deriv; private static void hypser(Complex a, Complex b, Complex c, Complex z) { Complex ONE = new Complex(1.0,0.0); int n; Complex aa,bb,cc,fac,temp; deriv = new Complex(0.0,0.0); fac=new Complex(1.0,0.0); temp=fac; aa=a; bb=b; cc=c; for (n=1;n<=1000;n++) { fac=(fac * (aa * (bb / cc))); deriv.Real+=fac.Real; deriv.Imaginary+=fac.Imaginary; fac=(fac * ((1.0/n)* z)); series=(temp + fac); if (series.Real == temp.Real && series.Imaginary == temp.Imaginary) return; temp= series; aa=(aa + ONE); bb=(bb + ONE); cc=(cc + ONE); } try { throw new Science.Error(); } catch (Science.Error e) { e.Write("convergence failure in hypser"); } } private static ArrayList xp = new ArrayList(1); private static ArrayList[] yp; private static double dxsav=0.0; private static int nok, nbad; private static void odeint(double[] ystart, int nvar, double x1, double x2, double eps, double h1, double hmin, Function derivs) { int MAXSTP = 10000; double TINY = 1.0e-30; yp = new ArrayList[nvar]; for(int j = 0; j < nvar; j++) yp[j] = new ArrayList(1); int nstp,i; double xsav,x,h; double[] yscal,y,dydx; yscal=new Double[nvar]; y=new Double[nvar]; dydx=new Double[nvar]; x=x1; h=Math.Sign(x2-x1)*h1; nok = nbad = 0; for (i=0;i Math.Abs(dxsav)) { xp.Add(x); for (i=0;i 0.0) h=x2-x; rkqs(y,dydx,nvar,x,h,eps,yscal,derivs); x = xout; if (hdid == h) ++nok; else ++nbad; if ((x-x2)*(x2-x1) >= 0.0) { for (i=0;i 1.0) { h=SAFETY*h*Math.Pow(errmax,PSHRNK); if (h < 0.1*h) h *= 0.1; xnew=x+h; if (xnew == x) try { throw new Science.Error(); } catch (Science.Error e) { e.Write("stepsize underflow in rkqs"); } continue; } else { if (errmax > ERRCON) hnext=SAFETY*h*Math.Pow(errmax,PGROW); else hnext=5.0*h; xout = x + (hdid=h); for (i=0;i