【问题标题】:Check if point lies inside mulit-dimensional ellipsoid检查点是否位于多维椭球内
【发布时间】:2015-12-21 17:49:54
【问题描述】:

我无法确定某些点是否位于多维椭球内。 真正的问题是由潜在的转换(旋转、平移)引起的,我不知道如何将它们应用到我的计算中。

在我的工作中,我将有一组点,我需要为这些点找到包围椭圆体的最小体积。然后我将不得不检查其他点集并确定其中哪些属于找到的椭球体。

我决定使用来自here的代码:

function [] = Checkup()
points  = [[ 0.53135758, -0.25818091, -0.32382715] 
    [ 0.58368177, -0.3286576,  -0.23854156,] 
    [ 0.18741533,  0.03066228, -0.94294771] 
    [ 0.65685862, -0.09220681, -0.60347573]
    [ 0.63137604, -0.22978685, -0.27479238]
    [ 0.59683195, -0.15111101, -0.40536606]
    [ 0.68646128,  0.0046802,  -0.68407367]
    [ 0.62311759,  0.0101013,  -0.75863324]];
P = points\'; % <- remove the \ symbol here
dimen = length(P(:,1));

% c - vector with ellipse centers
[A, c] = MinVolEllipse(P, 0.01);
[~, Q, V] = svd(A);
radiuses = 1:dimen;

% Calculate radiuses
for i = 1:dimen
    radiuses(1, i) = 1 / sqrt(Q(i,i));
end

% Check if points lie within ellipse and print Ok for every point inside ellipsoid
for i = 1:length(P(1,:)) % length(P(1,:)) is number of points
    value = 0;
    for j = 1:dimen
        %adding ((p_i - c_i) / (r_i))^2 value
        value = value + ( ( (P(j,i) - c(j, 1) )^2 ) / (radiuses(1, j)^2));

    end
    if value <= 1
        disp('Ok')
    end
end

现在这段代码不能打印 Ok 文本(但它应该打印 8 次)。

根据this:“V 是旋转矩阵,为您提供椭圆体的方向” 我认为这是我的代码需要使用的最后一个元素。

我的方法

好的,所以我对我的代码进行了一些更改。 现在我尝试做这样的事情:

假设我有椭球的中心和它的半径。

对于每一点:

  1. 如下更新位置:点 = 点 - 中心 -> 换句话说,将其转换为椭圆体的中心在点 (0, 0, ... 0)

  2. 像椭球平行于所有轴一样旋转它:point = invert(V) * point

  3. 使用等式检查点是否位于椭圆体内:(point.x / radius.x)^2 + ... + (point.i / radius.i)^2 其中 i 是维数

  4. 如果方程给出的结果

这种方法好吗?我的意思是 - 我不知道是否允许我反转 V 矩阵并像它反转先前的旋转一样使用它......

适当的解决方案

看起来我提出的方法不错,但还有一种更好:

function [result] = Ellipse()
% Returns vector consisting of 10 entries
% that represent error ratio for every test set 

result = 0:9;

% Run tests for all point sets
for pointSet = 0:9
    [Ptraining, Ptest] = LoadPointSet(pointSet);
    count = 0;

    % c - vector with ellipse centers
    [A, c] = MinVolEllipse(Ptraining, 0.00001);

    % Check if points lie within ellipse
    for i = 1:length(Ptest(1,:)) % length(P(1,:)) is number of points
        pp = Ptest(:, i) - c;
        value = pp' * A * pp;    
        if value > 1
            count = count + 1;
        end
    end

    % Get the error ratio
    index = pointSet + 1;
    result(index) = count / length(Ptest(1,:));
end

end

【问题讨论】:

  • 详细信息在哪里?你用的是什么方程?它是轴对齐的椭球体吗?您一直在尝试调试什么问题?我会使用视觉检查的正确性,比如做一组随机点 3D 图,并通过你的谓词函数为一些测试椭球设置它们的颜色......在那里你应该直接看到什么是错的......你也可以将椭球图添加到看看你的谓词是否符合预期
  • 我的问题的哪一部分您不清楚?我试图确定某个点是否属于找到的椭球。在我提供的 matlab 代码中,我找到了 3d 空间中 8 个点的最小体积封闭椭球。可视化可以在描述中前面提供的链接中找到。
  • 这并不是说任务没有明确说明......问题是你没有描述你是如何解决这个问题的,以及你目前的方法到底有多错误。如果您按照我的建议进行可视化,您将看到您的谓词在椭球内部究竟考虑了什么,因此更容易推断出什么是错误的......
  • 现在怎么样?我更新了我的方法部分。
  • NO 理由关闭此问题。对于那些不懂数学的人,请走开。您不需要关闭我们这些懂数学的人可以回答的问题。

标签: matlab math algebra


【解决方案1】:

现在这段代码不能打印 Ok 文本(但它应该打印 8 次)。

首先,没有理由期望像MinVolEllipse 函数这样的近似算法会给出封闭椭圆的精确最小体积。您正在为MinVolEllipse 提供容差,因此您应该预计该函数的结果会出现一些错误。

更重要的是,您不需要在这里使用奇异值分解(但请参阅下文了解详细信息)。椭球表面的方程是 (x-c)TA(x-c)=1。您只需检查 (x-c)TA(x-c) 对于每个点是否小于一(加上一些容差):

tol_mvee = 0.01;
tol_dist = 0.1;

[A, c] = MinVolEllipse(P, tol_mvee);

% Check if points lie within ellipse and print Ok for every point inside ellipsoid
for i = 1:length(P(1,:)) % length(P(1,:)) is number of points
    x   = P(i,:);
    x_c = x-c;
    d   = dot(x_c, A*x_c);
    if d < 1+tol_dist
        disp('Ok');
    end
end

您的第一个点显然在椭圆体内。所有其他七个点都在或非常接近封闭椭球的真实最小体积的边界。该算法会遇到一些问题,而且它也会遇到一些问题,即生成的椭球体明显是椭球体而不是球体(请参阅下面的条件编号)。

奇异值分解可能有助于告诉您来自MinVolEllipseA 矩阵是否是病态的,在这个特定问题中有点像这种情况。您的矩阵的条件数超过 200,这意味着您最好不要期望得到一个容差远小于 1e-6 的结果。

【讨论】:

  • 谢谢。这显然比我的方法快。但是你介意看看我使用奇异分解的方式吗?特别是第2点。反转V矩阵是否合法,希望我能得到“恢复旋转”的矩阵?
  • 好的,我刚刚检查过 - 两种方法都返回相同的结果。谢谢!
猜你喜欢
  • 2013-07-20
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 2021-01-01
  • 2022-01-17
相关资源
最近更新 更多