private void orthes()
{
// Nonsymmetric reduction to Hessenberg form.
// This is derived from the Algol procedures orthes and ortran, by Martin and Wilkinson,
// Handbook for Auto. Comp., Vol.ii-Linear Algebra, and the corresponding Fortran subroutines in EISPACK.
int low = 0;
int high = n - 1;
for (int m = low + 1; m <= high - 1; m++)
{
// Scale column.
Double scale = 0;
for (int i = m; i <= high; i++)
scale = scale + System.Math.Abs(H[i][m - 1]);
if (scale != 0)
{
// Compute Householder transformation.
Double h = 0;
for (int i = high; i >= m; i--)
{
ort[i] = H[i][m - 1] / scale;
h += ort[i] * ort[i];
}
Double g = (Double)System.Math.Sqrt(h);
if (ort[m] > 0) g = -g;
h = h - ort[m] * g;
ort[m] = ort[m] - g;
// Apply Householder similarity transformation
// H = (I - u * u' / h) * H * (I - u * u') / h)
for (int j = m; j < n; j++)
{
Double f = 0;
for (int i = high; i >= m; i--)
f += ort[i] * H[i][j];
f = f / h;
for (int i = m; i <= high; i++)
H[i][j] -= f * ort[i];
}
for (int i = 0; i <= high; i++)
{
Double f = 0;
for (int j = high; j >= m; j--)
f += ort[j] * H[i][j];
f = f / h;
for (int j = m; j <= high; j++)
H[i][j] -= f * ort[j];
}
ort[m] = scale * ort[m];
H[m][m - 1] = scale * g;
}
}
// Accumulate transformations (Algol's ortran).
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
V[i][j] = (i == j ? 1 : 0);
for (int m = high - 1; m >= low + 1; m--)
{
if (H[m][m - 1] != 0)
{
for (int i = m + 1; i <= high; i++)
ort[i] = H[i][m - 1];
for (int j = m; j <= high; j++)
{
Double g = 0;
for (int i = m; i <= high; i++)
g += ort[i] * V[i][j];
// Double division avoids possible underflow.
g = (g / ort[m]) / H[m][m - 1];
for (int i = m; i <= high; i++)
V[i][j] += g * ort[i];
}
}
}
}