@@ -118,26 +118,56 @@ static float magnitude(float[] v) {
118118 /**
119119 * Compute Q and R for QR decomposition of A such that A=QR.
120120 * Q and R should be matrices of the same size as A; their contents will be overwritten by the computation.
121+ * R's contents are ignored but
121122 */
122123 static void qrDecomp (float [][] A , float [][] Q , float [][] R ) {
123124 int m = A .length ; // rows
124125 int n = A [0 ].length ; // columns
125126
126- // Modified Gram-Schmidt
127- for (int i = 0 ; i < n ; i ++) {
128- float [] ai = getColumn (A , i );
129- float [] ui = copyVector (ai );
130-
131- for (int j = 0 ; j < i ; j ++) {
132- float [] qj = getColumn (Q , j );
133- float proj = dotProduct (ai , qj ); // Project on already-orthogonalized vectors
134- R [j ][i ] = proj ; // Fill the upper-triangular matrix R
135- ui = subtract (ui , scale (qj , proj )); // Orthogonalize with respect to already-orthogonalized vectors
127+ // Householder decomposition
128+ for (int k = 0 ; k < n ; k ++) {
129+ float [] x = getColumn (A , k );
130+ float [] e = new float [x .length ];
131+ e [0 ] = 1 ;
132+ float [] v_k = subtract (x , scale (e , x [0 ] >= 0 ? -magnitude (x ) : magnitude (x )));
133+ float [][] H_k = subtract (identity (m ), scaleOuterProduct (v_k , v_k , 2 / dotProduct (v_k , v_k )));
134+ float [][] A_next = multiply (H_k , A );
135+
136+ for (int i = 0 ; i < m ; i ++) {
137+ System .arraycopy (A_next [i ], 0 , A [i ], 0 , n );
136138 }
137139
138- R [i ][i ] = magnitude (ui );
139- insertColumn (Q , normalize (ui ), i );
140+ updateColumn (Q , getColumn (H_k , k ), k );
141+ updateColumn (R , getColumn (A , k ), k );
142+ }
143+ }
144+
145+ static float [][] subtract (float [][] mat1 , float [][] mat2 ) {
146+ int rows = mat1 .length ;
147+ int cols = mat1 [0 ].length ;
148+ float [][] result = new float [rows ][cols ];
149+
150+ for (int i = 0 ; i < rows ; i ++) {
151+ for (int j = 0 ; j < cols ; j ++) {
152+ result [i ][j ] = mat1 [i ][j ] - mat2 [i ][j ];
153+ }
140154 }
155+
156+ return result ;
157+ }
158+
159+ static float [][] scaleOuterProduct (float [] u , float [] v , float scale ) {
160+ int rows = u .length ;
161+ int cols = v .length ;
162+ float [][] result = new float [rows ][cols ];
163+
164+ for (int i = 0 ; i < rows ; i ++) {
165+ for (int j = 0 ; j < cols ; j ++) {
166+ result [i ][j ] = u [i ] * v [j ] * scale ;
167+ }
168+ }
169+
170+ return result ;
141171 }
142172
143173 private static float [] copyVector (float [] orig ) {
@@ -154,7 +184,7 @@ private static float[] getColumn(float[][] mat, int columnIndex) {
154184 return column ;
155185 }
156186
157- private static void insertColumn (float [][] mat , float [] col , int colIndex ) {
187+ private static void updateColumn (float [][] mat , float [] col , int colIndex ) {
158188 for (int i = 0 ; i < mat .length ; i ++) {
159189 mat [i ][colIndex ] = col [i ];
160190 }
0 commit comments