-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathfcnerrorellipse.m
122 lines (101 loc) · 3.42 KB
/
fcnerrorellipse.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
% Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
function [ellipse, cross, h] = fcnerrorellipse( C , mu, conf, plotflag)
% 'C' - Alternate method of specifying the covariance matrix
% 'mu' - Alternate method of specifying the ellipse (-oid) center
% 'conf' - A value between 0 and 1 specifying the confidence interval.
if nargin<4; plotflag=false; end
h=gobjects(2);
[r,c] = size(C);
x0=mu(1);
y0=mu(2);
if conf==.9 && r==2
k=2.14597;
elseif conf==.9 && r==3
k=2.50028;
else
% Compute quantile for the desired percentile
k = fcnconfidence2sigma(conf,r); % r is the number of dimensions (degrees of freedom)
%k = erfinv(conf)*sqrt(2); %1 dim only!!
end
if r==3
z0=mu(3);
[eigvec,eigval] = eig(C);
[X,Y,Z] = ellipsoid(0,0,0,1,1,1,100);
XYZ = [X(:),Y(:),Z(:)]*sqrt(eigval)*eigvec';
X(:) = k*XYZ(:,1)+x0;
Y(:) = k*XYZ(:,2)+y0;
Z(:) = k*XYZ(:,3)+z0;
ellipse.x=X; ellipse.y=Y; ellipse.z=Z;
%cross
XYZ = [1.3 0 0
-1 0 0
0 0 0
0 1 0
0 -1 0
0 0 0
0 0 1
0 0 -1] * sqrt(eigval)*eigvec';
cross.x = k*XYZ(:,1)+x0;
cross.y = k*XYZ(:,2)+y0;
cross.z = k*XYZ(:,3)+z0;
if plotflag
h(1)=surf(X,Y,Z,'FaceColor',[0 0 0],'FaceAlpha',.2,'FaceLighting','gouraud','EdgeColor','none');%,'AmbientStrength',1E6);
h(2)=plot3(cross.x,cross.y,cross.z,'b-','linewidth',1.2);
box on; axis vis3d; light; camlight headlight
end
elseif r==2
n=100; % Number of points around ellipse
p=(0:pi/n:2*pi)'; % angles around a circle
[eigvec,eigval] = eig(C); % Compute eigen-stuff
xy = k * [cos(p) sin(p)] * sqrt(eigval) * eigvec'; % Transformation
ellipse.x=xy(:,1)+x0; ellipse.y=xy(:,2)+y0;
%cross
XYZ = [1.1 0
-1 0
0 0
0 1
0 -1
0 0
0 0
0 0] * sqrt(eigval)*eigvec';
cross.x = k*XYZ(:,1)+x0;
cross.y = k*XYZ(:,2)+y0;
if plotflag
h(1)=plot(ellipse.x,ellipse.y,'-');
%h(2)=plot(cross.x,cross.y,'-','Color',h(1).Color,'linewidth',.1);
end
end
% %INPUT 2X2 COVARIANCE MATRIX, AND PERCENTILE YOU WANT ERROR ELLIPSE TO
% %ENCOMPASS. For example, if percentile=90, then the error ellipse will show
% %the region that encloses a 90% probability. If percentile=68.3, then you
% %will get a 1sigma error ellipse.
%
% %MEAN XY POINTS ARE THE CENTER OF THE ELLIPSE. Input [0 0] if you don't need that part.
%
% sigmaMultiple = erfinv(conf/100)*sqrt(2);
%
% %SET NUMBER OF DATA POINTS TO RETURN, AND CENTER OF CIRCLE
% t=(1:1:361)'*pi/180; %theta, angles on the circle.
% cx=mu(1); %center of circle
% cy=mu(2); %center of circle
%
% %GET EIGENVALUES AND EIGENVECTORS OF 2x2 XY COVMAT
% [eigVec eigVal] = eigs(C(1:2,1:2));
% a=sqrt(eigVal(1,1))*sigmaMultiple;
% b=sqrt(eigVal(2,2))*sigmaMultiple;
% phi=atan2(eigVec(2,1),eigVec(1,1));
%
% %CALCULATE CIRCLE XY POINTS
% x=cx+a*cos(t)*cos(phi)-b*sin(t)*sin(phi);
% y=cy+b*sin(t)*cos(phi)+a*cos(t)*sin(phi);
%
% %DEFINE OUTPUT ELLIPSE
% xyOut = [x y]; %move ellipse to mean point
%
% %DEFINE OUTPUT CROSS
% cross(:,:,1) = [x(360)*0 x(90)*0 x(180)*0 x(270)*0
% x(360)*1.1 x(90)*1 x(180)*1 x(270)*1] + ones(2,4)*mu(1);
% cross(:,:,2) = [y(360)*0 y(90)*0 y(180)*0 y(270)*0
% y(360)*1.1 y(90)*1 y(180)*1 y(270)*1] + ones(2,4)*mu(2);
%
% end