Создать трехугольную матрицу
Мне нужно запрограммировать R с матрицей, которая имеет (1+x^2) вниз по ведущей диагонали (постоянное значение x дано ранее в программе) и x вниз по диагонали по обе стороны от ведущей диагонали, и 0 везде остальное. Надеюсь это имеет смысл! Может кто-нибудь сказать мне, как я запрограммирую это, я могу только найти, как вводить значения на первой диагонали, а не любые другие диагонали. Это матрица 71x71, поэтому я не могу ввести ее вручную!
3 ответа
скаляр
Если x
это скаляр и n
является общим измерением строки и столбца:
# test inputs
x <- 10
n <- 5
m <- diag(1+x^2, n)
m[abs(row(m) - col(m)) == 1] <- x
давая:
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 101 10 0 0 0
[2,] 10 101 10 0 0
[3,] 0 10 101 10 0
[4,] 0 0 10 101 10
[5,] 0 0 0 10 101
Вектор
Если x
является вектором, так как субдиагональ и супердиагональ на один элемент короче диагонали, мы должны указать их отдельно - здесь последние два определены как y
,
# test values for diagonal and sub/super diagonals
x <- 1:5
y <- 11:14
m <- diag(x)
m[row(m) - col(m) == 1] <- m[row(m) - col(m) == -1] <- y
давая:
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 11 0 0 0
[2,] 11 2 12 0 0
[3,] 0 12 3 13 0
[4,] 0 0 13 4 14
[5,] 0 0 0 14 5
Заметка
Обратите внимание, что такая матрица называется трехдиагональной матрицей, и поиск трехдиагональной R приведет к появлению некоторых соответствующих ссылок.
Я хотел бы создать матрицу разреженной полосы:
# test inputs
x <- 10
n <- 5
library(Matrix)
M <- bandSparse(n, n, #dimensions
(-1):1, #band, diagonal is number 0
list(rep(x, n-1),
rep(1+x^2, n),
rep(x, n-1)))
#5 x 5 sparse Matrix of class "dgCMatrix"
#
#[1,] 101 10 . . .
#[2,] 10 101 10 . .
#[3,] . 10 101 10 .
#[4,] . . 10 101 10
#[5,] . . . 10 101
При необходимости его можно легко привести к плотной матрице:
as.matrix(M)
# [,1] [,2] [,3] [,4] [,5]
#[1,] 101 10 0 0 0
#[2,] 10 101 10 0 0
#[3,] 0 10 101 10 0
#[4,] 0 0 10 101 10
#[5,] 0 0 0 10 101
diagonals
пакет может приблизить вас (но не полностью) с fatdiag
функция. Вот пример того, как создать матрицу 12x12 и заполнить область вокруг диагонали значением:
> library(diagonals)
> m <- matrix(0, nrow=12, ncol=12)
> fatdiag(m, steps=3) <- 999
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 999 999 999 999 0 0 0 0 0 0 0 0
[2,] 999 999 999 999 0 0 0 0 0 0 0 0
[3,] 999 999 999 999 0 0 0 0 0 0 0 0
[4,] 999 999 999 999 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 999 999 999 999 0 0 0 0
[6,] 0 0 0 0 999 999 999 999 0 0 0 0
[7,] 0 0 0 0 999 999 999 999 0 0 0 0
[8,] 0 0 0 0 999 999 999 999 0 0 0 0
[9,] 0 0 0 0 0 0 0 0 999 999 999 999
[10,] 0 0 0 0 0 0 0 0 999 999 999 999
[11,] 0 0 0 0 0 0 0 0 999 999 999 999
[12,] 0 0 0 0 0 0 0 0 999 999 999 999
Вы также можете указать size
, что может быть более полезным для вас... это заполнит столько ячеек по диагонали:
> m <- matrix(0, nrow=12, ncol=12)
> fatdiag(m, size=2) <- 999
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 999 999 0 0 0 0 0 0 0 0 0 0
[2,] 999 999 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 999 999 0 0 0 0 0 0 0 0
[4,] 0 0 999 999 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 999 999 0 0 0 0 0 0
[6,] 0 0 0 0 999 999 0 0 0 0 0 0
[7,] 0 0 0 0 0 0 999 999 0 0 0 0
[8,] 0 0 0 0 0 0 999 999 0 0 0 0
[9,] 0 0 0 0 0 0 0 0 999 999 0 0
[10,] 0 0 0 0 0 0 0 0 999 999 0 0
[11,] 0 0 0 0 0 0 0 0 0 0 999 999
[12,] 0 0 0 0 0 0 0 0 0 0 999 999
Когда это будет сделано, вы сможете использовать методы, которые вы используете, чтобы заполнить диагональ желаемым значением. (Так как 71 не делится на что-либо, вам, возможно, придется создать 72x72, а затем отрубить концы.) Не зная контекста вашей проблемы, трудно оценить, насколько приемлема глупость:)