function Y = rref(A) % ---------------------------------------------------------------------- % J. R. Senning % Gordon College % February 15, 1995 % % $Id: rref.m,v 1.4 2005/02/03 18:26:44 senning Exp $ % % Computes the reduced row echelon form of a rectangular matrix A. % % February 10, 1998: Partial pivoting is still used, but now if the % RREF of the matrix has a row of zeros it is handled properly. This % is done by assuming the maxmimal pivot-element candidate is zero if % it is less than 10 times the machine epsilon. On a given row, if % no nonzero pivot element can be found then we give up on that row. % % February 3, 2000: Check to make sure that "c" (the pivot column) % is not greater than the number of columns in the matrix - this can % happen when the matrix does not have a pivot in each column. % % February 3, 2005: Change so the function ends with "endfunction" # keyword. % ---------------------------------------------------------------------- my_eps = 10 * eps; if nargin ~= 1 disp(setstr(7)), disp('Correct format: Y = rref(A)') return endif [rows cols] = size(A); c = 1; for k = [1 : min(rows, cols)] % % Find biggest element (in absolute value) in column c between row r % and the last row. If this is zero then we need to move one column % to the right and try again. If we end up at the right-most column % and still can't find a nonzero biggest element then we are done. % r = k; biggest = max(abs(A(r:rows,c))); while (abs(biggest) < my_eps) && (c < cols) c = c + 1; biggest = max(abs(A(r:rows,c))); endwhile % % check to see if we are at the end of a row but are still looking % for a nonzero pivot. If we haven't found one then we give up... % if (abs(biggest) < my_eps) && (c == cols) break; endif % % Once a biggest element is found, we need to swap rows so that it % will become the pivot element. First find the row that contains % the biggest element then swap the rows. % while (biggest > abs(A(r,c))) && (r < rows) r = r + 1; endwhile if r != k temp_v = A(k,:); A(k,:) = A(r,:); A(r,:) = temp_v; endif % % Now we can scale the row with the newly-found pivot and use it to % eliminate all other entries in the pivot column. % A(k,:) = A(k,:) / A(k,c); for j = [1 : rows] if j != k A(j,:) = A(j,:) - A(k,:) * A(j,c); endif endfor % % Finally, move to next column (if it exists) and repeat! % c = c + 1; if ( c > cols ) break; endif endfor % % Ok, we're done. If the elements in the matrix differ no less than my_eps % from integer values then we assume that the matrix should have only % integer values. % if (max(abs(A - round(A))) < my_eps) Y = round(A); else Y = A; endif endfunction