private void _improve ( final ColumnVector b , final ColumnVector x ) throws MatrixException { // Find the largest x element. float largestX = 0 ; for ( int r = 0 ; r < m_nRows ; ++ r ) { final float absX = Math . abs ( x . m_aValues [ r ] [ 0 ] ) ; if ( largestX < absX ) largestX = absX ; } // Is x already as good as possible? if ( largestX == 0 ) return ; final ColumnVector residuals = new ColumnVector ( m_nRows ) ; // Iterate to improve x. for ( int iter = 0 ; iter < MAX_ITER ; ++ iter ) { // Compute residuals = b - Ax. // Must use double precision! for ( int r = 0 ; r < m_nRows ; ++ r ) { double dot = 0 ; for ( int c = 0 ; c < m_nRows ; ++ c ) { final double elmt = at ( r , c ) ; dot += elmt * x . at ( c ) ; // dbl.prec. * } final double value = b . at ( r ) - dot ; // dbl.prec. - residuals . set ( r , ( float ) value ) ; } // Solve Az = residuals for z. final ColumnVector z = solve ( residuals , false ) ; // Set x = x + z. // Find largest the largest difference. float largestDiff = 0 ; for ( int r = 0 ; r < m_nRows ; ++ r ) { final float oldX = x . at ( r ) ; x . set ( r , oldX + z . at ( r ) ) ; final float diff = Math . abs ( x . at ( r ) - oldX ) ; if ( largestDiff < diff ) largestDiff = diff ; } // Is any further improvement possible? if ( largestDiff < largestX * TOLERANCE ) return ; } // Failed to converge because A is nearly singular. throw new MatrixException ( MatrixException . NO_CONVERGENCE ) ; }
Iteratively improve the solution x to machine accuracy .