Covariance Matrix of an Ellipse

后端 未结 2 1651
闹比i
闹比i 2021-01-05 06:47

I\'ve been trying to solve a problem. I\'m surprised I haven\'t been able to find anything really useful on the net.

I know that from the eigenvalues of the covarian

相关标签:
2条回答
  • 2021-01-05 07:22

    To expand on Rody's answer, the covariance matrix for a solid ellipse has eigenvalues given by lambda_i = r_i^2/4. This leads to OP's equation of r_i = 2*sqrt(lambda_i).

    For a (non-solid) ellipse, as in the OP's case, the eigenvalues are double those of the solid case: lambda_i = r_i^2/2, leading to r_i = sqrt(2*lambda_i) (which is equal to Rody's 2*sqrt(lambda_i/2)).

    I could not directly find a reference for this, but the math of the covariance matrix is identical to that of the moments of inertia. On Wikipedia you can see the case of the "circular hoop" and "solid disk", which differ by the same factor of 2.

    Here is an adaptation of Rody's test, doing both the solid and the non-solid cases:

    % Radius to test with
    r = rand(1,2);
    
    % Random rotation matrix
    R = @(a)[+cos(a) +sin(a); 
             -sin(a) +cos(a)];
    
    % Generate pionts on the ellipse
    N = 1000;
    t = linspace(0, 2*pi, N).';
    xy = r.*[cos(t),sin(t)] * R(rand);
    % Compute radii, compare to known radii
    L = eig(cov(xy));
    r_ = sqrt(2*L)';
    err = max(abs(1 - sort(r_) ./ sort(r)))
    
    % Generate points in the ellipse (SOLID CASE)
    N = 10000;
    t = 2*pi * rand(N,1);
    xy = r .* sqrt(rand(N,1)) .* [cos(t),sin(t)] * R(rand);
    % Compute radii, compare to known radii
    L = eig(cov(xy));
    r_ = 2*sqrt(L)';
    err_solid = max(abs(1 - sort(r_) ./ sort(r)))
    

    If you run this code, you'll see errors of 1e-3 and ~6e-3 (for the solid case I generate many more points, as the area needs more points to be sampled densely enough; the more points, the smaller the error).

    0 讨论(0)
  • 2021-01-05 07:25

    Just by pure reverse engineering (I'm not familiar anymore with this material), I can do this:

    %// Generate circle
    R = 189;
    t = linspace(0, 2*pi, 1000).';
    x = R*cos(t);
    y = R*sin(t);
    
    %// Find the radius?
    [~,L] = eig( cov([x,y]) );
    
    %// ...hmm, seems off by a factor of sqrt(2)
    2*sqrt( diag(L) )        
    
    %// so it would come out right when I'd include a factor of 1/2 in the sqrt():
    2*sqrt( diag(L)/2 )        
    

    So, let's test that theory for general ellipses:

    %// Random radii
    a1 = 1000*rand;
    a2 = 1000*rand;
    
    %// Random rotation matrix
    R = @(a)[
        +cos(a) +sin(a); 
        -sin(a) +cos(a)];
    
    %// Generate pionts on the ellipse 
    t = linspace(0, 2*pi, 1000).';
    xy = [a1*cos(t)  a2*sin(t);] * R(rand);
    
    %// Find the deviation from the known radii
    %// (taking care of that the ordering may be different)
    [~,L] = eig(cov(xy));
    min(abs(1-bsxfun(@rdivide, 2*sqrt( diag(L)/2 ), [a1 a2; a2 a1])),[],2)
    

    which always returns something acceptably small.

    So, seems to work :) Can anyone verify that this is indeed correct?

    0 讨论(0)
提交回复
热议问题