Mercurial > matrix-functions
view matrixcomp/gep.m @ 0:8f23314345f4 draft
Create local repository for matrix toolboxes. Step #0 done.
author | Antonio Pino Robles <data.script93@gmail.com> |
---|---|
date | Wed, 06 May 2015 14:56:53 +0200 |
parents | |
children |
line wrap: on
line source
function [L, U, P, Q, rho, ncomp] = gep(A, piv) %GEP Gaussian elimination with pivoting: none, complete, partial or rook. % [L, U, P, Q, RHO] = GEP(A, piv) computes the factorization P*A*Q = L*U % of the m-by-n matrix A, where m >= n, % where L is m-by-n unit lower triangular, U is n-by-n upper triangular, % and P and Q are permutation matrices. RHO is the growth factor. % PIV controls the pivoting strategy: % PIV = 'c': complete pivoting, % PIV = 'p': partial pivoting, % PIV = 'r': rook pivoting. % The default is no pivoting (PIV = ''). % For PIV = 'r' only, NCOMP is the total number of comparisons. % % By itself, GEP(A) returns the final reduced matrix from the % elimination containing both L and U. % Reference: % N. J. Higham, Accuracy and Stability of Numerical Algorithms, % Second edition, Society for Industrial and Applied Mathematics, % Philadelphia, PA, 2002; chap. 9. [m, n] = size(A); if m < n, error('Matrix must be m-by-n with m >= n.'), end if nargin < 2, piv = ''; end pp = 1:m; qq = 1:n; if nargout >= 5 maxA = norm(A(:), inf); rho = maxA; end ncomp = 0; for k = 1:min(m-1,n) if findstr(piv, 'cpr') if strcmp(piv, 'c') % Find largest element in remaining square submatrix. % Note: when tie for max, no guarantee which element is chosen. [colmaxima, rowindices] = max( abs(A(k:m, k:n)) ); [biggest, colindex] = max(colmaxima); row = rowindices(colindex)+k-1; col = colindex+k-1; elseif strcmp(piv, 'p') % Find largest element in k'th column. [colmaxima, rowindices] = max( abs(A(k:m, k)) ); row = rowindices(1)+k-1; col = k; elseif strcmp(piv, 'r') % Find element that is largest in its row and its column. col_last = k; for it = 1:inf [colmaxima, rowindices] = max( abs(A(k:m, col_last)) ); ncomp = ncomp + m-k; row = rowindices(1)+k-1; new_abs = abs(A(row,col_last)); if it > 1 if new_abs == last_abs row = row_last; break end end last_abs = new_abs; row_last = row; [rowmaxima, colindices] = max( abs(A(row, k:n)) ); ncomp = ncomp + n-k; col = colindices(1)+k-1; new_abs = abs(A(row,col)); if new_abs == last_abs col = col_last; break end last_abs = new_abs; col_last = col; end end % Permute largest element into pivot position. A( [k, row], : ) = A( [row, k], : ); A( :, [k, col] ) = A( :, [col, k] ); pp( [k, row] ) = pp( [row, k] ); qq( [k, col] ) = qq( [col, k] ); end if A(k,k) == 0 if findstr(piv, 'c') break elseif strcmp(piv, '') % Zero pivot is problem only for no pivoting. error('Elimination breaks down with zero pivot. Quitting...') end end i = k+1:m; if A(k,k) ~= 0 % Simplest way to handle zero pivot for partial and rook. A(i,k) = A(i,k)/A(k,k); % Multipliers. end if k+1 <= n % Elimination j = k+1:n; A(i,j) = A(i,j) - A(i,k) * A(k,j); if nargout >= 5, rho = max( rho, max(max(abs(A(i,j)))) ); end end end if nargout <= 1 L = A; return end L = tril(A,-1) + eye(m,n); U = triu(A); U = U(1:n,:); if nargout >= 3, P = eye(m); P = P(pp,:); end if nargout >= 4, Q = eye(n); Q = Q(:,qq); end if nargout >= 5, rho = rho/maxA; end