public static void Jacobi(MatrixR A, double tolerance, out MatrixR x, out VectorR lambda) { MatrixR AA = A.Clone(); int n = A.GetCols(); int maxTransform = 5 * n * n; MatrixR matrix = new MatrixR(n, n); MatrixR R = matrix.Identity(); MatrixR R1 = R; MatrixR A1 = A; lambda = new VectorR(n); x = R; double maxTerm = 0.0; int I, J; do { maxTerm = MaxTerm(A, out I, out J); Transformation(A, R, I, J, out A1, out R1); A = A1; R = R1; }while (maxTerm > tolerance); x = R; for (int i = 0; i < n; i++) { lambda[i] = A[i, i]; } for (int i = 0; i < n - 1; i++) { int index = i; double d = lambda[i]; for (int j = i + 1; j < n; j++) { if (lambda[j] > d) { index = j; d = lambda[j]; } } if (index != i) { lambda = lambda.GetSwap(i, index); x = x.GetColSwap(i, index); } } }
public static MatrixR Tridiagonalize(MatrixR A) { int n = A.GetCols(); MatrixR A1 = new MatrixR(n, n); A1 = A.Clone(); double h, g, unorm; for (int i = 0; i < n - 2; i++) { VectorR u = new VectorR(n - i - 1); for (int j = i + 1; j < n; j++) { u[j - i - 1] = A[i, j]; } unorm = u.GetNorm(); if (u[0] < 0.0) { unorm = -unorm; } u[0] += unorm; for (int j = i + 1; j < n; j++) { A[j, i] = u[j - i - 1]; } h = VectorR.DotProduct(u, u) * 0.5; VectorR v = new VectorR(n - i - 1); MatrixR a1 = new MatrixR(n - i - 1, n - i - 1); for (int j = i + 1; j < n; j++) { for (int k = i + 1; k < n; k++) { a1[j - i - 1, k - i - 1] = A[j, k]; } } v = MatrixR.Transform(a1, u) / h; g = VectorR.DotProduct(u, v) / (2.0 * h); v -= g * u; for (int j = i + 1; j < n; j++) { for (int k = i + 1; k < n; k++) { A[j, k] = A[j, k] - v[j - i - 1] * u[k - i - 1] - u[j - i - 1] * v[k - i - 1]; } } A[i, i + 1] = -unorm; } Alpha = new double[n]; Beta = new double[n - 1]; Alpha[0] = A[0, 0]; for (int i = 1; i < n; i++) { Alpha[i] = A[i, i]; Beta[i - 1] = A[i - 1, i]; } MatrixR V = new MatrixR(n, n); V = V.Identity(); for (int i = 0; i < n - 2; i++) { VectorR u = new VectorR(n - i - 1); for (int j = i + 1; j < n; j++) { u[j - i - 1] = A.GetColVector(i)[j]; } h = VectorR.DotProduct(u, u) * 0.5; VectorR v = new VectorR(n - 1); MatrixR v1 = new MatrixR(n - 1, n - i - 1); for (int j = 1; j < n; j++) { for (int k = i + 1; k < n; k++) { v1[j - 1, k - i - 1] = V[j, k]; } } v = MatrixR.Transform(v1, u) / h; for (int j = 1; j < n; j++) { for (int k = i + 1; k < n; k++) { V[j, k] -= v[j - 1] * u[k - i - 1]; } } } return(V); }