Geometry 利用距离矩阵求点集坐标点

Geometry 利用距离矩阵求点集坐标点,geometry,Geometry,给定一个距离矩阵和一组点,如何计算这些点的坐标 编辑:这是在一个平面上 这个问题得到了回答,但在尝试不同的距离矩阵时,我真的不能使用这个答案,因为M矩阵有负值,我的特征向量也是。因此,当您取平方根时,程序(在R中)为那些相关条目输出“NaN”。 我猜每次D(I,j)^2大于D(1,j)^2+D(I,1)^2时都会发生这种情况 例如,假设我有一个距离矩阵: 0 73 102 496 432 184 73 0 303 392 436 233 102 303 0

给定一个距离矩阵和一组点,如何计算这些点的坐标

编辑:这是在一个平面上

这个问题得到了回答,但在尝试不同的距离矩阵时,我真的不能使用这个答案,因为M矩阵有负值,我的特征向量也是。因此,当您取平方根时,程序(在R中)为那些相关条目输出“NaN”。 我猜每次D(I,j)^2大于D(1,j)^2+D(I,1)^2时都会发生这种情况

例如,假设我有一个距离矩阵:

0    73   102  496  432  184
73    0   303  392  436  233
102  303    0  366  207  353
496  392  366    0  172  103
432  436  207  172    0  352
184  233  353  103  352    0
使用方程M(i,j)=(0.5)(D(1,j)^2+D(i,1)^2-D(i,j)^2),我得到(已经有负项):

然后我得到非零特征值和特征向量:

477718.27  101845.63   16474.30  -13116.72 -100692.49


        [,1]       [,2]        [,3]        [,4]        [,5]
 0.00000000  0.0000000  0.00000000  0.00000000  0.00000000
-0.05928626  0.3205747  0.84148945  0.04869546 -0.42806691
-0.16650486 -0.5670946 -0.04507520 -0.58222690 -0.55647098
-0.73371713  0.2827320  0.07386302 -0.45957443  0.40627254
-0.59727407 -0.4623603  0.07806418  0.64968004 -0.03617241
-0.27144823  0.5309625 -0.52755471  0.15920983 -0.58372335
由于存在负特征值和特征向量,当我们计算 sqrt(特征向量(i)*特征值(i)),我们会有负值。 以下是我的最终输出:

[,1]     [,2]      [,3]     [,4]      [,5]
   0   0.0000   0.00000  0.00000   0.00000
 NaN 180.6907 117.74103      NaN 207.61291
 NaN      NaN       NaN 87.38939 236.71174
 NaN 169.6910  34.88326 77.64089       NaN
 NaN      NaN  35.86158      NaN  60.35139
 NaN 232.5429       NaN      NaN 242.43877
这是计算坐标点而不使用角度的唯一清晰方法吗? 如果是,我们是否必须固定距离矩阵,使D(i,j)^2不大于D(1,j)^2+D(i,1)^2

谢谢

你的数据不一致 您的坐标与中的点位置不一致ℝ⁴, 更不用说低维空间了。通过计算平方距离矩阵的门格尔行列式,可以看出这一事实:

