Matrix is close to singular or badly scaled.

  • Follow


Overview: Trying to make a short polynomial fitting function using the Vandermonde matrix.

Here is how I generate the necessary vectors:
n = (some number, see below);
T = n/12;
for i=1:n
   xt(i) = i;  % row vector of indep. variable
   s = 0.05*(1 - 2*rand(1));  % add noise
   dt(i) = exp(-0.02*xt(i)) * sin(xt(i)/T) + s;  % synthetic "observations"
end
x = xt';   % column vector of  of indep. variable
d = dt';   % column vector of corresponding observations

q = length(x);
z = x(:);              
A = ones(q,class(z));  
for j = q-1:-1:1
    A(:,j) = z.*A(:,j+1);
end

My next line is either:
P = (A\d);

or
[B,R]=qr(A,0);
P = (R\(B'*d));


Now, for n<10, I can get perfect fits.  However, for n>~15, I get the badly behaved matrix, no matter if I decompose it or not, and my final polynomial fit is just crap.  

Anyone have any suggestions for fixing this?  I'd like to be able to get up to at least n=100 with minimal errors....

Thanks!
0
Reply Mike 10/18/2010 5:06:03 AM

On 10/17/2010 10:06 PM, Mike wrote:
> Overview: Trying to make a short polynomial fitting function using the Vandermonde matrix.
>

<SNIP>

if cond(A) is too big, i.e. A close to singular, try pinv(A) ?.

--Nasser
0
Reply Nasser 10/18/2010 5:12:34 AM



"Mike " <mrg2138@gmail.com> wrote in message 
news:i9gkjr$ksu$1@fred.mathworks.com...
> Overview: Trying to make a short polynomial fitting function using the 
> Vandermonde matrix.
>
> Here is how I generate the necessary vectors:
> n = (some number, see below);
> T = n/12;
> for i=1:n
>   xt(i) = i;  % row vector of indep. variable
>   s = 0.05*(1 - 2*rand(1));  % add noise
>   dt(i) = exp(-0.02*xt(i)) * sin(xt(i)/T) + s;  % synthetic "observations"
> end
> x = xt';   % column vector of  of indep. variable
> d = dt';   % column vector of corresponding observations
>
> q = length(x);
> z = x(:);              A = ones(q,class(z));  for j = q-1:-1:1
>    A(:,j) = z.*A(:,j+1);
> end
>
> My next line is either:
> P = (A\d);
>
> or
> [B,R]=qr(A,0);
> P = (R\(B'*d));
>
>
> Now, for n<10, I can get perfect fits.  However, for n>~15, I get the 
> badly behaved matrix, no matter if I decompose it or not, and my final 
> polynomial fit is just crap.
> Anyone have any suggestions for fixing this?  I'd like to be able to get 
> up to at least n=100 with minimal errors....

In general, unless there's a VERY good reason (based on the underlying 
problem) to fit a high order polynomial equation, you should stick to small 
order (<= 10) equations.  Trying to fit a 100th order polynomial puts you 
squarely in the GIGO scenario.

http://en.wikipedia.org/wiki/GIGO

If you're looking to get a curve that EXACTLY goes through all the points, 
then rather than using a high order polynomial switch to an interpolating 
spline approach.

-- 
Steve Lord
slord@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ
To contact Technical Support use the Contact Us link on 
http://www.mathworks.com 

0
Reply Steven_Lord 10/18/2010 2:14:21 PM

"Mike " <mrg2138@gmail.com> wrote in message <i9gkjr$ksu$1@fred.mathworks.com>...
> Overview: Trying to make a short polynomial fitting function using the Vandermonde matrix.
> 
> Here is how I generate the necessary vectors:
> n = (some number, see below);
> T = n/12;
> for i=1:n
>    xt(i) = i;  % row vector of indep. variable
>    s = 0.05*(1 - 2*rand(1));  % add noise
>    dt(i) = exp(-0.02*xt(i)) * sin(xt(i)/T) + s;  % synthetic "observations"
> end
> x = xt';   % column vector of  of indep. variable
> d = dt';   % column vector of corresponding observations
> 
> q = length(x);
> z = x(:);              
> A = ones(q,class(z));  
> for j = q-1:-1:1
>     A(:,j) = z.*A(:,j+1);
> end
> 
> My next line is either:
> P = (A\d);
> 
> or
> [B,R]=qr(A,0);
> P = (R\(B'*d));
> 
> 
> Now, for n<10, I can get perfect fits.  However, for n>~15, I get the badly behaved matrix, no matter if I decompose it or not, and my final polynomial fit is just crap.  
> 
> Anyone have any suggestions for fixing this?  I'd like to be able to get up to at least n=100 with minimal errors....
> 
> Thanks!

Sigh.

Something works reasonably well. In this case, a low
order polynomial fit. The user tries a slightly higher
order fit, and it works slightly better. So the obvious
extrapolative conclusion is that we can get arbitrarily
better results using an arbitrarily high order polynomial
fit.

The user typically understands nothing about floating
point arithmetic, but his computer is big and fast.

The answer is that, no, high order polynomials are not
a great thing to use. They fail miserably, despite the
idea that a Taylor series is just a high order polynomial.
Floating point arithmetic is your downfall. Do NOT
just keep on throwing higher order polynomials at all
problems.

Instead, use a least squares spline, or any of a variety
of other models. The model you choose will often be
delegated by your particular needs. My suggestion,
which has been designed to do very well for many
problems, is SLM.

http://www.mathworks.com/matlabcentral/fileexchange/24443

John
0
Reply John 10/18/2010 2:38:03 PM

3 Replies
569 Views

(page loaded in 0.056 seconds)

Similiar Articles:












7/23/2012 8:30:37 PM


Reply: