[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Polyfit with scaling
From: |
Ben Abbott |
Subject: |
Re: Polyfit with scaling |
Date: |
Mon, 4 Feb 2008 20:25:03 -0500 |
On Feb 4, 2008, at 8:07 PM, Dmitri A. Sergatskov wrote:
On Feb 4, 2008 7:01 PM, Ben Abbott <address@hidden> wrote:
I'm now confused as to your position. Do you wish to do any check on
mu(2) or just leave it as it is?
I do not think we need to do any check at all.
Ok.
I've attached the corrected version (with some change to the help as
well).
I've also attached a diff to the original.
Ben
--- /Users/bpabbott/Development/cvs/octave/scripts/polynomial/
polyfit.m 2008-01-22 16:52:25.000000000 -0500
+++ polyfit.m 2008-02-04 20:21:57.000000000 -0500
@@ -18,39 +18,37 @@
## <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
-## @deftypefn {Function File} address@hidden, @var{s}] =} polyfit
(@var{x}, @var{y}, @var{n})
+## @deftypefn {Function File} address@hidden, @var{s}, @var{mu}] =}
polyfit (@var{x}, @var{y}, @var{n})
## Return the coefficients of a polynomial @var{p}(@var{x}) of degree
-## @var{n} that minimizes
-## @iftex
-## @tex
-## $$
-## \sum_{i=1}^N (p(x_i) - y_i)^2
-## $$
-## @end tex
-## @end iftex
-## @ifinfo
-## @code{sumsq (p(x(i)) - y(i))},
-## @end ifinfo
-## to best fit the data in the least squares sense.
+## @var{n} that minimizes the least-squares-error of the fit.
##
## The polynomial coefficients are returned in a row vector.
##
-## If two output arguments are requested, the second is a structure
+## The second output is a structured variable, @var{s},
## containing the following fields:
##
-## @table @code
+## @table @samp
## @item R
-## The Cholesky factor of the Vandermonde matrix used to compute the
-## polynomial coefficients.
+## Triangular factor R from the QR decomposition.
## @item X
-## The Vandermonde matrix used to compute the polynomial coefficients.
+## The Vandermonde matrix matrix used to compute the polynomial
coefficients.
## @item df
-## The degrees of freedom.
+## The degrees of freedom.
## @item normr
-## The norm of the residuals.
+## The norm of the residuals.
## @item yf
-## The values of the polynomial for each value of @var{x}.
+## The values of the polynomial for each value of @var{x}.
## @end table
+##
+## The second output may be used by POLYVAL to calculate the
statistical
+## error limits of the predicted values.
+##
+## When the third output, @var{mu}, is present the
+## coefficients, @var{p}, are associated with a polynomial in
+## @var{xhat} = (@address@hidden(1))/@var{mu}(2).
+## Where @var{mu}(1) = mean (@var{x}), and @var{mu}(2) = std (@var{x}).
+## This linear transformation of @var{x} improves the numerical
+## stability of the fit.
## @end deftypefn
## Author: KH <address@hidden>
@@ -59,11 +57,16 @@
function [p, s, mu] = polyfit (x, y, n)
-
- if (nargin != 3)
+ if (nargin < 3 || nargin > 4)
print_usage ();
endif
+ if (nargout > 2)
+ ## Normalized the x values.
+ mu = [mean(x), std(x)];
+ x = (x - mu(1)) / mu(2);
+ endif
+
if (! (isvector (x) && isvector (y) && size_equal (x, y)))
error ("polyfit: x and y must be vectors of the same size");
endif
@@ -74,17 +77,21 @@
y_is_row_vector = (rows (y) == 1);
+ ## Reshape x & y into column vectors.
l = length (x);
x = reshape (x, l, 1);
y = reshape (y, l, 1);
- X = (x * ones (1, n+1)) .^ (ones (l, 1) * (n : -1 : 0));
+ ## Construct the Vandermonde matrix.
+ v = (x * ones (1, n+1)) .^ (ones (l, 1) * (n : -1 : 0));
- p = X \ y;
+ ## Solve by QR decomposition.
+ [q, r, k] = qr (v, 0);
+ p = r \ (y' * q)';
+ p(k) = p;
if (nargout > 1)
-
- yf = X*p;
+ yf = v*p;
if (y_is_row_vector)
s.yf = yf.';
@@ -92,15 +99,13 @@
s.yf = yf;
endif
- [s.R, dummy] = chol (X'*X);
- s.X = X;
+ s.R = r;
+ s.X = v;
s.df = l - n - 1;
s.normr = norm (yf - y);
-
endif
- ## Return value should be a row vector.
-
+ ## Return a row vector.
p = p.';
endfunction
@@ -123,3 +128,38 @@
%! x = [-2, -1, 0, 1, 2];
%! fail("polyfit (x, x.^2+x+1, [])");
+## Test difficult case where scaling is really needed. This example
+## demonstrates the rather poor result which occurs when the dependent
+## variable is not normalized properly.
+## Also check the usage of 2nd & 3rd output arguments.
+%!test
+%! x = [ -1196.4, -1195.2, -1194, -1192.8, -1191.6, -1190.4, -1189.2,
-1188, \
+%! -1186.8, -1185.6, -1184.4, -1183.2, -1182];
+%! y = [ 315571.7086, 315575.9618, 315579.4195, 315582.6206,
315585.4966, \
+%! 315588.3172, 315590.9326, 315593.5934, 315596.0455,
315598.4201, \
+%! 315600.7143, 315602.9508, 315605.1765 ];
+%! [p1, s1] = polyfit (x, y, 10);
+%! [p2, s2, mu] = polyfit (x, y, 10);
+%! assert (s1.normr, 0.11264, 0.1)
+%! assert (s2.normr < s1.normr)
+
+%!test
+%! x = 1:4;
+%! p0 = [1i, 0, 2i, 4];
+%! y0 = polyval (p0, x);
+%! p = polyfit (x, y0, numel(p0)-1);
+%! assert (p, p0, 1000*eps)
+
+%!test
+%! x = 1000 + (-5:5);
+%! xn = (x - mean (x)) / std (x);
+%! pn = ones (1,5);
+%! y = polyval (pn, xn);
+%! [p, s, mu] = polyfit (x, y, numel(pn)-1);
+%! [p2, s2] = polyfit (x, y, numel(pn)-1);
+%! assert (p, pn, s.normr)
+%! assert (s.yf, y, s.normr)
+%! assert (mu, [mean(x), std(x)])
+%! assert (s.normr/s2.normr < 1e-9)
+
+
polyfit.diff
Description: Binary data
polyfit.m
Description: Binary data
- Re: Polyfit with scaling, (continued)
- Re: Polyfit with scaling, Thomas Weber, 2008/02/04
- Re: Polyfit with scaling, Ben Abbott, 2008/02/04
- Re: Polyfit with scaling, Ben Abbott, 2008/02/04
- Re: Polyfit with scaling, John W. Eaton, 2008/02/04
- Re: Polyfit with scaling, Dmitri A. Sergatskov, 2008/02/04
- Re: Polyfit with scaling, John W. Eaton, 2008/02/04
- Re: Polyfit with scaling, Ben Abbott, 2008/02/04
- Re: Polyfit with scaling, Ben Abbott, 2008/02/04
- Re: Polyfit with scaling, Dmitri A. Sergatskov, 2008/02/04
- Re: Polyfit with scaling, Ben Abbott, 2008/02/04
- Message not available
- Re: Polyfit with scaling,
Ben Abbott <=
- Re: Polyfit with scaling - Q regarding polyval, Ben Abbott, 2008/02/05
- Re: Polyfit with scaling - Q regarding polyconf, Ben Abbott, 2008/02/13
- Re: Polyfit with scaling - Q regarding polyconf, Thomas Weber, 2008/02/13
- Re: Polyfit with scaling - Q regarding polyconf, Ben Abbott, 2008/02/13
- Re: Polyfit with scaling - Q regarding polyconf, Thomas Weber, 2008/02/13
- Re: Polyfit with scaling - Q regarding polyconf, Ben Abbott, 2008/02/13
- Re: Polyfit with scaling - Q regarding polyconf, Ben Abbott, 2008/02/13
- [Patch] Polyfit with scaling, Ben Abbott, 2008/02/14
- Re: [Patch] Polyfit with scaling, Dmitri A. Sergatskov, 2008/02/14
- Re: [Patch] Polyfit with scaling, Ben Abbott, 2008/02/14