[R] row echelon form
Scott Hyde
hydes at byuh.edu
Sat Sep 1 05:57:02 CEST 2007
Hi everyone,
I am looking to use R as a MATLAB replacement for linear algebra.
I've done a fairly good job for finding replacements for most of the
functions I'm interested in, I
John Fox wrote a program for implementing the reduced row echelon form
of a matrix (by doing the Gauss-Jordan elimination). I modified it a
bit:
rref <- function(A, tol=sqrt(.Machine$double.eps),verbose=FALSE,
fractions=FALSE){
## A: coefficient matrix
## tol: tolerance for checking for 0 pivot
## verbose: if TRUE, print intermediate steps
## fractions: try to express nonintegers as rational numbers
## Written by John Fox
if (fractions) {
mass <- require(MASS)
if (!mass) stop("fractions=TRUE needs MASS package")
}
if ((!is.matrix(A)) || (!is.numeric(A)))
stop("argument must be a numeric matrix")
n <- nrow(A)
m <- ncol(A)
for (i in 1:min(c(m, n))){
col <- A[,i]
col[1:n < i] <- 0
# find maximum pivot in current column at or below current row
which <- which.max(abs(col))
pivot <- A[which, i]
if (abs(pivot) <= tol) next # check for 0 pivot
if (which > i) A[c(i, which),] <- A[c(which, i),] # exchange rows
A[i,] <- A[i,]/pivot # pivot
row <- A[i,]
A <- A - outer(A[,i], row) # sweep
A[i,] <- row # restore current row
if (verbose)
if (fractions) print(fractions(A))
else print(round(A,round(abs(log(tol,10)))))
}
for (i in 1:n)
if (max(abs(A[i,1:m])) <= tol)
A[c(i,n),] <- A[c(n,i),] # 0 rows to bottom
if (fractions) fractions (A)
else round(A, round(abs(log(tol,10))))
}
I've found its useful for my students.
I wrote a program for implementing row echelon form, which is only
concerned with the getting the lower triangular part to be zero, along
with the first non-zero entry in each non-zero row being a one. Here
is what I wrote:
ref <- function(A) {
## Implements gaussian elimination using the QR factorization.
## Note: ref form is not unique.
## written by S. K. Hyde
##
qrA <- qr(A)
r <- qrA$rank ##computed rank of the matrix
R <- qr.R(qrA)
if (r < nrow(R))
R[-(1:r),] <- 0 #zero out rows that should be zero (according to the rank).
#Get ones as the first nonzero entry in each row and return result.
diag(c(1/diag(R)[1:r],rep(1,nrow(R)-r)))%*%R
}
Any suggestions of problems that anyone sees?
-Scott
--
*****************************************************************
Scott K. Hyde
Assistant Professor of Statistics and Mathematics
Brigham Young University -- Hawaii
More information about the R-help
mailing list