Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 把这个向量转换成对称矩阵的快速方法是什么?_R - Fatal编程技术网

R 把这个向量转换成对称矩阵的快速方法是什么?

R 把这个向量转换成对称矩阵的快速方法是什么?,r,R,各位!!假设我有一个长度为nn+1/2的向量: a = (a_11, a_12, a_22, ...., a_nn) 现在我想把它变成一个对称矩阵,意思是 我可以一个接一个地赋值,但我想知道是否有更快的方法来创建这个矩阵?非常感谢 a <- 1:25 sq.m <- matrix( a, ncol=sqrt(length(a) ) ) > sq.m [,1] [,2] [,3] [,4] [,5] [1,] 1 6 11 16 21 [2

各位!!假设我有一个长度为nn+1/2的向量:

a = (a_11, a_12, a_22, ...., a_nn) 
现在我想把它变成一个对称矩阵,意思是

我可以一个接一个地赋值,但我想知道是否有更快的方法来创建这个矩阵?非常感谢

a <- 1:25
sq.m <- matrix( a, ncol=sqrt(length(a) ) )

> sq.m
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
显然,这不是一个对称矩阵,但如果初始向量的阶数为1,那么它就成功了

如果要强制非方形矩阵,使其上三角元素与下三角元素相同,则可以在赋值的两侧进行索引:

 sq.m[ upper.tri(sq.m) ] <- sq.m[lower.tri(sq.m)]
> sq.m
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    5   10
[2,]    2    7    4    8   14
[3,]    3    8   13    9   15
[4,]    4    9   14   19   20
[5,]    5   10   15   20   25
显然,这不是一个对称矩阵,但如果初始向量的阶数为1,那么它就成功了

如果要强制非方形矩阵,使其上三角元素与下三角元素相同,则可以在赋值的两侧进行索引:

 sq.m[ upper.tri(sq.m) ] <- sq.m[lower.tri(sq.m)]
> sq.m
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    5   10
[2,]    2    7    4    8   14
[3,]    3    8   13    9   15
[4,]    4    9   14   19   20
[5,]    5   10   15   20   25
您可以尝试:

#define n
n <- 2

#Create n(n+1)/2 objects in global environment
#OP already has that
a_11 <- 5
a_12 <- 9
a_22 <- 8

#Create n X n matrix with NA
mat <- matrix(nrow = n, ncol = n)
#Get all the individual objects in one vector
vec <- unlist(mget(ls(pattern = 'a_')), use.names = FALSE)
#Replace upper (or lower) triangular elements with it
mat[upper.tri(mat, diag = TRUE)] <- vec
#Copy the elements to other half.
mat[lower.tri(mat)] <- mat[upper.tri(mat)]

#      [,1] [,2]
#[1,]    5    9
#[2,]    9    8
您可以尝试:

#define n
n <- 2

#Create n(n+1)/2 objects in global environment
#OP already has that
a_11 <- 5
a_12 <- 9
a_22 <- 8

#Create n X n matrix with NA
mat <- matrix(nrow = n, ncol = n)
#Get all the individual objects in one vector
vec <- unlist(mget(ls(pattern = 'a_')), use.names = FALSE)
#Replace upper (or lower) triangular elements with it
mat[upper.tri(mat, diag = TRUE)] <- vec
#Copy the elements to other half.
mat[lower.tri(mat)] <- mat[upper.tri(mat)]

#      [,1] [,2]
#[1,]    5    9
#[2,]    9    8

您可以编写一个函数来执行以下操作:

如果你的向量是a11,a12,a13..a1n,a22,a23..a2n,a33,…a3n,…ann 你可以这样做:

vec2mat <- function(x){
  p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
  m <- matrix(0, p, p)
  m[lower.tri(m, diag = TRUE)] <- x
  m[upper.tri(m)] <- (t(m))[upper.tri(m)]
  m
}
如果你有a11,a12,a22,a31,a32,a33


您可以编写一个函数来执行以下操作:

如果你的向量是a11,a12,a13..a1n,a22,a23..a2n,a33,…a3n,…ann 你可以这样做:

vec2mat <- function(x){
  p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
  m <- matrix(0, p, p)
  m[lower.tri(m, diag = TRUE)] <- x
  m[upper.tri(m)] <- (t(m))[upper.tri(m)]
  m
}
如果你有a11,a12,a22,a31,a32,a33


您可以创建如下稀疏矩阵:

a <- 1:6
n <- as.integer(-0.5 + sqrt(0.25 + 2 * length(a)))

library(Matrix)
sparseMatrix(x = a, dims = c(n, n), symmetric = TRUE, 
             i = sequence(1:n), j = rep(1:n, 1:n))
#3 x 3 sparse Matrix of class "dsCMatrix"
#          
#[1,] 1 2 4
#[2,] 2 3 5
#[3,] 4 5 6

如果需要密集矩阵,请在结果上使用as.matrix。如果向量的顺序不同于您显示的顺序,例如,如其他一些答案假设的行主键,则需要稍微调整i和j的计算。

您可以创建如下稀疏矩阵:

a <- 1:6
n <- as.integer(-0.5 + sqrt(0.25 + 2 * length(a)))

library(Matrix)
sparseMatrix(x = a, dims = c(n, n), symmetric = TRUE, 
             i = sequence(1:n), j = rep(1:n, 1:n))
#3 x 3 sparse Matrix of class "dsCMatrix"
#          
#[1,] 1 2 4
#[2,] 2 3 5
#[3,] 4 5 6

如果需要密集矩阵,请在结果上使用as.matrix。如果向量的顺序不同于您所显示的顺序,例如,如其他一些答案所假设的行主键,则需要稍微调整i和j的计算。

如果向量较大且速度很重要,则可以使用从使用Rfast包的@onyanbu获取的此函数

vec2mat_rfast <- function(x){
    p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
    m <- matrix(0, p, p)
    m[Rfast::upper_tri(m, diag = TRUE)] <- x
    m[Rfast::lower_tri(m)] <- Rfast::transpose(m)[Rfast::lower_tri(m)]
    m
}

vec2mat <- function(x){
    p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
    m <- matrix(0, p, p)
    m[upper.tri(m, diag = TRUE)] <- x
    m[lower.tri(m)] <- t(m)[lower.tri(m)]
    m
}

y=numeric(500500)


> microbenchmark::microbenchmark(a<-vec2mat(y),b<-vec2mat_rfast(y),times = 10)
Unit: milliseconds
                    expr     min       lq      mean    median       uq      max neval
         a <- vec2mat(y) 88.9461 101.5294 114.96752 108.86680 112.9854 180.9679    10
   b <- vec2mat_rfast(y) 33.1351  34.5294  49.61295  45.26955  62.8214  80.5069    10

> all.equal(a,b)
[1] TRUE

如果你有大的向量和速度问题,那么你可以使用这个来自@Onyambu的函数,它使用Rfast包

vec2mat_rfast <- function(x){
    p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
    m <- matrix(0, p, p)
    m[Rfast::upper_tri(m, diag = TRUE)] <- x
    m[Rfast::lower_tri(m)] <- Rfast::transpose(m)[Rfast::lower_tri(m)]
    m
}

vec2mat <- function(x){
    p <- sqrt(1 + 8 * length(x))/ 2 - 0.5
    m <- matrix(0, p, p)
    m[upper.tri(m, diag = TRUE)] <- x
    m[lower.tri(m)] <- t(m)[lower.tri(m)]
    m
}

y=numeric(500500)


> microbenchmark::microbenchmark(a<-vec2mat(y),b<-vec2mat_rfast(y),times = 10)
Unit: milliseconds
                    expr     min       lq      mean    median       uq      max neval
         a <- vec2mat(y) 88.9461 101.5294 114.96752 108.86680 112.9854 180.9679    10
   b <- vec2mat_rfast(y) 33.1351  34.5294  49.61295  45.26955  62.8214  80.5069    10

> all.equal(a,b)
[1] TRUE


提供一个实际向量和相应的预期输出,而不是索引,这将使回答更容易。是否应该将输入向量中的_12插入矩阵中的a_12和a_21?提供一个实际向量和相应的预期输出,而不是索引,这将使回答更容易答案。是不是应该将输入向量中的_12插入矩阵中的a_12和a_21?OP在输入向量中没有n^2个元素。我认为其目的是在对角线上复制某些元素,以创建一个。他的问题演示向我建议,他确实有n^2个元素。假设我有一个长度为nn+1/2的向量,那么你只有下三角元素?啊,现在我明白了。他只有对角线和上三角元素。没关系,这是一个对称矩阵。它可以是上三角形或下三角形。OP在输入向量中没有n^2个元素。我认为其目的是在对角线上复制某些元素,以创建一个。他的问题演示向我建议,他确实有n^2个元素。假设我有一个长度为nn+1/2的向量,那么你只有下三角元素?啊,现在我明白了。他只有对角线和上三角元素。没关系,这是一个对称矩阵。它可以是上三角形或下三角形。对于1000个元素,它会崩溃。。。为什么?@manospadakis因为你不能有1000个元素。请注意,该数字必须是三角形数字。即包括对角线的正方形矩阵的下三角形或上三角形。如果向量是44行44列的正方形,那么向量的长度应该是990;如果向量是45行45列的正方形,那么向量的长度应该是1035。非常感谢!对于1000个元素,它崩溃了。。。为什么?@manospadakis因为你不能有1000个元素。请注意,该数字必须是三角形数字。即包括对角线的正方形矩阵的下三角形或上三角形。如果向量是44行44列的正方形,那么向量的长度应该是990;如果向量是45行45列的正方形,那么向量的长度应该是1035。非常感谢!