D <- as.matrix(read.table(textConnection("\
0    73   102  496  432  184
73    0   303  392  436  233
102  303    0  366  207  353
496  392  366    0  172  103
432  436  207  172    0  352
184  233  353  103  352    0")))
n <- nrow(D)
det(rbind(cbind(D^2, 1), c(rep(1, n), 0)))
# Result: 3.38761e+25
直接从a到c所花费的时间永远不会比通过b所花费的时间更长,但根据你的数据,它确实如此

简单平面法 如果数据与平面中的点一致(即,四个点组合的所有Menger行列式计算为零),则可以使用以下方法获得坐标:

distance2coordinates <- function(D) {
  n <- nrow(D)
  maxDist <- which.max(D)
  p1 <- ((maxDist - 1) %% n) + 1
  p2 <- ((maxDist - 1) %/% n) + 1
  x2 <- D[p1, p2]
  r1sq <- D[p1,]^2
  r2sq <- D[p2,]^2
  x <- (r1sq - r2sq + x2^2)/(2*x2)
  y <- sqrt(r1sq - x^2)
  p3 <- which.max(y)
  x3 <- x[p3]
  y3 <- y[p3]
  plus <- abs(D[p3,]^2 - (x3 - x)^2 - (y3 - y)^2)
  minus <- abs(D[p3,]^2 - (x3 - x)^2 - (y3 + y)^2)
  y[minus < plus] <- -y[minus < plus]
  coords <- data.frame(x = x, y = y)
  return(coords)
}
给定这些x坐标,您也可以获得y坐标,直至符号。然后选择第三个点,距离这两个起点中的任何一个都足够远,以确定标志

这种方法根本不试图处理不精确的输入。它假定数据准确,并且只使用部分距离矩阵来查找点。它不会找到与所有输入数据最匹配的点集

在您的数据上,这将失败,因为平方根的一些参数将是负数。这意味着所涉及的两个圆根本不相交,因此违反了三角形不等式

如果是,我们是否必须固定距离矩阵,使D(i,j)^2不大于D(1,j)^2+D(i,1)^2

D(i,j)≤ D(i,k)+D(k,j)会有帮助,即对于所有三元组和不带正方形的组。这将确保三角不平等无处不在。结果仍然不需要是平面的;为此,您必须修正所有门格尔行列式。

您的数据不一致 您的坐标与中的点位置不一致ℝ⁴, 更不用说低维空间了。通过计算平方距离矩阵的门格尔行列式,可以看出这一事实:

D <- as.matrix(read.table(textConnection("\
0    73   102  496  432  184
73    0   303  392  436  233
102  303    0  366  207  353
496  392  366    0  172  103
432  436  207  172    0  352
184  233  353  103  352    0")))
n <- nrow(D)
det(rbind(cbind(D^2, 1), c(rep(1, n), 0)))
# Result: 3.38761e+25
直接从a到c所花费的时间永远不会比通过b所花费的时间更长,但根据你的数据,它确实如此

简单平面法 如果数据与平面中的点一致(即,四个点组合的所有Menger行列式计算为零),则可以使用以下方法获得坐标:

distance2coordinates <- function(D) {
  n <- nrow(D)
  maxDist <- which.max(D)
  p1 <- ((maxDist - 1) %% n) + 1
  p2 <- ((maxDist - 1) %/% n) + 1
  x2 <- D[p1, p2]
  r1sq <- D[p1,]^2
  r2sq <- D[p2,]^2
  x <- (r1sq - r2sq + x2^2)/(2*x2)
  y <- sqrt(r1sq - x^2)
  p3 <- which.max(y)
  x3 <- x[p3]
  y3 <- y[p3]
  plus <- abs(D[p3,]^2 - (x3 - x)^2 - (y3 - y)^2)
  minus <- abs(D[p3,]^2 - (x3 - x)^2 - (y3 + y)^2)
  y[minus < plus] <- -y[minus < plus]
  coords <- data.frame(x = x, y = y)
  return(coords)
}
给定这些x坐标,您也可以获得y坐标,直至符号。然后选择第三个点,距离这两个起点中的任何一个都足够远,以确定标志

这种方法根本不试图处理不精确的输入。它假定数据准确,并且只使用部分距离矩阵来查找点。它不会找到与所有输入数据最匹配的点集

在您的数据上,这将失败,因为平方根的一些参数将是负数。这意味着所涉及的两个圆根本不相交,因此违反了三角形不等式

如果是,我们是否必须固定距离矩阵,使D(i,j)^2不大于D(1,j)^2+D(i,1)^2


D(i,j)≤ D(i,k)+D(k,j)会有帮助,即对于所有三元组和不带正方形的组。这将确保三角不平等无处不在。结果仍然不需要是平面的;为此,你必须修正所有的门格尔行列式。

这是可解的

如果您想查看满足您在问题中提供的距离矩阵的笛卡尔类型坐标,请查看下图。
您的输入矩阵给出了6个节点之间的距离,我们称之为a、b、c、d、e和f。总共需要5个维度才能为满足距离矩阵的所有六个节点分配坐标。其中两个维度是虚值——这是打破三角形规则的结果。结果是利用余弦定律和一些数字运算得出的

  • a(0,0,0,0,0)
  • b(73,0,0,0,0)
  • c(-521.07,510.99i,0,0,0)
  • d(669.05,-802.08i,664.62,0,0)
  • e(12.72,-163.83i,488.13158.01i,0)
  • f(-103.45184.11i,84.52138.06i,262.62)

  • 这是可以解决的

    如果您想查看满足您在问题中提供的距离矩阵的笛卡尔类型坐标,请查看下图。
    您的输入矩阵给出了6个节点之间的距离,我们称之为a、b、c、d、e和f。总共需要5个维度才能为满足距离矩阵的所有六个节点分配坐标。其中两个维度是虚值——这是打破三角形规则的结果。结果是利用余弦定律和一些数字运算得出的

    • a(0,0,0,0,0)
    • b(73,0,0,0,0)
    • c(-521.07,510.99i,0,0,0)
    • d(669.05,-802.08i,664.62,0,0)
    • e(12.72,-163.83i,488.13158.01i,0)
    • f(-103.4)
      I:     x²       + y² = r₁²
      II:   (x - x₂)² + y² = r₂²
      I-II:  2*x*x₂ = r₁² - r₂² + x₂²
      
      import sympy
      import numpy as np
      def give_coords(distances):
          """give coordinates of points for which distances given
      
          coordinates are given relatively. 1st point on origin, 2nd on x-axis, 3rd 
          x-y plane and so on. Maximum n-1 dimentions for which n is the number
          of points
      
           Args:
              distanes (list): is a n x n, 2d array where distances[i][j] gives the distance 
                  from i to j assumed distances[i][j] == distances[j][i]
      
           Returns:
              numpy.ndarray: cordinates in list form n dim
      
           Examples:
              >>> a = sympy.sqrt(2)
              >>> distances = [[0,1,1,1,1,1],
                               [1,0,a,a,a,a],
                               [1,a,0,a,a,a],
                               [1,a,a,0,a,a],
                               [1,a,a,a,0,a],
                               [1,a,a,a,a,0]]
              >>> give_coords(distances)
              array([[0, 0, 0, 0, 0],
                     [1, 0, 0, 0, 0],
                     [0, 1, 0, 0, 0],
                     [0, 0, 1, 0, 0],
                     [0, 0, 0, 1, 0],
                     [0, 0, 0, 0, 1]], dtype=object)
      
              >>> give_coords([[0, 3, 4], [3, 0, 5], [4, 5, 0]])
              array([[0, 0],
              [3, 0],
              [0, 4]], dtype=object)        
      
          """
          distances = np.array(distances)
      
          n = len(distances)
          X = sympy.symarray('x', (n, n - 1))
      
          for row in range(n):
              X[row, row:] = [0] * (n - 1 - row)
      
          for point2 in range(1, n):
      
              expressions = []
      
              for point1 in range(point2):
                  expression = np.sum((X[point1] - X[point2]) ** 2) 
                  expression -= distances[point1,point2] ** 2
                  expressions.append(expression)
      
              X[point2,:point2] = sympy.solve(expressions, list(X[point2,:point2]))[1]
      
          return X