private void tql2()
{
// Symmetric tridiagonal QL algorithm.
// This is derived from the Algol procedures tql2, by Bowdler, Martin, Reinsch, and Wilkinson,
// Handbook for Auto. Comp., Vol.ii-Linear Algebra, and the corresponding Fortran subroutine in EISPACK.
for (int i = 1; i < n; i++)
e[i - 1] = e[i];
e[n - 1] = 0;
Double f = 0;
Double tst1 = 0;
Double eps = 2 * Constants.DoubleEpsilon;
for (int l = 0; l < n; l++)
{
// Find small subdiagonal element.
tst1 = System.Math.Max(tst1, System.Math.Abs(d[l]) + System.Math.Abs(e[l]));
int m = l;
while (m < n)
{
if (System.Math.Abs(e[m]) <= eps * tst1)
break;
m++;
}
// If m == l, d[l] is an eigenvalue, otherwise, iterate.
if (m > l)
{
int iter = 0;
do
{
iter = iter + 1; // (Could check iteration count here.)
// Compute implicit shift
Double g = d[l];
Double p = (d[l + 1] - g) / (2 * e[l]);
Double r = Accord.Math.Tools.Hypotenuse(p, 1);
if (p < 0)
{
r = -r;
}
d[l] = e[l] / (p + r);
d[l + 1] = e[l] * (p + r);
Double dl1 = d[l + 1];
Double h = g - d[l];
for (int i = l + 2; i < n; i++)
{
d[i] -= h;
}
f = f + h;
// Implicit QL transformation.
p = d[m];
Double c = 1;
Double c2 = c;
Double c3 = c;
Double el1 = e[l + 1];
Double s = 0;
Double s2 = 0;
for (int i = m - 1; i >= l; i--)
{
c3 = c2;
c2 = c;
s2 = s;
g = c * e[i];
h = c * p;
r = Accord.Math.Tools.Hypotenuse(p, e[i]);
e[i + 1] = s * r;
s = e[i] / r;
c = p / r;
p = c * d[i] - s * g;
d[i + 1] = h + s * (c * g + s * d[i]);
// Accumulate transformation.
for (int k = 0; k < n; k++)
{
h = V[k, i + 1];
V[k, i + 1] = s * V[k, i] + c * h;
V[k, i] = c * V[k, i] - s * h;
}
}
p = -s * s2 * c3 * el1 * e[l] / dl1;
e[l] = s * p;
d[l] = c * p;
// Check for convergence.
}
while (System.Math.Abs(e[l]) > eps * tst1);
}
d[l] = d[l] + f;
e[l] = 0;
}
// Sort eigenvalues and corresponding vectors.
for (int i = 0; i < n - 1; i++)
{
int k = i;
Double p = d[i];
for (int j = i + 1; j < n; j++)
{
if (d[j] < p)
{
k = j;
p = d[j];
}
}
if (k != i)
{
d[k] = d[i];
d[i] = p;
for (int j = 0; j < n; j++)
{
p = V[j, i];
V[j, i] = V[j, k];
V[j, k] = p;
}
}
}
}