1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.linear;
19
20 import junit.framework.Test;
21 import junit.framework.TestCase;
22 import junit.framework.TestSuite;
23
24 public class QRDecompositionImplTest extends TestCase {
25 double[][] testData3x3NonSingular = {
26 { 12, -51, 4 },
27 { 6, 167, -68 },
28 { -4, 24, -41 }, };
29
30 double[][] testData3x3Singular = {
31 { 1, 4, 7, },
32 { 2, 5, 8, },
33 { 3, 6, 9, }, };
34
35 double[][] testData3x4 = {
36 { 12, -51, 4, 1 },
37 { 6, 167, -68, 2 },
38 { -4, 24, -41, 3 }, };
39
40 double[][] testData4x3 = {
41 { 12, -51, 4, },
42 { 6, 167, -68, },
43 { -4, 24, -41, },
44 { -5, 34, 7, }, };
45
46 private static final double entryTolerance = 10e-16;
47
48 private static final double normTolerance = 10e-14;
49
50 public QRDecompositionImplTest(String name) {
51 super(name);
52 }
53
54 public static Test suite() {
55 TestSuite suite = new TestSuite(QRDecompositionImplTest.class);
56 suite.setName("QRDecompositionImpl Tests");
57 return suite;
58 }
59
60
61 public void testDimensions() {
62 RealMatrixImpl matrix = new RealMatrixImpl(testData3x3NonSingular);
63 QRDecomposition qr = new QRDecompositionImpl(matrix);
64 assertEquals("3x3 Q size", qr.getQ().getRowDimension(), 3);
65 assertEquals("3x3 Q size", qr.getQ().getColumnDimension(), 3);
66 assertEquals("3x3 R size", qr.getR().getRowDimension(), 3);
67 assertEquals("3x3 R size", qr.getR().getColumnDimension(), 3);
68
69 matrix = new RealMatrixImpl(testData4x3);
70 qr = new QRDecompositionImpl(matrix);
71 assertEquals("4x3 Q size", qr.getQ().getRowDimension(), 4);
72 assertEquals("4x3 Q size", qr.getQ().getColumnDimension(), 4);
73 assertEquals("4x3 R size", qr.getR().getRowDimension(), 4);
74 assertEquals("4x3 R size", qr.getR().getColumnDimension(), 3);
75
76 matrix = new RealMatrixImpl(testData3x4);
77 qr = new QRDecompositionImpl(matrix);
78 assertEquals("3x4 Q size", qr.getQ().getRowDimension(), 3);
79 assertEquals("3x4 Q size", qr.getQ().getColumnDimension(), 3);
80 assertEquals("3x4 R size", qr.getR().getRowDimension(), 3);
81 assertEquals("3x4 R size", qr.getR().getColumnDimension(), 4);
82 }
83
84
85 public void testAEqualQR() {
86 RealMatrix A = new RealMatrixImpl(testData3x3NonSingular);
87 QRDecomposition qr = new QRDecompositionImpl(A);
88 RealMatrix Q = qr.getQ();
89 RealMatrix R = qr.getR();
90 double norm = Q.multiply(R).subtract(A).getNorm();
91 assertEquals("3x3 nonsingular A = QR", 0, norm, normTolerance);
92
93 RealMatrix matrix = new RealMatrixImpl(testData3x3Singular);
94 qr = new QRDecompositionImpl(matrix);
95 norm = qr.getQ().multiply(qr.getR()).subtract(matrix).getNorm();
96 assertEquals("3x3 singular A = QR", 0, norm, normTolerance);
97
98 matrix = new RealMatrixImpl(testData3x4);
99 qr = new QRDecompositionImpl(matrix);
100 norm = qr.getQ().multiply(qr.getR()).subtract(matrix).getNorm();
101 assertEquals("3x4 A = QR", 0, norm, normTolerance);
102
103 matrix = new RealMatrixImpl(testData4x3);
104 qr = new QRDecompositionImpl(matrix);
105 norm = qr.getQ().multiply(qr.getR()).subtract(matrix).getNorm();
106 assertEquals("4x3 A = QR", 0, norm, normTolerance);
107 }
108
109
110 public void testQOrthogonal() {
111 RealMatrix matrix = new RealMatrixImpl(testData3x3NonSingular);
112 matrix = new QRDecompositionImpl(matrix).getQ();
113 RealMatrix eye = MatrixUtils.createRealIdentityMatrix(3);
114 double norm = matrix.transpose().multiply(matrix).subtract(eye)
115 .getNorm();
116 assertEquals("3x3 nonsingular Q'Q = I", 0, norm, normTolerance);
117
118 matrix = new RealMatrixImpl(testData3x3Singular);
119 matrix = new QRDecompositionImpl(matrix).getQ();
120 eye = MatrixUtils.createRealIdentityMatrix(3);
121 norm = matrix.transpose().multiply(matrix).subtract(eye)
122 .getNorm();
123 assertEquals("3x3 singular Q'Q = I", 0, norm, normTolerance);
124
125 matrix = new RealMatrixImpl(testData3x4);
126 matrix = new QRDecompositionImpl(matrix).getQ();
127 eye = MatrixUtils.createRealIdentityMatrix(3);
128 norm = matrix.transpose().multiply(matrix).subtract(eye)
129 .getNorm();
130 assertEquals("3x4 Q'Q = I", 0, norm, normTolerance);
131
132 matrix = new RealMatrixImpl(testData4x3);
133 matrix = new QRDecompositionImpl(matrix).getQ();
134 eye = MatrixUtils.createRealIdentityMatrix(4);
135 norm = matrix.transpose().multiply(matrix).subtract(eye)
136 .getNorm();
137 assertEquals("4x3 Q'Q = I", 0, norm, normTolerance);
138 }
139
140
141 public void testRUpperTriangular() {
142 RealMatrixImpl matrix = new RealMatrixImpl(testData3x3NonSingular);
143 RealMatrix R = new QRDecompositionImpl(matrix).getR();
144 for (int i = 0; i < R.getRowDimension(); i++)
145 for (int j = 0; j < i; j++)
146 assertEquals("R lower triangle", R.getEntry(i, j), 0,
147 entryTolerance);
148
149 matrix = new RealMatrixImpl(testData3x4);
150 R = new QRDecompositionImpl(matrix).getR();
151 for (int i = 0; i < R.getRowDimension(); i++)
152 for (int j = 0; j < i; j++)
153 assertEquals("R lower triangle", R.getEntry(i, j), 0,
154 entryTolerance);
155
156 matrix = new RealMatrixImpl(testData4x3);
157 R = new QRDecompositionImpl(matrix).getR();
158 for (int i = 0; i < R.getRowDimension(); i++)
159 for (int j = 0; j < i; j++)
160 assertEquals("R lower triangle", R.getEntry(i, j), 0,
161 entryTolerance);
162 }
163 }