我正在使用rdist
计算矩阵与其自身之间的欧几里德距离:
> m = matrix(c(1,1,1,2,2,2,3,4,3),nrow=3, ncol=3)
> m
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 4
[3,] 1 2 3
library(fields)
> rdist(m)
[,1] [,2] [,3]
[1,] 1e-10 1e+00 1e-10
[2,] 1e+00 1e-10 1e+00
[3,] 1e-10 1e+00 1e-10
让我感到困惑的是,我认为对角线上应该有0(当然向量与自身的距离是0?),出于同样的原因,它应该有0比较第一和第三行。我看到的值(1e-10)看起来很大,是数值噪声。出了什么问题?
编辑:rdist
来自包fields
。
答案 0 :(得分:4)
首先1e-10
只是1*10^-10
0.0000000001
,因此数字非常接近0
(因为它是平方根的结果,所以实际的错误在计算中是一行幅度1e-20
)。它“太大了”吗?好吧,库是用fortran编写的,专注于速度,因此它是完全可以接受的。如果您分析确切的代码,您将了解它是如何计算的:
# fields, Tools for spatial data
# Copyright 2004-2011, Institute for Mathematics Applied Geosciences
# University Corporation for Atmospheric Research
# Licensed under the GPL -- www.gpl.org/licenses/gpl.html
"rdist" <- function(x1, x2) {
if (!is.matrix(x1))
x1 <- as.matrix(x1)
if (missing(x2))
x2 <- x1
if (!is.matrix(x2))
x2 <- as.matrix(x2)
d <- ncol(x1)
n1 <- nrow(x1)
n2 <- nrow(x2)
par <- c(1/2, 0)
temp <- .Fortran("radbas", nd = as.integer(d), x1 = as.double(x1),
n1 = as.integer(n1), x2 = as.double(x2), n2 = as.integer(n2),
par = as.double(par), k = as.double(rep(0, n1 * n2)))$k
return(matrix(temp, ncol = n2, nrow = n1))
}
确切的答案隐藏在fortran文件中(在radfun.f
中调用radbas.f
),在那里你可以找到该行
if( dtemp.lt.1e-20) dtemp =1e-20
将小(偶数0)值视为1e-20
,在将1e-10
作为平方根后得出。似乎动机是通过使用值的对数来加速过程(因此,平方根只是除以2),当然没有为0
定义。