创建三对角矩阵

时间:2018-03-28 13:51:47

标签: r matrix diagonal

我需要用一个矩阵编程R,该矩阵在前导对角线上有(1 + x ^ 2)(x的常数值在程序的前面给出),x在前导对角线两侧的对角线上,其他地方都是0。我希望这是有道理的!任何人都可以告诉我如何编程,我只能找到如何在前导对角线上输入值而不是任何其他对角线。这是一个71x71矩阵,所以我无法手动输入!

3 个答案:

答案 0 :(得分: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 tridiagonal 会出现一些相关的链接。

答案 1 :(得分:1)

我会创建一个稀疏带矩阵:

# 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

答案 2 :(得分:-1)

使用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,然后砍掉两端。)在不知道问题背景的情况下,很难评估可以接受多少kludginess:)