Уменьшенный ряд эшелонов - PullRequest
10 голосов
/ 27 июня 2010

Есть ли в R функция, которая производит reduced row echelon form матрицы? Эта ссылка говорит, что нет.Вы согласны?

Ответы [ 4 ]

17 голосов
/ 17 декабря 2014

Мне не хватает представителя, чтобы комментировать, но функция, указанная выше soldier.moth в принятом ответе [править 2018: больше не принятый ответ], глючит - не обрабатывает матрицы, в которых решение RREF имеет нули на главной диагонали. Попробуйте, например,

т <-матрица (с (1,0,1,0,0,2), byrow = TRUE, то nrow = 2) RREF (м) </p>

и обратите внимание, что вывод не в RREF.

Я думаю, у меня это работает, но вы можете сами проверить результаты:

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
  # Modified by Geoffrey Brent 2014-12-17 to fix a bug
  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)
  x.position<-1
  y.position<-1
  # change loop:
  while((x.position<=m) & (y.position<=n)){
    col <- A[,x.position]
    col[1:n < y.position] <- 0
    # find maximum pivot in current column at or below current row
    which <- which.max(abs(col))
    pivot <- col[which]
    if (abs(pivot) <= tol) x.position<-x.position+1     # check for 0 pivot
    else{
      if (which > y.position) { A[c(y.position,which),]<-A[c(which,y.position),] } # exchange rows
      A[y.position,]<-A[y.position,]/pivot # pivot
      row <-A[y.position,]
      A <- A - outer(A[,x.position],row) # sweep
      A[y.position,]<-row # restore current row
      if (verbose)
        if (fractions) print(fractions(A))
        else print(round(A,round(abs(log(tol,10)))))
      x.position<-x.position+1
      y.position<-y.position+1
    }
  }
  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))))
}
8 голосов
/ 03 мая 2013

Пакет pracma также содержит реализацию. См. Pracma :: rref.

6 голосов
/ 22 июня 2016

Существует также недавний пакет, разработанный для обучения Линейная алгебра ( matlib ), который вычисляет эшелонную форму матрицы и показывает шаги, используемые на этом пути.

Пример из справочных документов :

library('matlib')
A <- matrix(c(2, 1, -1,-3, -1, 2,-2, 1, 2), 3, 3, byrow=TRUE)
b <- c(8, -11, -3)
echelon(A, b, verbose=TRUE, fractions=TRUE)

Initial matrix:
     [,1] [,2] [,3] [,4]
[1,]   2    1   -1    8 
[2,]  -3   -1    2  -11 
[3,]  -2    1    2   -3 

row: 1 

 exchange rows 1 and 2 
     [,1] [,2] [,3] [,4]
[1,]  -3   -1    2  -11 
[2,]   2    1   -1    8 
[3,]  -2    1    2   -3 

 multiply row 1 by -1/3 
     [,1] [,2] [,3] [,4]
[1,]    1  1/3 -2/3 11/3
[2,]    2    1   -1    8
[3,]   -2    1    2   -3

 multiply row 1 by 2 and subtract from row 2 
     [,1] [,2] [,3] [,4]
[1,]    1  1/3 -2/3 11/3
[2,]    0  1/3  1/3  2/3
[3,]   -2    1    2   -3

 multiply row 1 by 2 and add to row 3 
     [,1] [,2] [,3] [,4]
[1,]    1  1/3 -2/3 11/3
[2,]    0  1/3  1/3  2/3
[3,]    0  5/3  2/3 13/3

row: 2 

 exchange rows 2 and 3 
     [,1] [,2] [,3] [,4]
[1,]    1  1/3 -2/3 11/3
[2,]    0  5/3  2/3 13/3
[3,]    0  1/3  1/3  2/3

 multiply row 2 by 3/5 
     [,1] [,2] [,3] [,4]
[1,]    1  1/3 -2/3 11/3
[2,]    0    1  2/5 13/5
[3,]    0  1/3  1/3  2/3

 multiply row 2 by 1/3 and subtract from row 1 
     [,1] [,2] [,3] [,4]
[1,]    1    0 -4/5 14/5
[2,]    0    1  2/5 13/5
[3,]    0  1/3  1/3  2/3

 multiply row 2 by 1/3 and subtract from row 3 
     [,1] [,2] [,3] [,4]
[1,]    1    0 -4/5 14/5
[2,]    0    1  2/5 13/5
[3,]    0    0  1/5 -1/5

row: 3 

 multiply row 3 by 5 
     [,1] [,2] [,3] [,4]
[1,]    1    0 -4/5 14/5
[2,]    0    1  2/5 13/5
[3,]    0    0    1   -1

 multiply row 3 by 4/5 and add to row 1 
     [,1] [,2] [,3] [,4]
[1,]    1    0    0    2
[2,]    0    1  2/5 13/5
[3,]    0    0    1   -1

 multiply row 3 by 2/5 and subtract from row 2 
     [,1] [,2] [,3] [,4]
[1,]  1    0    0    2  
[2,]  0    1    0    3  
[3,]  0    0    1   -1  
4 голосов
/ 27 июня 2010

Не похоже, что он встроен, но я нашел эту функцию rref на этой странице.

 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))))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...