/Users/lyon/j4p/src/math/linearAlgebra/examples/MagicSquareExample.java
|
1 package math.linearAlgebra.examples;
2
3 import math.linearAlgebra.EigenvalueDecomposition;
4 import math.linearAlgebra.LUDecomposition;
5 import math.linearAlgebra.Matrix;
6 import math.linearAlgebra.QRDecomposition;
7
8 import java.util.Date;
9
10 /** Example of use of Matrix Class, featuring magic squares. **/
11
12 public class MagicSquareExample {
13
14 /** Generate magic square test matrix. **/
15
16 public static Matrix magic(int n) {
17
18 double[][] M = new double[n][n];
19
20 // Odd order
21
22 if ((n % 2) == 1) {
23 int a = (n + 1) / 2;
24 int b = (n + 1);
25 for (int j = 0; j < n; j++) {
26 for (int i = 0; i < n; i++) {
27 M[i][j] = n * ((i + j + a) % n) + ((i + 2 * j + b) % n) + 1;
28 }
29 }
30
31 // Doubly Even Order
32
33 } else if ((n % 4) == 0) {
34 for (int j = 0; j < n; j++) {
35 for (int i = 0; i < n; i++) {
36 if (((i + 1) / 2) % 2 == ((j + 1) / 2) % 2) {
37 M[i][j] = n * n - n * i - j;
38 } else {
39 M[i][j] = n * i + j + 1;
40 }
41 }
42 }
43
44 // Singly Even Order
45
46 } else {
47 int p = n / 2;
48 int k = (n - 2) / 4;
49 Matrix A = magic(p);
50 for (int j = 0; j < p; j++) {
51 for (int i = 0; i < p; i++) {
52 double aij = A.get(i, j);
53 M[i][j] = aij;
54 M[i][j + p] = aij + 2 * p * p;
55 M[i + p][j] = aij + 3 * p * p;
56 M[i + p][j + p] = aij + p * p;
57 }
58 }
59 for (int i = 0; i < p; i++) {
60 for (int j = 0; j < k; j++) {
61 double t = M[i][j];
62 M[i][j] = M[i + p][j];
63 M[i + p][j] = t;
64 }
65 for (int j = n - k + 1; j < n; j++) {
66 double t = M[i][j];
67 M[i][j] = M[i + p][j];
68 M[i + p][j] = t;
69 }
70 }
71 double t = M[k][0];
72 M[k][0] = M[k + p][0];
73 M[k + p][0] = t;
74 t = M[k][k];
75 M[k][k] = M[k + p][k];
76 M[k + p][k] = t;
77 }
78 return new Matrix(M);
79 }
80
81 /** Shorten spelling of print. **/
82
83 private static void print(String s) {
84 System.out.print(s);
85 }
86
87 /** Format double with Fw.d. **/
88
89 public static String fixedWidthDoubletoString(double x, int w, int d) {
90 java.text.DecimalFormat fmt = new java.text.DecimalFormat();
91 fmt.setMaximumFractionDigits(d);
92 fmt.setMinimumFractionDigits(d);
93 fmt.setGroupingUsed(false);
94 String s = fmt.format(x);
95 while (s.length() < w) {
96 s = " " + s;
97 }
98 return s;
99 }
100
101 /** Format integer with Iw. **/
102
103 public static String fixedWidthIntegertoString(int n, int w) {
104 String s = Integer.toString(n);
105 while (s.length() < w) {
106 s = " " + s;
107 }
108 return s;
109 }
110
111
112 public static void main(String argv[]) {
113
114 /*
115 | Tests LU, QR, SVD and symmetric Eig decompositions.
116 |
117 | n = order of magic square.
118 | trace = diagonal sum, should be the magic sum, (n^3 + n)/2.
119 | max_eig = maximum eigenvalue of (A + A')/2, should equal trace.
120 | rank = linear algebraic rank,
121 | should equal n if n is odd, be less than n if n is even.
122 | cond = L_2 condition number, ratio of singular values.
123 | lu_res = test of LU factorization, norm1(L*U-A(p,:))/(n*eps).
124 | qr_res = test of QR factorization, norm1(Q*R-A)/(n*eps).
125 */
126
127 print("\n Test of Matrix Class, using magic squares.\n");
128 print(" See MagicSquareExample.main() for an explanation.\n");
129 print("\n n trace max_eig rank cond lu_res qr_res\n\n");
130
131 Date start_time = new Date();
132 double eps = Math.pow(2.0, -52.0);
133 for (int n = 3; n <= 32; n++) {
134 print(fixedWidthIntegertoString(n, 7));
135
136 Matrix M = magic(n);
137
138 int t = (int) M.trace();
139 print(fixedWidthIntegertoString(t, 10));
140
141 EigenvalueDecomposition E =
142 new EigenvalueDecomposition(M.plus(M.transpose()).times(0.5));
143 double[] d = E.getRealEigenvalues();
144 print(fixedWidthDoubletoString(d[n - 1], 14, 3));
145
146 int r = M.rank();
147 print(fixedWidthIntegertoString(r, 7));
148
149 double c = M.cond();
150 print(c < 1 / eps ? fixedWidthDoubletoString(c, 12, 3) :
151 " Inf");
152
153 LUDecomposition LU = new LUDecomposition(M);
154 Matrix L = LU.getL();
155 Matrix U = LU.getU();
156 int[] p = LU.getPivot();
157 Matrix R = L.times(U).minus(M.getMatrix(p, 0, n - 1));
158 double res = R.norm1() / (n * eps);
159 print(fixedWidthDoubletoString(res, 12, 3));
160
161 QRDecomposition QR = new QRDecomposition(M);
162 Matrix Q = QR.getQ();
163 R = QR.getR();
164 R = Q.times(R).minus(M);
165 res = R.norm1() / (n * eps);
166 print(fixedWidthDoubletoString(res, 12, 3));
167
168 print("\n");
169 }
170 Date stop_time = new Date();
171 double etime = (stop_time.getTime() - start_time.getTime()) / 1000.;
172 print("\nElapsed Time = " +
173 fixedWidthDoubletoString(etime, 12, 3) + " seconds\n");
174 print("Adios\n");
175 }
176 }
177