public static double Digamma(double x)
{
if (x == 0)
return Double.NegativeInfinity;
double s = 0;
double w = 0;
double y = 0;
double z = 0;
double nz = 0;
bool negative = false;
if (x <= 0.0)
{
negative = true;
double q = x;
double p = (int)System.Math.Floor(q);
if (p == q)
throw new OverflowException("Function computation resulted in arithmetic overflow.");
nz = q - p;
if (nz != 0.5)
{
if (nz > 0.5)
{
p = p + 1.0;
nz = q - p;
}
nz = Math.PI / Math.Tan(System.Math.PI * nz);
}
else
{
nz = 0.0;
}
x = 1.0 - x;
}
if (x <= 10.0 & x == Math.Floor(x))
{
y = 0.0;
int n = (int)Math.Floor(x);
for (int i = 1; i <= n - 1; i++)
{
w = i;
y = y + 1.0 / w;
}
y = y - 0.57721566490153286061;
}
else
{
s = x;
w = 0.0;
while (s < 10.0)
{
w = w + 1.0 / s;
s = s + 1.0;
}
if (s < 1.0E17)
{
z = 1.0 / (s * s);
double polv = 8.33333333333333333333E-2;
polv = polv * z - 2.10927960927960927961E-2;
polv = polv * z + 7.57575757575757575758E-3;
polv = polv * z - 4.16666666666666666667E-3;
polv = polv * z + 3.96825396825396825397E-3;
polv = polv * z - 8.33333333333333333333E-3;
polv = polv * z + 8.33333333333333333333E-2;
y = z * polv;
}
else
{
y = 0.0;
}
y = Math.Log(s) - 0.5 / s - y - w;
}
if (negative == true)
{
y = y - nz;
}
return y;
}