O0123
O0123

Reputation: 491

MATLAB curve fitting - least squares method - wrong "fit" using high degrees

Anyone here that could help me with the following problem? The following code calculates the best polynomial fit to a given data-set, that is; a polynomial of a specified degree.

Unfortunately, whatever the data-set may be, usually at degree 6 or higher, MATLAB gets a totally wrong fit. Usually the fit curves totally away from the data in a sort of exponantial-looking-manner downwards. (see the example: degree = 8).

x=[1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5] % experimental x-values
y=[4.3 6.2 10.1 13.5 19.8 22.6 24.7 29.2] % experimental y-values

degree=8; % specify the degree
A = zeros(length(x),degree);
for exponent=0:degree;
for data=1:length(x);
   A(data,exponent+1)=x(data).^exponent; % create matrix A
end;
end;

a=inv((transpose(A)*A))*transpose(A)*y'; % a are the coëfficients of the polynom
a=flipud(a);
fitpolynoom=polyval(a,x);
error=sum((y-fitpolynoom).^2); % calculates the fit-error using the least-squares method
fitpolynoom=polyval(a,x);

figure;
plot(x,y,'black*',x,fitpolynoom,'g-');

error % displays the value of the fit-error in the Matlab command window

Thanks in advance.

Degree 8 - wrong MATLAB polynomial curve fitting

Upvotes: 2

Views: 1481

Answers (1)

Juho Kokkala
Juho Kokkala

Reputation: 141

First, some remarks: for least-squares fitting polynomials in Matlab, you could use the existingpolyfit function instead. Furthermore (this may depend on your application) you probably should not be fitting $8$th degree polynomials, especially when you have $8$ data points. In this answer, I assume you have good reasons to fit polynomials to your data (e.g., just for self-study purposes).

The issue is a numeric problem arising from matrix inversion. For solving equations of type $Ax=b$ where $A$ is a square matrix, actually inverting $A$ is not recommended (See Blogpost 'Don't invert that matrix' by John D. Cook). In the least-squares case, instead of \begin{equation} a = (A^\mathrm{T} A)^{-1} A^\mathrm{T} y^\mathrm{T} \end{equation} it is better to solve \begin{equation} (A^\mathrm{T} A)a = A^\mathrm{T} y^\mathrm{T} \end{equation} by other means. In your MATLAB code, you may replace

a=inv((transpose(A)*A))*transpose(A)*y';

by

a = (transpose(A) * A) \ (transpose(A) * y');

By this modification to your code, I obtained a fit going through the data points.

Upvotes: 4

Related Questions