summaryrefslogtreecommitdiff
path: root/numpy/polynomial
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/polynomial')
-rw-r--r--numpy/polynomial/chebyshev.py60
-rw-r--r--numpy/polynomial/tests/test_chebyshev.py20
2 files changed, 79 insertions, 1 deletions
diff --git a/numpy/polynomial/chebyshev.py b/numpy/polynomial/chebyshev.py
index b983b2fec..79623d37e 100644
--- a/numpy/polynomial/chebyshev.py
+++ b/numpy/polynomial/chebyshev.py
@@ -52,6 +52,7 @@ Misc Functions
- `chebline` -- Chebyshev series representing given straight line.
- `cheb2poly` -- convert a Chebyshev series to a polynomial.
- `poly2cheb` -- convert a polynomial to a Chebyshev series.
+- `chebinterp` -- approximate a function with Chebyshev polynomials.
Classes
-------
@@ -87,6 +88,7 @@ References
"""
from __future__ import division, absolute_import, print_function
+import numbers
import warnings
import numpy as np
import numpy.linalg as la
@@ -102,7 +104,7 @@ __all__ = [
'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1',
'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d',
'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion',
- 'chebgauss', 'chebweight']
+ 'chebgauss', 'chebweight', 'chebinterp']
chebtrim = pu.trimcoef
@@ -1886,6 +1888,55 @@ def chebroots(c):
return r
+def chebinterp(func, deg, args=()):
+ """Return the Chebyshev series instance that interpolates a given function
+ at the Chebyshev points of the first kind over the interval [-1, 1].
+
+ Parameters
+ ----------
+ func : function
+ The function to be approximated. It must be a function of a single
+ variable of the form f(x,a,b,c...), where a,b,c... are extra arguments
+ that can be passed in the `args` parameter.
+ deg : int
+ Degree of the resulting polynomial expressed in a Chebyshev basis.
+ args : tuple, optional
+ Extra arguments to be used in the function call.
+
+ Returns
+ -------
+ new_series : series
+ A series that represents the polynomial interpolation
+ to the function.
+
+ Examples
+ --------
+ >>> from numpy import tanh, pi
+ >>> import numpy.polynomial.chebyshev as C
+ >>> C.chebinterp(lambda x: tanh(x)+0.5, 8, domain=[0, 2*np.pi])
+ array([ 1.30198814, 0.3540514 , -0.25209078, 0.14032589, -0.05706644,
+ 0.01226391, 0.00367748, -0.00455335])
+
+ .. versionadded:: 1.14.0
+
+ """
+ ideg = int(deg)
+ if ideg != deg:
+ raise ValueError("deg must be integer")
+ if ideg < 0:
+ raise ValueError("deg must be non-negative")
+
+ degp1 = deg+1
+ xcheb = chebpts1(degp1)
+ yfunc = func(xcheb, *args)
+ m = chebvander(xcheb, deg)
+ c = np.dot(m.T, yfunc)
+ c[0] /= degp1
+ c[1:] /= 0.5*degp1
+
+ return c
+
+
def chebgauss(deg):
"""
Gauss-Chebyshev quadrature.
@@ -2069,6 +2120,13 @@ class Chebyshev(ABCPolyBase):
_roots = staticmethod(chebroots)
_fromroots = staticmethod(chebfromroots)
+ @classmethod
+ def fromfunction(cls, func, deg, domain=None, args=()):
+ """Wrapper method for chebinterp()"""
+ xfunc = lambda x: func(pu.mapdomain(x, [-1, 1], domain))
+ coef = chebinterp(xfunc, deg, args)
+ return cls(coef, domain=domain, window=chebdomain)
+
# Virtual properties
nickname = 'cheb'
domain = np.array(chebdomain)
diff --git a/numpy/polynomial/tests/test_chebyshev.py b/numpy/polynomial/tests/test_chebyshev.py
index 2e4344731..74701af1a 100644
--- a/numpy/polynomial/tests/test_chebyshev.py
+++ b/numpy/polynomial/tests/test_chebyshev.py
@@ -471,6 +471,26 @@ class TestFitting(object):
assert_almost_equal(coef1, coef2)
+class TestInterp(object):
+
+ @staticmethod
+ def f(x):
+ return x * (x - 1) * (x - 2)
+
+ def test_raises(self):
+ assert_raises(ValueError, cheb.chebinterp, self.f, -1, [-1, 1])
+ assert_raises(ValueError, cheb.chebinterp, self.f, 10.1, [-1, 1])
+
+ def test_dimensions(self):
+ for i in range(1, 5):
+ assert_(cheb.chebinterp(self.f, i, [-1, 1]).shape == (i+1,))
+
+ def test_approx(self):
+ assert_almost_equal(cheb.chebinterp(lambda x: [1, 1, 1, 1], 3, [-1, 1]), np.array([1, 0, 0, 0]))
+ assert_almost_equal(cheb.chebinterp(lambda x: x, 3, [-1, 1]), np.array([0, 1, 0, 0]))
+ assert_almost_equal(cheb.chebinterp(self.f, 3, [-1, 1]), np.array([-3/2, 11/4, -3/2, 1/4]))
+
+
class TestCompanion(object):
def test_raises(self):