7

我想在给定相关向量的情况下创建一个相关矩阵,它是相关矩阵的上(或下)三角矩阵。

目标是转换这个向量

在此处输入图像描述

到这个对角线上为 1 的相关矩阵。

在此处输入图像描述

您知道是否有一种方法可以在给定对角线上方的三角形的情况下创建矩阵并将对角线设置为 1?

4

4 回答 4

8

您可以让 R 相信您的向量是一个距离对象,然后使用as.matrix它来转换它:

> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> class(myvec) <- 'dist'
> attr(myvec,'Size') <- 4
> as.matrix(myvec)
      1     2     3     4
1  0.00 -0.55 -0.48  0.66
2 -0.55  0.00  0.47 -0.38
3 -0.48  0.47  0.00 -0.46
4  0.66 -0.38 -0.46  0.00

或者@AnandaMahto 的答案的变体(类似于上面使用的内部结构):

> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> mycor <- matrix(0,4,4)
> mycor[ col(mycor) < row(mycor) ] <- myvec
> mycor <- mycor + t(mycor)
> diag(mycor) <- 1
> mycor
      [,1]  [,2]  [,3]  [,4]
[1,]  1.00 -0.55 -0.48  0.66
[2,] -0.55  1.00  0.47 -0.38
[3,] -0.48  0.47  1.00 -0.46
[4,]  0.66 -0.38 -0.46  1.00
于 2013-09-03T19:12:33.817 回答
7

我不知道是否有自动的方法来做到这一点,但扩展我的评论:

myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
mempty <- matrix(0, nrow = 4, ncol = 4)
mindex <- matrix(1:16, nrow = 4, ncol = 4)
mempty[mindex[upper.tri(mindex)]] <- myvec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
diag(mempty) <- 1
mempty
#       [,1]  [,2]  [,3]  [,4]
# [1,]  1.00 -0.55 -0.48  0.47
# [2,] -0.55  1.00  0.66 -0.38
# [3,] -0.48  0.66  1.00 -0.46
# [4,]  0.47 -0.38 -0.46  1.00

这是一个快速破解的功能。我希望我所有的数学步骤都是正确的!

vec2symmat <- function(invec, diag = 1, byrow = TRUE) {
  Nrow <- ceiling(sqrt(2*length(invec)))

  if (!sqrt(length(invec)*2 + Nrow) %% 1 == 0) {
    stop("invec is wrong length to create a square symmetrical matrix")
  }

  mempty <- matrix(0, nrow = Nrow, ncol = Nrow)
  mindex <- matrix(sequence(Nrow^2), nrow = Nrow, ncol = Nrow, byrow = byrow)
  if (isTRUE(byrow)) {
    mempty[mindex[lower.tri(mindex)]] <- invec
    mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
  } else {
    mempty[mindex[upper.tri(mindex)]] <- invec
    mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
  }

  diag(mempty) <- diag
  mempty
}

这是对角线的不同值。

vec2symmat(1:3, diag = NA)
#      [,1] [,2] [,3]
# [1,]   NA    1    2
# [2,]    1   NA    3
# [3,]    2    3   NA

如果您尝试提供无法创建方阵的数据,则会出现错误消息。

vec2symmat(1:4)
# Error in vec2symmat(1:4) : 
#   invec is wrong length to create a square symmetrical matrix

并且,使用默认设置。

vec2symmat(1:10)
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    1    2    3    4
# [2,]    1    1    5    6    7
# [3,]    2    5    1    8    9
# [4,]    3    6    8    1   10
# [5,]    4    7    9   10    1
于 2013-09-03T18:17:12.050 回答
4

一些可能在其他问题中有用的辅助函数的答案:

`lower.tri<-` <- function(x,value){
    x[lower.tri(x)] <- value
    x
}

`upper.tri<-` <- function(x,value){
    y <- t(x)
    lower.tri(y) <- value
    t(y)
}

vec2mat <- function(r){
    n <- (1+sqrt(1+8*length(r)))/2
    x <- diag(1,n)
    lower.tri(x) <- upper.tri(x) <- r
    x
}

编辑:请注意,这upper.tri<-不是简单地通过在 lower.tri<-. 这会使结果不对称。

结果:

vec2mat(c(-0.55, -0.48, 0.66, 0.47, -0.38, -0.46))

      [,1]  [,2]  [,3]  [,4]
[1,]  1.00 -0.55 -0.48  0.66
[2,] -0.55  1.00  0.47 -0.38
[3,] -0.48  0.47  1.00 -0.46
[4,]  0.66 -0.38 -0.46  1.00
于 2013-09-04T00:02:07.850 回答
0

在任何编程语言中,我认为您只需使用几个嵌套的 for 循环,如下所示:

鉴于:

向量 R;// 我将使用圆括号 R(3) 来表示基于第 3 个元素。// (以零基数组的语言存储在内存位置 R[2] 中) int N;

矩阵 M=矩阵(N,N);// 你的矩阵对象的一个​​新实例,或者你可以只使用数组。

int i,j,k;

k=1;
for(i=1;i<N;i++)
{
   M(i,i)=1;
   for(j=i+1,j<=N;j++)
   { 
      M(i,j)=M(j,i)=R[k];
      k=k+1;
   }
}

在这里,我假设您知道 N 是什么,并且您拥有可用的向量和矩阵等基本对象。(如果不是,它们是编写你的第一个“对象”的一个很好的示例问题)复杂的数据结构,如向量、矩阵、复数和直方图,都是理想的对象。为科学工作考虑面向对象编程的正确方法是使用对象来教编译器理解您想要在实际工作中使用的高级数据类型......对象用于创建自定义编程语言非常适合您的工作类型。任何一般有用的东西都应该放在对象中,因为这些对象会成长并演变成您的可重用代码库。

然后,顶层代码可以是一个非常强大、易于阅读和清洁的应用程序(因为很多细节工作都在对象中完成)或者,对于快速和肮脏的编码,顶层代码是你放置所有代码的地方脆弱的黑客。因为它不是可重复使用的。

一旦你调试了这样的东西,你只需创建一个矩阵构造函数,它将相关向量和 N 作为参数,并为你初始化矩阵。

当然,如果您正在使用一些高级图形数学程序,该程序对矩阵和向量可以做什么和不能做什么有强烈的看法,那么您必须将向量乘以 N 个矩阵以生成每个列向量最后的矩阵。(或者阅读手册)

至少,你必须告诉我们数学程序叫什么...... :)

于 2013-09-03T18:43:56.203 回答