summaryrefslogtreecommitdiff
path: root/numpy/lib/polynomial.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/lib/polynomial.py')
-rw-r--r--numpy/lib/polynomial.py37
1 files changed, 25 insertions, 12 deletions
diff --git a/numpy/lib/polynomial.py b/numpy/lib/polynomial.py
index 9911c878f..c87d60f51 100644
--- a/numpy/lib/polynomial.py
+++ b/numpy/lib/polynomial.py
@@ -30,13 +30,13 @@ def _eigvals(arg):
get_linalg_funcs()
return eigvals(arg)
-def _lstsq(X, y):
+def _lstsq(X, y, rcond):
"Do least squares on the arguments"
try:
- return lstsq(X, y)
+ return lstsq(X, y, rcond)
except TypeError:
get_linalg_funcs()
- return lstsq(X, y)
+ return lstsq(X, y, rcond)
def poly(seq_of_zeros):
""" Return a sequence representing a polynomial given a sequence of roots.
@@ -169,10 +169,10 @@ def polyder(p, m=1):
val = poly1d(val)
return val
-def polyfit(x, y, N):
+def polyfit(x, y, N, rcond=-1):
"""
- Do a best fit polynomial of order N of y to x. Return value is a
+ Do a best fit polynomial of degree N of y to x. Return value is a
vector of polynomial coefficients [pk ... p1 p0]. Eg, for N=2
p2*x0^2 + p1*x0 + p0 = y1
@@ -195,7 +195,22 @@ def polyfit(x, y, N):
p = (XT*X)^-1 * XT * y
- where XT is the transpose of X and -1 denotes the inverse.
+ where XT is the transpose of X gand -1 denotes the inverse. However, this
+ method is susceptible to rounding errors and generally the singular value
+ decomposition is preferred and that is the method used here. The singular
+ value method takes a paramenter, 'rcond', which sets a limit on the
+ relative size of the smallest singular value to be used in solving the
+ equation. The default value of rcond is the double precision machine
+ precision as the actual solution is carried out in double precision.
+
+ WARNING: Power series fits are full of pitfalls for the unwary once the
+ degree of the fit get up around 4 or 5. Computation of the polynomial
+ values are sensitive to coefficient errors and the Vandermonde matrix is
+ ill conditioned. The knobs available to tune the fit are degree and rcond.
+ The rcond knob is a bit flaky and it can be useful to use values of rcond
+ less than the machine precision, 1e-24 for instance, but the quality of the
+ resulting fit needs to be checked against the data. The quality of
+ polynomial fits *can not* be taken for granted.
For more info, see
http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html,
@@ -205,12 +220,10 @@ def polyfit(x, y, N):
See also polyval
"""
- x = NX.asarray(x)+0.
- y = NX.asarray(y)+0.
- y = NX.reshape(y, (len(y), 1))
- X = vander(x, N+1)
- c, resids, rank, s = _lstsq(X, y)
- c.shape = (N+1,)
+ x = NX.asarray(x) + 0.0
+ y = NX.asarray(y) + 0.0
+ v = vander(x, N+1)
+ c, resids, rank, s = _lstsq(v, y, rcond)
return c