如何找到多边形的协方差矩阵?


9

假设您有一个由一组坐标(x1,y1)...(xn,yn)定义的多边形x ny n并且其质心在(0,0)。您可以将多边形视为具有多边形边界的均匀分布在此处输入图片说明

我正在寻找一种可以找到多边形的协方差矩阵的方法

我怀疑多边形的协方差矩阵与面积第二矩密切相关,但是我不确定它们是否相等。在我链接的Wikipedia文章中找到的公式似乎(这里是一个猜测,对我来说不是很清楚)指的是绕x,y和z轴而不是多边形的主轴的旋转惯量。

(顺便说一句,如果有人可以指出我如何计算多边形的主轴,那对我也很有用)

试图仅对坐标执行PCA是很诱人,但是这样做会遇到这样的问题,即坐标不一定在多边形周围均匀分布,因此不能代表多边形的密度。一个极端的例子是北达科他州的轮廓,其多边形由紧随红河的大量点定义,再加上仅两个定义该州西部边缘的点。


通过“查找”,我假设只是从多边形中采样,然后计算样本的协方差,这不是您要考虑的吗?
Stephan Kolassa,

另外,您可以编辑帖子以包含多边形的坐标,以便人们随心所欲吗?
Stephan Kolassa,

1
@StephanKolassa我的意思是将多边形视为具有多边形边界的统一双变量概率密度。当然,您可以采样点,并且限制将是一回事,但是我正在寻找一种先验方法。图片只是我使用的油漆的插图。我打算使用的真实世界数据是州和地区的轮廓。
Ingolifs

1
正确的是,“协方差矩阵”的常用术语是惯性矩第二矩。主轴沿其本征方向定向。在坐标上运行PCA是不正确的:这等于假设所有质量都位于顶点。我在gis.stackexchange.com/a/22744/664上的文章中讨论了重心计算的最直接方法- 第一刻。第二矩的计算方式相同,但稍有修改。在此领域需要特殊考虑。
ub

2
它以另一种方式起作用:计算惯性张量并从中找到其主轴。在您的情况下的技术涉及格林定理,这表明所需的积分可以被计算为围绕轮廓积分P一形式的ω,其中d ω = x k y l d x d y 这样的形式很容易找到,因为任何合适的线性组合
μk,l(P)=Pxkyldxdy
Pωdω=xkyldxdy. x k + 1 y l d y将起作用。轮廓积分是边缘上积分的总和。xkyl+1dxxk+1yldy
ub

Answers:


10

让我们先做一些分析。

假设在多边形P其概率密度为比例函数p(x,y). 则比例常数是p在多边形上的积分的倒数,

μ0,0(P)=Pp(x,y)dxdy.

多边形的重心是平均坐标的点,以其第一矩计算。第一个是

μ1,0(P)=1μ0,0(P)Pxp(x,y)dxdy.

惯性张量可表示为的平移所述多边形把它的重心在原点之后计算第二矩对称阵列:即,矩阵中央第二矩

μk,l(P)=1μ0,0(P)P(xμ1,0(P))k(yμ0,1(P))lp(x,y)dxdy

其中(k,l)范围内(2,0)(1,1)(0,2). 张量本身- 也就是协方差矩阵-是

I(P)=(μ2,0(P)μ1,1(P)μ1,1(P)μ0,2(P)).

的PCA I(P)产生的主轴P:这些是由它们的特征值缩放单元的特征向量。


接下来,让我们弄清楚如何进行计算。 因为多边形被呈现为描述其取向边界顶点的序列P,很自然地调用

格林定理:

Pdω=Pω
,其中ω=M(x,y)dx+N(x,y)dy是在的邻域定义的一个形式的P
dω=(xN(x,y)yM(x,y))dxdy.

例如,对于dω=xkyldxdy和恒定(,均匀的)密度p,我们可以(通过检查)选择了许多解决方案,诸如一个

ω(x,y)=1l+1xkyl+1dx.

这样做的目的是轮廓积分遵循由顶点序列确定的线段。顶点u到顶点v任何线段都可以由实变量t进行参数化,形式为

tu+tw

其中wvu是从uv.的单位法线方向因此,t范围是0|vu|. 根据这一参数xy是线性函数tdxdy是线性函数dt. 因此在每个边缘轮廓积分的积变为多项式函数t,很容易评估k ll.


实施此分析就像对其组件进行编码一样简单。在最低级别,我们将需要一个函数将一个线段上的多项式一形式积分。更高级别的函数将汇总这些矩以计算原始矩和中心矩,以获得重心和惯性张量,最后,我们可以在该张量上进行操作以找到主轴(即缩放后的特征向量)。R下面的代码执行此工作。它没有冒充效率:只是为了说明上述分析的实际应用。每个函数都很简单,命名约定与分析的命名约定相似。

该代码中包含一个生成有效的闭合,简单连接的,非自相交多边形的过程(通过沿圆弧随机变形点,并将起始顶点作为最终点,以创建一个闭合环)。接下来是一些用于绘制多边形,显示其顶点,邻接重心并以红色(最大)和蓝色(最小)绘制主轴的语句,以创建一个以多边形为中心的正向坐标系。

该图显示了多边形和主轴

