R эквивалентно diag (x, k) в matlab

#r #matlab

#r #matlab

Вопрос:

Я думаю, у меня есть двухуровневый вопрос, относящийся к diag R и matlab.

1) Мне было интересно, существует ли уже разработанный способ доступа к различным диагоналям матриц в R аналогично тому, как это делается в Matlab (см. http://www.mathworks.com/help/techdoc/ref/diag.html ).

2) Если текущей функции еще нет, как можно улучшить мой код, чтобы он был похож на R diag , где

 diag(x = 1, nrow, ncol) # returns the values of the diagonal
diag(x) <- value # inserts values on the diagonal
  

В настоящее время мой код возвращает элементы по диагонали с заданным значением k, но как его можно записать так, чтобы, если он указан как второй способ (выше), он позволял мне вставлять значения по диагонали. В настоящее время для этого я использую diag.ind , чтобы указать индексы, а затем использовать эти индексы для вставки значений по диагонали k.

Вот код:

 'diag.ind'<-function(x,k=0){
   if(k=='') k=0
   x<-as.matrix(x)

   if(dim(x)[2]==dim(x)[1]){
     stp_pt_r<-dim(x)[1]
     stp_pt_c<-dim(x)[2]
   }
   if(ncol(x)> dim(x)[1]){
     stp_pt_r<-dim(x)[1]
     stp_pt_c<-stp_pt_r   1
   }
   if(ncol(x)< dim(x)[1]){
    stp_pt_c<-dim(x)[2]
    stp_pt_r<-stp_pt_c 1
   }

   if(k==0){
   r<-as.matrix(seq(1,stp_pt_r,by=1))
   c<-as.matrix(seq(1,stp_pt_c,by=1))
   ind.r<- cbind(r,c)
   }
  if(k>0){
    r<-t(as.matrix(seq(1,stp_pt_r,by=1)))
    c<-t(as.matrix(seq((1 k),stp_pt_c,by=1)))
   ind<-t(rbind.fill.matrix(r,c))
   ind.r<-ind[!is.na(ind[,2]),]
  }
  if(k<0){
    k<-abs(k)
    r<-t(as.matrix(seq((1 k),stp_pt_r,by=1)))
    c<-t(as.matrix(seq(1,stp_pt_c,by=1)))
    ind<-t(rbind.fill.matrix(r,c))
    ind.r<-ind[!is.na(ind[,1]),]
  }
diag.x<-x[ind.r]

output<-list(diag.x=diag.x, diag.ind=ind.r)
return(output)
}
  

Это довольно неуклюже, и я чувствую, что должен изобретать велосипед. Заранее спасибо за любую информацию!

Ответ №1:

После вашего ответа на Andrie это может удовлетворить:

  exdiag <- function(mat, off) {mat[row(mat) off == col(mat)]}
 x <- matrix(1:16, ncol=4)
 exdiag(x,1)
#[1]  5 10 15
  

Я думал, вам нужна функция, которая может назначать или возвращать одну из диагональных или суб- или супердиагональных матриц, это функция конструктора:

 subdiag <- function(vec, size, offset=0){ 
      M <- matrix(0, size, size)
      M[row(M)-offset == col(M)] <- vec
      return(M)}
> subdiag(1, 5, 1)
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    1    0    0    0    0
[3,]    0    1    0    0    0
[4,]    0    0    1    0    0
[5,]    0    0    0    1    0
  

Вызываемый только с двумя аргументами, вы получите диагональную матрицу. Вы можете создавать супердиагональные матрицы с отрицательными смещениями. Если это то, что вы хотели для конструктора, то не должно быть слишком сложно создать аналогичную subdiag<- функцию, чтобы она соответствовала ей.

Комментарии:

1. Отлично, это то, что я искал, и намного проще, чем мой код. Спасибо!

Ответ №2:

В MATLAB, чтобы присвоить значения x диагонали A :

 n = size(A,1);
A(1:n 1:end) = x
  

Найдите линейную индексацию.

Хотя, возможно, это не то, что вы просили.