Hypergeometric Functions
using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// Hypergeometric Functions
/// </summary>
public class Hypergeo
{
//private Complex series, deriv;
private Hypergeo()
{
}
public static void hypser(Complex a, Complex b, Complex c, Complex z, Complex series, Complex deriv)
{
deriv = new Complex(0.0);
Complex fac = new Complex(1.0);
Complex temp = new Complex(fac);
Complex aa = new Complex(a);
Complex bb = new Complex(b);
Complex cc = new Complex(c);
for (int n = 1; n <= 1000; n++)
{
fac *= ((aa * bb) / cc);
deriv += fac;
fac *= ((1.0 / n) * z);
series = temp + fac;
if (series == temp)
{
return;
}
temp = series;
aa += 1.0;
bb += 1.0;
cc += 1.0;
}
throw new Exception("convergence failure in hypser");
}
public Complex hypgeo0(Complex a, Complex b, Complex c, Complex z)
{
double atol = 1.0e-14;
double rtol = 1.0e-14;
Complex ans = new Complex();
Complex dz = new Complex();
Complex z0 = new Complex();
Complex[] y = new Complex[2];
double[] yy = new double[4];
if ((z.norm()) <= 0.25)
{
hypser(a, b, c, z, ans, y[1]);
return ans;
}
else if ((z.re) < 0.0)
{
z0 = new Complex(-0.5, 0.0);
}
else if ((z.re) <= 1.0)
{
z0 = new Complex(0.5, 0.0);
}
else
{
z0 = new Complex(0.0, (z.im) >= 0.0 ? 0.5 : -0.5);
}
dz = z - z0;
hypser(a, b, c, z0, y[0], y[1]);
yy[0] = (y[0].re);
yy[1] = (y[0].im);
yy[2] = (y[1].re);
yy[3] = (y[1].im);
Hypderiv d = new Hypderiv(a, b, c, z0, dz);
Output xout = new Output();
StepperBS s = new StepperBS();
Odeint ode = new Odeint(yy, 0.0, 1.0, atol, rtol, 0.1, 0.0, xout, d, s);
ode.integrate();
y[0] = new Complex(yy[0], yy[1]);
return y[0];
}
public Complex hypgeo(Complex a, Complex b, Complex c, Complex z)
{
Hypergeo h = new Hypergeo();
return h.hypgeo0(a, b, c, z);
}
}
}