#
# Integrate a monomial one-form x^k*y^l*dx along the line segment given as an 
# origin, unit direction vector, and distance.
#
lintegrate <- function(k, l, origin, normal, distance) {
  # Binomial theorem expansion of (u + tw)^k
  expand <- function(k, u, w) {
    i <- seq_len(k+1)-1
    u^i * w^rev(i) * choose(k,i)
  }
  # Construction of the product of two polynomials times a constant.
  omega <- normal[1] * convolve(rev(expand(k, origin[1], normal[1])), 
                                expand(l, origin[2], normal[2]),
                                type="open")
  # Integrate the resulting polynomial from 0 to `distance`.
  sum(omega * distance^seq_along(omega) / seq_along(omega))
}
#
# Integrate monomials along a piecewise linear path given as a sequence of
# (x,y) vertices.
#
cintegrate <- function(xy, k, l) {
  n <- dim(xy)[1]-1 # Number of edges
  sum(sapply(1:n, function(i) {
    dv <- xy[i+1,] - xy[i,]               # The direction vector
    lambda <- sum(dv * dv)
    if (isTRUE(all.equal(lambda, 0.0))) {
      0.0
    } else {
      lambda <- sqrt(lambda)              # Length of the direction vector
      -lintegrate(k, l+1, xy[i,], dv/lambda, lambda) / (l+1)
    }
  }))
}
#
# Compute moments of inertia.
#
inertia <- function(xy) {
  mass <- cintegrate(xy, 0, 0)
  barycenter = c(cintegrate(xy, 1, 0), cintegrate(xy, 0, 1)) / mass
  uv <- t(t(xy) - barycenter)   # Recenter the polygon to obtain central moments
  i <- matrix(0.0, 2, 2)
  i[1,1] <- cintegrate(uv, 2, 0)
  i[1,2] <- i[2,1] <- cintegrate(uv, 1, 1)
  i[2,2] <- cintegrate(uv, 0, 2)
  list(Mass=mass,
       Barycenter=barycenter,
       Inertia=i / mass)
}
#
# Find principal axes of an inertial tensor.
#
principal.axes <- function(i.xy) {
  obj <- eigen(i.xy)
  t(t(obj$vectors) * obj$values)
}
#
# Construct a polygon.
#
circle <- t(sapply(seq(0, 2*pi, length.out=11), function(a) c(cos(a), sin(a))))
set.seed(17)
radii <- (1 + rgamma(dim(circle)[1]-1, 3, 3))
radii <- c(radii, radii[1])  # Closes the loop
xy <- circle * radii
#
# Compute principal axes.
#
i.xy <- inertia(xy)
axes <- principal.axes(i.xy$Inertia)
sign <- sign(det(axes))
#
# Plot barycenter and principal axes.
#
plot(xy, bty="n", xaxt="n", yaxt="n", asp=1, xlab="x", ylab="y",
     main="A random polygon\nand its principal axes", cex.main=0.75)
polygon(xy, col="#e0e0e080")
arrows(rep(i.xy$Barycenter[1], 2), 
       rep(i.xy$Barycenter[2], 2),
       -axes[1,] + i.xy$Barycenter[1],     # The -signs make the first axis .. 
       -axes[2,]*sign + i.xy$Barycenter[2],# .. point to the right or down.
       length=0.1, angle=15, col=c("#e02020", "#4040c0"), lwd=2)
points(matrix(i.xy$Barycenter, 1, 2), pch=21, bg="#404040")

+1哇,这是一个很好的答案!
变形虫

7

编辑:没注意到胡夫已经回答了。我将以其他(也许不太优雅)的方法来举例说明这个问题。

协方差矩阵

(X,Y)为具有面积A的多边形P上均匀分布的随机点。协方差矩阵为:A

C=[CXXCXYCXYCYY]

CXX=E[X2]XCYY=E[Y2]YCXY=E[XY]XY1AP

(1)CXX=1APx2dVCYY=1APy2dVCXY=1APxydV

三角剖分

PPn

P=T1Tn

在您的示例中,一种可能的分区如下所示:

在此处输入图片说明

P

P

(2)CXX=1Ai=1nTix2dVCYY=1Ai=1nTiy2dVCXY=1Ai=1nTixydV

三角形具有很好的简单边界,因此更易于评估这些积分。

在三角形上积分

有多种方法可以对三角形进行积分。在这种情况下,我使用了一个技巧,涉及将三角形映射到单位正方形。转换为重心坐标可能是一个更好的选择。

T(x1,y1),(x2,y2),(x3,y3)

vx=[x1x2x3]vy=[y1y2y3]1=[111]L=[100110111]

然后:

(3)Tx2dV=A6Tr(vxvxTL)Ty2dV=A6Tr(vyvyTL)TxydV=A12(1TvxvyT1+vxTvy)

放在一起

vxivyiTi(3)(2)

(4)CXX=16i=1nTr(vxi(vxi)TL)CYY=16i=1nTr(vyi(vyi)TL)CXY=112i=1n(1Tvxi(vyi)T1+(vxi)Tvyi)

主轴

CCPC(4)


2
OOPiPi+1:PiPi+1.Quantdec.com/SYSEN597/GTKAV/section2/chapter_11.htm
ub

@whuber有趣,感谢您指出这一点
user20160

这两个答案都不错,尽管有点超出我的教育水平。一旦确定我完全了解他们,我将尝试找出谁得到了赏金。
Ingolifs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.