Polyfit not giving expected answers on rotated data

조회 수: 2 (최근 30일)
Joe Bailey
Joe Bailey 2025년 3월 14일
댓글: Joe Bailey 2025년 3월 15일
Hello, I am trying to determine the angle of movement of a target from radar data. I'm trying to use a line of best fit in simulated east-north data (with noise added). The issue came when I got different answers from the same data, but rotated 45 degrees. I wrote a script to see if polyfit was the problem:
rotang = 80;
data1 = [1 :20: 100;zeros(1,5)];
rot = [cosd(rotang), -sind(rotang); sind(rotang), cosd(rotang)];
data1_noise = zeros(2,5);
data2_noise = zeros(2,5);
for m = 1 : 5
data1_noise(1,m) = data1(1,m) + randn*5;
data1_noise(2,m) = data1(2,m) + randn*5;
data2_noise(:,m) = rot * data1_noise(:,m) ;
end
data2 = [(1 :20: 100) *cosd(rotang); (1 :20: 100) *sind(rotang)];
p1 = polyfit(data1_noise(1,:),data1_noise(2,:),1);
p2 = polyfit(data2_noise(1,:),data2_noise(2,:),1);
y1 = polyval(p1,data1_noise(1,:));
y2 = polyval(p2,data2_noise(1,:));
azimuth1 = atand(p1(1));
azimuth2 = atand(p2(1));
disp(azimuth1);disp(azimuth2-rotang);
figure(1);clf;hold on
plot(data1(1,:),data1(2,:),'b')
plot(data2(1,:),data2(2,:),'r')
plot(data1_noise(1,:),data1_noise(2,:),'xb')
plot(data2_noise(1,:),data2_noise(2,:),'xr')
plot(data1_noise(1,:),y1,'--b')
plot(data2_noise(1,:),y2,'--r')
axis equal
hold off
I would expect azimuth2 to be azimuth1 + the rotation angle, since data2 is just data1 rotated, but it is not. Depending on the random noise, it can be completely different:
Does anyone understand what I am doing wrong?
Many thanks
  댓글 수: 2
Torsten
Torsten 2025년 3월 14일
편집: Torsten 2025년 3월 14일
5*randn is quite a lot of noise ... Orthogonal regression instead of usual least-squares regression should give you the expected relation between p1(1) and p2(1) - independent of the noise introduced.
Joe Bailey
Joe Bailey 2025년 3월 15일
Deming worked, thanks

댓글을 달려면 로그인하십시오.

채택된 답변

Cris LaPierre
Cris LaPierre 2025년 3월 14일
polyfit finds the best fit in a least-squares sense. That means it uses the vertical distance between each point and the fit line to determine the best fit. The vertical distance changes as you rotate the line. See the visualizaions below from the curve fitter app. Note the change in scale of the x axis between the two; data1_noise is on the top, and data2_noise is on the bottom.
  댓글 수: 2
Cris LaPierre
Cris LaPierre 2025년 3월 14일
What you want to do is instead use perpendicular distance. Then you would get what you expect - the fit line angle only differs by rotang.
There may be a simpler way to do this, but I followed the example given here: Fitting an Orthogonal Regression using PCA
% create your data
rotang = 80;
data1 = [1 :20: 100;zeros(1,5)];
rot = [cosd(rotang), -sind(rotang); sind(rotang), cosd(rotang)]
rot = 2×2
0.1736 -0.9848 0.9848 0.1736
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
data1_noise = data1 + randn(size(data1))*5;
data2_noise = rot * data1_noise;
% Compute az of data1_noise
az1 = computeAz(data1_noise')
az1 = 0.2322
% Compute az of data2_noise
az2 = computeAz(data2_noise')
az2 = 80.2322
az2-rotang
ans = 0.2322
function az = computeAz(X)
[n,p] = size(X);
meanX = mean(X,1);
[coeff,score,roots] = pca(X);
dirVect = coeff(:,1);
Xfit1 = repmat(meanX,n,1) + score(:,1)*coeff(:,1)';
t = [min(score(:,1))-.2, max(score(:,1))+.2];
endpts = [meanX + t(1)*dirVect'; meanX + t(2)*dirVect'];
plot(endpts(:,1),endpts(:,2),'k-');
X1 = [X(:,1) Xfit1(:,1)];
X2 = [X(:,2) Xfit1(:,2)];
hold on
plot(X1',X2','b-', X(:,1),X(:,2),'bo');
hold off
axis equal
grid on
delta = diff(endpts);
slope = delta(2)/delta(1);
az = atand(slope);
end
Joe Bailey
Joe Bailey 2025년 3월 15일
Thanks

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Descriptive Statistics에 대해 자세히 알아보기

태그

제품


릴리스

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by