如果您需要高阶导数,则使用等距数据点不会得到好的结果。如果您可以在任意节点对函数进行采样,我建议您使用 Chebyshev 点,即用于多项式度数。
xk=cos(πkn),k=0…n
n
您可以使用Barycentric Interpolation稳定地评估多项式。请注意,由于您在整个区间内使用高次多项式,因此您可能需要更少的数据点。另请注意,这假设您的数据可以用多项式表示,即它是连续且平滑的。
从插值中获得高阶导数有点棘手,并且不适用于高阶导数。然而,它可以使用切比雪夫多项式来完成。但是,在 Matlab/Octave 中(对不起,我的 Python 一点都不好),您可以执行以下操作:
% We will use the sine function as a test case
f = @(x) sin( 4*pi*x );
% Set the number of points and the interval
N = 40;
a = 0; b = 1;
% Create a Vandermonde-like matrix for the interpolation using the
% three-term recurrence relation for the Chebyshev polynomials.
x = cos( pi*[0:N-1]/(N-1) )';
V = ones( N ); V(:,2) = x;
for k=3:N, V(:,k) = 2*x.*V(:,k-1) - V(:,k-2); end;
% Compute the Chebyshev coefficients of the interpolation. Note that we
% map the points x to the interval [a,b]. Note also that the matrix inverse
% can be either computed explicitly or evaluated using a discrete cosine transform.
c = V \ f( (a+b)/2 + (b-a)/2*x );
% Compute the derivative: this is a bit trickier and relies on the relationship
% between Chebyshev polynomials of the first and second kind.
temp = [ 0 ; 0 ; 2*(N-1:-1:1)'.*c(end:-1:2) ];
cdiff = zeros( N+1 , 1 );
cdiff(1:2:end) = cumsum( temp(1:2:end) );
cdiff(2:2:end) = cumsum( temp(2:2:end) );
cdiff(end) = 0.5*cdiff(end);
cdiff = cdiff(end:-1:3);
% Evaluate the derivative fp at the nodes x. This is useful if you want
% to use Barycentric Interpolation to evaluate it anywhere in the interval.
fp = V(:,1:n-1) * cdiff;
% Evaluate the polynomial and its derivative at a set of points and plot them.
xx = linspace(-1,1,200)';
Vxx = ones( length(xx) , N ); Vxx(:,2) = xx;
for k=3:N, Vxx(:,k) = 2*xx.*Vxx(:,k-1) - Vxx(:,k-2); end;
plot( (a+b)/2 + (b-a)/2*xx , [ Vxx*c , Vxx(:,1:N-1)*cdiff ] );
计算导数的代码可以多次重新应用以计算更高的导数。
如果您使用 Matlab,您可能会对Chebfun项目感兴趣,该项目会自动完成大部分工作,并且上面的代码示例的部分内容取自。Chebfun 可以从字面上任何函数创建插值,例如连续、不连续、具有奇异性等......然后计算它的积分、导数,用它来解决 ODE 等......