Dẫn xuất bậc cao của spline bằng SciPy


8

Tôi đã tạo một spline để phù hợp với dữ liệu của mình trong python bằng cách sử dụng:

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

Phương trình tôi muốn sử dụng bao gồm tổng giữa n = 2 và n = vô cùng, trong đó n là thứ tự của vi phân tại một điểm Eo. Tuy nhiên, sử dụng;

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

để gọi giá trị, tôi không thể nhận được giá trị cho bất cứ thứ gì vượt qua chênh lệch bậc 4. Có chức năng nào khác mà mọi người biết để đánh giá chức năng này không? Ở trên khoảng thứ 8 có một số nhân trước nên đặt giá trị thành 0 nhưng tôi vẫn cần phải tăng cao hơn đơn hàng thứ 4.

Câu trả lời:


11

Nếu bạn cần các công cụ phái sinh bậc cao hơn, bạn sẽ không nhận được kết quả tốt khi sử dụng các điểm dữ liệu tương đương. Nếu bạn có thể lấy mẫu hàm của mình tại các nút tùy ý, tôi khuyên bạn nên sử dụng các điểm , tức là cho đa thức độ .n

xk=cos(πkn),k=0n
n

Bạn có thể đánh giá đa thức ổn định bằng Nội suy Barycentric . Lưu ý rằng vì bạn đang sử dụng đa thức mức độ cao trong toàn bộ khoảng thời gian, nên có thể bạn sẽ cần ít điểm dữ liệu hơn. Cũng lưu ý rằng điều này giả định rằng dữ liệu của bạn có thể được biểu diễn bằng đa thức, tức là nó liên tục và trơn tru.

Nhận các dẫn xuất bậc cao từ nội suy là một chút khó khăn và không có điều kiện cho các dẫn xuất cao. Nó có thể được thực hiện, tuy nhiên, bằng cách sử dụng đa thức Ch Quashev . Trong Matlab / Octave (xin lỗi, Python của tôi không tốt chút nào), tuy nhiên, bạn có thể làm như sau:

% 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 ] );

Mã để tính đạo hàm có thể được áp dụng lại nhiều lần để tính đạo hàm cao hơn.

Nếu bạn sử dụng Matlab, bạn có thể quan tâm đến dự án Chebfun , phần lớn thực hiện điều này một cách tự động và từ đó các phần của ví dụ mã ở trên đã được thực hiện. Chebfun có thể tạo ra một phép nội suy từ bất kỳ hàm nào theo nghĩa đen, ví dụ như liên tục, không liên tục, với các điểm kỳ dị, v.v ... và sau đó tính tích phân, đạo hàm của nó, sử dụng nó để giải ODE, v.v ...


10

Kiểm tra tài liệu cho UnivariateSplineđối tượng, có vẻ như bạn đang xây dựng một spline bậc 4, đó là lý do tại sao bạn không thể nhận được các giá trị cho các đạo hàm lớn hơn bậc 4. (Tất cả các dẫn xuất đó, như bạn biết, sẽ bằng không.)

SciPy giới hạn mức độ đa thức của spline là bậc 5 trở xuống (nghĩa là k <= 5). Nếu bạn cần một phép nội suy spline đa thức bậc 8, bạn phải tìm một thư viện thay thế hoặc có thể tự viết mã cho nó.


3

Theo mặc định, bạn sử dụng các khối vuông, là đa thức piecewise bậc 3. Nếu bạn lấy đạo hàm thứ tư của đa thức bậc 3, bạn sẽ kết thúc bằng 0. Nếu bạn thực sự cần những khác biệt bậc cao này, sử dụng các khối vuông sẽ không tốt cho bạn.


Tôi đồng ý với hầu hết câu trả lời của bạn, nhưng nếu k=4trong cuộc gọi đến scipy.interpolate.UnivariateSpline, thì spline là quartic.
Geoff Oxberry

2

Trong Scipy, nếu bạn cố gắng tính đạo hàm bậc n của một spline bậc k, trong đó n> k, thì bạn nhận được a ValueError:

Giá trịError: 0 <= der = 5 <= k = 4 phải giữ

Bạn có thể viết một cái gì đó như thế này:

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

PS: Như bạn thấy, thay vì sử dụng __call__, bạn chỉ cần viết

spline(e0, nu=n)

Hân hạnh! :)
astrojuanlu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.