Wenn Sie Derivate höherer Ordnung benötigen, erzielen Sie mit äquidistanten Datenpunkten keine guten Ergebnisse. Wenn Sie Ihre Funktion an beliebigen Knoten abtasten können, würde ich die Verwendung von Chebyshev-Punkten empfehlen, dh für ein Polynom Grad .n
xk= cos( πkn) ,k = 0 … n
n
Sie können das Polynom mithilfe der baryzentrischen Interpolation stabil auswerten . Beachten Sie, dass Sie wahrscheinlich weniger Datenpunkte benötigen, da Sie über das gesamte Intervall ein Polynom von hohem Grad verwenden. Beachten Sie auch, dass dies voraussetzt, dass Ihre Daten durch ein Polynom dargestellt werden können, dh sie sind kontinuierlich und glatt.
Ableitungen höherer Ordnung aus dem Interpolanten zu erhalten, ist etwas schwierig und für Ableitungen hoher Ordnung schlecht konditioniert. Dies kann jedoch unter Verwendung von Chebyshev-Polynomen erfolgen . In Matlab / Octave (sorry, mein Python ist überhaupt nicht gut) können Sie jedoch Folgendes tun:
% 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 ] );
Der Code zum Berechnen der Ableitung kann mehrmals erneut angewendet werden, um höhere Ableitungen zu berechnen.
Wenn Sie Matlab verwenden, könnte Sie das Chebfun- Projekt interessieren , das das meiste automatisch erledigt und aus dem Teile des obigen Codebeispiels stammen. Chebfun kann einen Interpolanten aus buchstäblich jeder Funktion erstellen, z. B. stetig, diskontinuierlich, mit Singularitäten usw. und dann sein Integral und seine Ableitungen berechnen, um ODEs usw. zu lösen.
k=4
anrufenscipy.interpolate.UnivariateSpline
, ist der Spline quartisch.Wenn Sie in Scipy versuchen, die Ableitung n-ter Ordnung eines Splines k-ter Ordnung zu berechnen, wobei n> k ist, erhalten Sie a
ValueError
:Sie könnten so etwas schreiben:
PS: Wie Sie sehen, können Sie anstelle von
__call__
einfach schreibenquelle