Code covered by the BSD License

# Euclidian projection on ellipsoid and conic

### Bruno Luong (view profile)

24 May 2010 (Updated )

Projecting a point on ellipsoid or conic in n-dimensional space

EllPrj(P, radii, U, x0, nocheck)
```function x = EllPrj(P, radii, U, x0, nocheck)
%
% x = EllPrj(P, radii, U, x0)
%
% Find the projection of point P in R^n on the ellipsoid
%   E = { x = x0 + U*(z.*radii) : |z| = 1 }, where
% - radii is the length of the ellipsoid axis.
% - U is a n x n matrix given the orientation of the ellipsoid, i.e.,
%   U(:,k) is the kth axis of the ellipsoid corresponding to radii(k).
%   If U is not provided, ellipsoid is alligned with Cartesian axis.
% - x0 is the center coordinates of the ellipsoid. If x0 is not provided
%   origin is selected
%
% INPUTS:
% - P is (n x 1) vector
% - radii is (n x 1) vector
% - U (optional) is (n x n) matrix
% - x0 (optional) is (n x 1) vector
%
% OUTPUT:
%   x (n x p) array, all possible solutions. Each column is coordinate
%   of the candidate point.
%   The condition satisfied by x is vk := (x(:,k)-P) are orthogonal to E.
%   The maximum number of candidates is 2*n, the minimum is 2.
%   It is up to user to filter out the smallest and largest distance to P
%   depending on the need.
%
% To discard orthogonaliy check of U (expensive), call
% with TRUE flag in fifth parameter
%   EllPrj(P, radii, U, x0, true)
%
% Limitation: problem might arise when using on very large dimension
% (e.g., > 50).
%
% See also: StdConicPrj, ConicPrj
%
% Author: Bruno Luong <brunoluong@yahoo.com>
%   Original: 24-May-2010

n = size(radii,1);

radii = radii(:);
if nargin<3 || isempty(U)
U = eye(n);
else
if nargin<5 || ~nocheck
% Make sure the direction are mutually orthogonal
[U R E] = qr(U,0); %#ok
p(E) = 1:n;
U = U(:,p);
end
end
if nargin<4 || isempty(x0)
x0 = zeros(n,1,class(radii));
end
s = 1./radii.^2;

% Change coordinates
%   P = U*d+x0
%   x = U*y+x0
d = U'*(P(:)-x0(:));
y = StdConicPrj(d, s, 0, 1);
x = bsxfun(@plus, U*y, x0(:));

end % EllPrj
```

Contact us