Установить значения по диагонали в матрице - PullRequest
0 голосов
/ 04 февраля 2019

Я пытаюсь использовать функции matrix() и diag() для создания следующего шаблона, но с матрицей 100 x 100 вместо 5 x 5.

5 x 5:

| 0 1 0 0 0 |
| 1 0 1 0 0 |
| 0 1 0 1 0 |
| 0 0 1 0 1 |
| 0 0 0 1 0 |

Другими словами, я хочу иметь две диагонали со значениями 1, одну слева от главной диагонали и одну справа от главной диагонали.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Для основной диагонали индексы строк и столбцов совпадают.Для других диагоналей существует разница 1 между индексом строки и индексом столбца.Сгенерируйте эти индексы напрямую и присвойте значения этим индексам.

sz = 5
m = matrix(0, sz, sz)
inds1 = cbind(r = 1:(sz-1), c = 2:sz)
inds2 = cbind(r = 2:sz, c = 1:(sz-1))
m[inds1] = 1
m[inds2] = 1
m

# OR, to make it concise
m = matrix(0, sz, sz)
inds = rbind(cbind(1:(sz-1), 2:sz), cbind(2:sz, 1:(sz-1)))
replace(m, inds, 1)

#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    1    0    0    0
#[2,]    1    0    1    0    0
#[3,]    0    1    0    1    0
#[4,]    0    0    1    0    1
#[5,]    0    0    0    1    0
0 голосов
/ 04 февраля 2019

Функция diag() (фактически функция diag<-) может использоваться для назначения:

mat <- matrix( 0, 100,100)
diag(mat) <- 1
mat[1:10,1:10]
#-----------
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    0    0    0    0    0    0    0     0
 [2,]    0    1    0    0    0    0    0    0    0     0
 [3,]    0    0    1    0    0    0    0    0    0     0
 [4,]    0    0    0    1    0    0    0    0    0     0
 [5,]    0    0    0    0    1    0    0    0    0     0
 [6,]    0    0    0    0    0    1    0    0    0     0
 [7,]    0    0    0    0    0    0    1    0    0     0
 [8,]    0    0    0    0    0    0    0    1    0     0
 [9,]    0    0    0    0    0    0    0    0    1     0
[10,]    0    0    0    0    0    0    0    0    0     1

Однако вы хотите, чтобы субдиагональные и супердиагональные были назначенными значениями, поэтомуиспользуйте логические выражения с col и row:

mat <- matrix( 0, 100,100)
mat[row(mat)==col(mat)-1] <- 1 
mat[row(mat)==col(mat)+1] <- 1
mat[1:10,1:10]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    1    0    0    0    0    0    0    0     0
 [2,]    1    0    1    0    0    0    0    0    0     0
 [3,]    0    1    0    1    0    0    0    0    0     0
 [4,]    0    0    1    0    1    0    0    0    0     0
 [5,]    0    0    0    1    0    1    0    0    0     0
 [6,]    0    0    0    0    1    0    1    0    0     0
 [7,]    0    0    0    0    0    1    0    1    0     0
 [8,]    0    0    0    0    0    0    1    0    1     0
 [9,]    0    0    0    0    0    0    0    1    0     1
[10,]    0    0    0    0    0    0    0    0    1     0

(Этот метод не зависит от наличия квадратной матрицы. У меня есть неопределенная память, что есть более быстрый метод, который не требует использования row и col. Для очень больших объектов каждая из этих функций возвращает матрицу тех же размеров, что и их аргументы.)

0 голосов
/ 04 февраля 2019

Мы могли бы создать функцию, используя математический трюк, который работал бы для всей квадратной матрицы.

get_off_diagonal_1s <- function(n) {
  #Create a matrix with all 0's
  mat <- matrix(0, ncol = n, nrow = n)
  #Subtract row indices by column indices
  inds = row(mat) - col(mat)
  #Replace values where inds is 1 or -1
  mat[inds == 1 | inds == -1] = 1
  mat
}

get_off_diagonal_1s(5)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    1    0    0    0
#[2,]    1    0    1    0    0
#[3,]    0    1    0    1    0
#[4,]    0    0    1    0    1
#[5,]    0    0    0    1    0

get_off_diagonal_1s(8)
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#[1,]    0    1    0    0    0    0    0    0
#[2,]    1    0    1    0    0    0    0    0
#[3,]    0    1    0    1    0    0    0    0
#[4,]    0    0    1    0    1    0    0    0
#[5,]    0    0    0    1    0    1    0    0
#[6,]    0    0    0    0    1    0    1    0
#[7,]    0    0    0    0    0    1    0    1
#[8,]    0    0    0    0    0    0    1    0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...