你如何创建一个函数来输入两个向量来产生一个矩阵

Posted

技术标签:

【中文标题】你如何创建一个函数来输入两个向量来产生一个矩阵【英文标题】:How do you create a function to input two vectors to produce a matrix 【发布时间】:2022-01-05 02:45:05 【问题描述】:

假设我有 5 对向量形式的坐标 (x1,y1)(region1) , (x2,y2)(region2) 等等,直到 (x5,y5)(region5)。 现在我想找到每个区域之间的距离。例如,我采取 距离,D = √[(????i−????????)^2+(????????−????????)^2] 区域 i和 j 并且输出将是一个 5 x 5 矩阵,其中矩阵 (Dij) 中的每个条目是两个区域之间的距离。

例如,我有区域 1,其坐标为 (4,3),区域 2 (1,2)。那么这两个区域之间的距离应该是 D = √10,这应该在 Dij 的条目中,其中 i =1 和 j=2,因此 D12 如上述矩阵所示。 我尝试了如下所示的代码:

x=c(1,2,4,1,1)
y=c(4,3,1,2,2)
Distance = function(x,y)
D = sqrt(abs((x[i]-x[j])^2+(y[i]-y[j])^2))
A = matrix(0,nrow=5,ncol=5,T)
i = nrow(A)
j = ncol(A)
for (i in 1:5)
for (j in 1:5)
A[i][j] = D


return(A) 
 

输出:

Warning messages:
 1: In A[i] <- `*vtmp*` :
 number of items to replace is not a multiple of replacement length

其中有 20 条警告消息。叹。我知道我的代码远非正确。请帮忙

【问题讨论】:

我不会在评论中正确解决您的函数问题,这足以说明计算应该发生在双循环内并且A 的索引不正确。 R 有一个内置的距离函数,所以我认为你只是在寻找 dist(cbind(x, y), diag = TRUE, upper = TRUE) 您可以接受解决问题的答案,也可以发布自己的答案,而不是在标题中标记 好吧,我没注意到。从现在开始会记住这一点。我对堆栈溢出很陌生。谢谢友情提醒。干杯 【参考方案1】:

代码存在以下问题。

定义 D 的行使用 i 和 j,即使它们当时尚未定义 定义 D 的行使用 abs(...) 但 (...) 中的部分永远不会是负数,因此使用 abs 毫无意义 如果 x[i], y[i] 是第 i 个点,那么 x 和 y 的长度必须相同,所以我们应该检查一下。 定义 A 硬编码 5 的行,因此该函数只有在 x 和 y 的长度为 5 时才能工作。 matrix 的第四个参数是 T。切勿使用 T 来表示 TRUE。总是把它写出来,因为 T 是一个可能的变量,但 TRUE 永远不可能是一个变量名。 在定义矩阵时指定 byrow = TRUE 是没有意义的,因为每个元素都被赋予相同的值,因此顺序无关紧要。事实上,我们根本不需要填写 A,因为循环稍后会这样做。 i 和 j 定义为 nrow(A) 和 ncol(A);但是,在此之后它们被重新定义,因此原始定义被丢弃并且从未使用过。这些行无效。 这两个循环将上限硬编码为 5,因此,同样,该函数仅在 x 和 y 的长度均为 5 时才有效。 A[i][j] 应该是 A[i, j] D 在循环中使用,但在循环外定义,因此 A[i,j] 的每个元素都将被赋予相同的值 代码没有缩进,难以阅读 在代码中添加更多空格会更容易阅读 虽然写 return(A) 并没有错,只写 A 就足以返回它 问题是指输出,但没有输出,因为代码从不运行函数

代码--

Distance = function(x, y) 
  stopifnot(length(x) == length(y))
  n = length(x)
  A = matrix(nrow = n, ncol = n)
  for (i in 1:n) 
    for (j in 1:n) 
      A[i, j] = sqrt( (x[i] - x[j])^2 + (y[i] - y[j])^2 )
    
  
  A
 

# test
x = c(1, 2, 4, 1, 1)
y = c(4, 3, 1, 2, 2)
Distance(x, y)
##        [,1]   [,2]   [,3]   [,4]   [,5]
## [1,] 0.0000 1.4142 4.2426 2.0000 2.0000
## [2,] 1.4142 0.0000 2.8284 1.4142 1.4142
## [3,] 4.2426 2.8284 0.0000 3.1623 3.1623
## [4,] 2.0000 1.4142 3.1623 0.0000 0.0000
## [5,] 2.0000 1.4142 3.1623 0.0000 0.0000

请注意,这可以使用外部更紧凑地完成。

d <- function(i, j) sqrt((x[i] - x[j])^2 + (y[i] - y[j])^2)
n <- length(x)
outer(1:n, 1:n, Vectorize(d))
##        [,1]   [,2]   [,3]   [,4]   [,5]
## [1,] 0.0000 1.4142 4.2426 2.0000 2.0000
## [2,] 1.4142 0.0000 2.8284 1.4142 1.4142
## [3,] 4.2426 2.8284 0.0000 3.1623 3.1623
## [4,] 2.0000 1.4142 3.1623 0.0000 0.0000
## [5,] 2.0000 1.4142 3.1623 0.0000 0.0000

【讨论】:

哇,老实说,我真的很感激你花时间指出我的错误!感谢您的帮助,但我想提一下,如果在函数中间使用 dist(cbind(x, y), diag = TRUE, upper = TRUE) 是否应该让事情变得更快? 好主意。 as.matrix(dist(cbind(x, y))) 给出了与 Distance(x, y) 相同的答案,因为它给出了一个矩阵,而 dist(cbind(x, y), diag = TRUE, upper = TRUE) 返回一个类 "dist" 的对象。

以上是关于你如何创建一个函数来输入两个向量来产生一个矩阵的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Matlab 中对两个向量应用二元函数以获得所有成对结果的矩阵?

在 C++ 中使用二维向量乘以矩阵

matlab中如何交换矩阵的行或者列

在matlab中如何将一个矩阵的一行或一列取出来,还是一个矩阵?

如何编写向量函数来应用操作 f(x,y)?

glm lookAt 和矩阵变换产生奇怪的行为