public class Jacobi { public double [][] a, abs; public int p, q; private static int n; public Jacobi(int in) { int i, j; n = in; a = new double[n][n]; abs = new double[n][n]; // initail value for (i = 0; i < n; i++) { for (j = 0; j <= i; j++) { a[i][j] = a[j][i] = 2.0 * (Math.random() - 0.5); abs[i][j] = abs[j][i] = Math.abs(a[i][j]); } } Max(); } private double Max() { double max; p = 1; q = 0; max = abs[1][0]; for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (abs[i][j] > max) { p = i; q = j; max = abs[i][j]; } } } return max; } private void Rotate(int p, int q, double c, double s) { double [][] ww; double cc, ss, cs; cc = c * c; ss = s * s; cs = c * s; ww = abs; for (int i = 0; i < n; i++) { ww[p][i] = ww[i][p] = a[p][i] * c - a[q][i] * s; } for (int i = 0; i < n; i++) { ww[q][i] = ww[i][q] = a[p][i] * s + a[q][i] * c; } ww[p][p] = a[p][p] * cc - 2 * a[p][q] * cs + a[q][q] * ss; ww[q][q] = a[p][p] * ss + 2 * a[p][q] * cs + a[q][q] * cc; ww[p][q] = ww[q][p] = (a[p][p] - a[q][q]) * cs + a[p][q] * (cc - ss); abs = a; a = ww; } public void Step(int loop) { double w, c, s; while (loop-- > 0) { w = (a[q][q] - a[p][p]) / (2 * a[p][q]); if (w >= 0) { w = 1.0 / (w + Math.sqrt(w * w + 1)); } else { w = 1.0 / (w - Math.sqrt(w * w + 1)); } c = 1.0 / Math.sqrt(w * w + 1.0); s = w * c; Rotate(p, q, c, s); for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { abs[i][j] = abs[j][i] = Math.abs(a[i][j]); } } Max(); } } public double SumOffDiag() { double sum = 0.0; for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { sum += abs[i][j] * abs[i][j]; } } return sum; } }