如何确定一系列点是否位于使用R的三维椭球中?

时间:2015-02-25 23:18:32

标签: r

我生成3组二项式数据,其中先验是多元正态分布,具有一些均值和方差,使用R中的以下代码。我需要确定p(p1,p2,p3)的真值是否属于由p(rate1,rate2,rate3)的估计产生的三维椭球空间。我为双变量做了类似的问题,我使用了point.in.polygon作为函数。三变量和四变量有类似的东西吗?我编辑了我的代码,我可以使用3组生成的数据绘制椭圆体。

library(MASS)

  set.seed(1234)

  m<-300

  x<-NULL

  k<-20

  Sigma2 <- matrix(c(.58,.49,.37,.49,.58,.38,.37,.38,.34),3,3)

  eta<-mvrnorm(k, mu=c(-0.85,-2.09,-1.90), Sigma2)

  p1<-exp(eta[,1])/(1+exp(eta[,1]))

  p2<-exp(eta[,2])/(1+exp(eta[,2]))

  p3<-exp(eta[,3])/(1+exp(eta[,3]))

  n<-60

  x1<-replicate(m,rbinom(k,n,p1))

  x2<-replicate(m,rbinom(k,n,p2))

  x3<-replicate(m,rbinom(k,n,p3))

  x<-cbind(x1,x2,x3)

  rate<-x/60

  x<-cbind(x1,x2,x3)

 sigma<-var(rate)

 origin<-c(mean(rate[,1]), mean(rate[,2]), mean(rate[,3]))

 #origin<-c(0.349,0.184,0.148)

  coords<-matrix(c(p1,p2,p3),nrow=3)

  A<-sigma

  cFromO<-coords-origin

  Ell<-apply(cFromO,2,function(c){t(c) %*% A %*% c})<=1

  Ell

  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE     TRUE TRUE TRUE TRUE TRUE TRUE TRUE

2 个答案:

答案 0 :(得分:3)

我相信这里解决了完全相同的问题:

Ellipsoid R function - finding if a point fits in - R script

对于更高维度,我认为给定M椭圆矩阵和点p的简单解决方案是检查ginv(M)%*%p的范数是否小于1。

答案 1 :(得分:3)

首先,如果要检查扁平椭圆,椭圆的公式很容易编写,并且可能更快,因为它可以应用于矢量:

使用格式良好的数学wikipaedia

查看原始答案

(x-h)²/(rx)²+(y -k)²/(ry)²=&lt; 1

用(x,y)表示点的坐标,(h,k)表示椭圆的原点,rx,ry是椭圆的半主轴。

任何维度的通用解决方案由wikipaedia

提供
  

(x-v)^ T A(x-v)=&lt; 1

其中x是定义坐标系中点的矢量。 v是定义原点的向量。 A仍在您的坐标系中,是定义椭圆半主轴的矢量坐标。

它很容易翻译成R:

    origin <- c(h=1,k=2,l=3)
    coords <- matrix(c(1,2,3,4,5,6),nrow=3)
    A <- matrix(c(0,1,1,1,0,1,1,1,0),nrow=3)
    cFromO <- coords-origin

你的答案简单地通过以下方式给出:

    apply(cFromO,2,function(c){t(c) %*% A %*% c})<=1

如果你想将它应用到多个点,你可以把它包装成一个函数,用roxygen格式很好地评论:

    #' @title Is point in an ellispoid?
    #' @description Returns if each point in a matrix of points is in the ellispoid defined by its origin and its matrix of semi-principal axes
    #' @param points A matrix of points with a coordinate per column
    #' @param origin The coordinates of the center of the ellipsoid
    #' @param A The square matrix defining the ellipsoid: one 
    #'       semi-principal axe per line (vectors)
    #' @return A vector of boolean indicating for each given point if it is in the ellispoid

    IsInEllipsoid <- function(points,origin,A){
        cFromO <- points-origin
        isIn <- (diag(cFromO %*% A %*% t(cFromO))<=1)
        return(isIn)
    }

Exemple d'utilization:

    # definition of points
    p1 <- c(1,2,3)
    p2 <- c(4,5,6)
    points <- rbind(p1,p2)

    # definition of the ellipsoid
    origin <- c(h=1,k=2,l=3)
    axe1 <- c(0,0,2)
    axe2 <- c(0,1,0)
    axe3 <- c(0.5,0,0)  
    A <- rbind(axe1,axe2,axe3)

    expect_equal(IsInEllipsoid(points,origin,A),c(p1=TRUE,p2=FALSE))

修改 然后,要定义多元法线的置信椭球,您希望使用方差/协方差矩阵的逆作为A,并使用卡方系数来指定置信水平,如here所述。虽然这不是问题的标题,但您可以在下文中找到R:

中的一个简单示例
    # just to make sure everybody get the same draws
    set.seed(1234)

    #-----------------
    # definition of a 95% enveloppe for a 3D multivariate normal
    #-----------------
    # the origin defining your multivariate normal
    origin <- c(0.5,0.5,0.5)

    # the variance covariance matrix defining your multivariate normal
    sigma <- matrix(c(.58,.49,.37,.49,.58,.38,.37,.38,.34),3,3)

    # the precision matrix needed in the calculus 
    sigmaInv <-solve(sigma)

    # the function defining the CV% enveloppe
    ArePointsInCVEllipsoid <- function(points,origin,sigmaInv,CV){
        nDegreeFreedom <- length(dim(sigmaInv)[1])
        cFromO <- points-origin
        areIn <- apply(cFromO,2,function(p){t(p) %*% sigmaInv %*% p <= qchisq(CV,nDegreeFreedom)})
        return(areIn)
    }
    #-----------------------
    # example of use
    #-----------------------
    k<-10000 # number of points to be drawn 

    # random draw in a cube
    toTest <- matrix(runif(k*3,min=-3,max=3),nrow=3)

    # plot the points fitting in the 0.75% confidence region
    library(scatterplot3d)
    toPlot <-t(toTest[,which(ArePointsInCVEllipsoid(toTest,origin,sigmaInv,0.95))])
    scatterplot3d(toPlot)