SciPyを使用したスプラインの高次導関数


8

私はPythonで私のデータに合うようにスプラインを作成しました:

spline=scipy.interpolate.UnivariateSpline(energy, fpp, k=4)

使用したい方程式には、n = 2とn = infinityの合計が含まれます。ここで、nは点Eoでの微分の次数です。ただし、使用;

UnivariateSpline.__call__(spline, e0, nu=n)

値を呼び出すために、4階差分を超える値を取得できません。この関数を評価するために人々が知っている他の関数はありますか?約8次の上には、値をゼロに設定する前置乗算器がありますが、それでも4次より高くする必要があります。

回答:


11

より高次の導関数が必要な場合、等距離のデータポイントを使用しても良い結果は得られません。任意のノードで関数をサンプリングできる場合は、チェビシェフポイントを使用することをお勧めします。つまり、 for polynomial程度の。n

xk=cos(πkn),k=0n
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を解くために使用できます。


10

オブジェクトのドキュメントを調べると、UnivariateSpline4次のスプラインを作成しているように見えます。そのため、4次を超える導関数の値を取得できません。(ご承知のとおり、これらの派生物はすべてゼロになります。)

SciPyは、スプラインの多項式次数を5次以下に制限します(つまり、k <= 5)。8次の多項式スプライン補間関数が必要な場合は、別のライブラリを見つけるか、自分でコーディングする必要があります。


3

デフォルトでは、3次の区分的多項式である3次スプラインを使用します。3次多項式の4次導関数をとると、結果は0になります。これらの高次微分が本当に必要な場合は、3次スプラインを使用しても効果がありません。


私はあなたの答えのほとんどに同意しますが、k=4への呼び出しの場合scipy.interpolate.UnivariateSpline、スプラインは4次です。
Geoff Oxberry、2012

2

Scipyでは、k次のスプラインのn次の導関数(n> k)を計算しようとすると、次のようになりますValueError

ValueError:0 <= der = 5 <= k = 4は保持する必要があります

あなたはこのようなものを書くことができます:

def spline_der(spline, x, nu=0):
    sd = 0
    try:
        sd = spline(x, nu=nu)
    except ValueError:
        pass
    return sd

PS:ご覧のとおり、を使用する代わりに__call__、単に

spline(e0, nu=n)

どういたしまして!:)
astrojuanlu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.