2016-04-15 13 views
1

Ich möchte ein Polynom dritten Grades berechnen, die durch seine Funktion Werte und Ableitungen an bestimmten Punkten definiert ist.Cubic Einsiedler Spline-Interpolation Python

https://en.wikipedia.org/wiki/Cubic_Hermite_spline

Ich kenne Interpolationsverfahren des scipy. Spezifisch

splprep eine N-dimensionale Spline und splev zu interpolieren, dessen Derivate eveluate.

Gibt es eine Python-Routine, die Funktion nimmt Werte f (x) und Derivatef '(x) entsprechend Werten x und berechnet eine Spline-Darstellung, die die gegebenen Daten paßt.

ein Beispiel zu geben:
Ich habe zwei Objektpositionen im Raum durch die Koordinaten definiert x, y, z und ich weiß, um die Geschwindigkeit x ‚y‘, z‘ des Objekts an diesen Positionen . Kann ich nun den Weg, den das Objekt zwischen den beiden Punkten über die Zeit t zurücklegt, interpolieren? Berücksichtigung aller gegebenen Parameter.

Antwort

2

Sie können BPoly.from_derivatives verwenden. Das Ergebnis ist ein Polynom in der Bernstein-Basis.

1

Ausziehbarer ev-br's answer hier einigen Beispielcode, der die Verwendung von BPoly.from_derivatives exemplifiziert zwischen Punkten in n Dimensionen mit vorgeschriebenen Derivate zu interpolieren.

import numpy as np 
from scipy import interpolate 

def sampleCubicSplinesWithDerivative(points, tangents, resolution): 
    ''' 
    Compute and sample the cubic splines for a set of input points with 
    optional information about the tangent (direction AND magnitude). The 
    splines are parametrized along the traverse line (piecewise linear), with 
    the resolution being the step size of the parametrization parameter. 
    The resulting samples have NOT an equidistant spacing. 

    Arguments:  points: a list of n-dimensional points 
        tangents: a list of tangents 
        resolution: parametrization step size 
    Returns:  samples 

    Notes: Lists points and tangents must have equal length. In case a tangent 
      is not specified for a point, just pass None. For example: 
        points = [[0,0], [1,1], [2,0]] 
        tangents = [[1,1], None, [1,-1]] 

    ''' 
    resolution = float(resolution) 
    points = np.asarray(points) 
    nPoints, dim = points.shape 

    # Parametrization parameter s. 
    dp = np.diff(points, axis=0)     # difference between points 
    dp = np.linalg.norm(dp, axis=1)    # distance between points 
    d = np.cumsum(dp)       # cumsum along the segments 
    d = np.hstack([[0],d])      # add distance from first point 
    l = d[-1]         # length of point sequence 
    nSamples = int(l/resolution)     # number of samples 
    s,r = np.linspace(0,l,nSamples,retstep=True) # sample parameter and step 

    # Bring points and (optional) tangent information into correct format. 
    assert(len(points) == len(tangents)) 
    data = np.empty([nPoints, dim], dtype=object) 
    for i,p in enumerate(points): 
     t = tangents[i] 
     # Either tangent is None or has the same 
     # number of dimensions as the point p. 
     assert(t is None or len(t)==dim) 
     fuse = list(zip(p,t) if t is not None else zip(p,)) 
     data[i,:] = fuse 

    # Compute splines per dimension separately. 
    samples = np.zeros([nSamples, dim]) 
    for i in range(dim): 
     poly = interpolate.BPoly.from_derivatives(d, data[:,i]) 
     samples[:,i] = poly(s) 
    return samples 

Um die Verwendung dieser Funktion zu demonstrieren, spezifizieren wir die Punkte und Tangenten. Das Beispiel zeigt weiter den Effekt, wenn die "Größe" der Tangenten geändert wird.

# Input. 
points = [] 
tangents = [] 
resolution = 0.2 
points.append([0.,0.]); tangents.append([1,1]) 
points.append([3.,4.]); tangents.append([1,0]) 
points.append([5.,2.]); tangents.append([0,-1]) 
points.append([3.,0.]); tangents.append([-1,-1]) 
points = np.asarray(points) 
tangents = np.asarray(tangents) 

# Interpolate with different tangent lengths, but equal direction. 
scale = 1. 
tangents1 = np.dot(tangents, scale*np.eye(2)) 
samples1 = sampleCubicSplinesWithDerivative(points, tangents1, resolution) 
scale = 2. 
tangents2 = np.dot(tangents, scale*np.eye(2)) 
samples2 = sampleCubicSplinesWithDerivative(points, tangents2, resolution) 
scale = 0.1 
tangents3 = np.dot(tangents, scale*np.eye(2)) 
samples3 = sampleCubicSplinesWithDerivative(points, tangents3, resolution) 

# Plot. 
import matplotlib.pyplot as plt 
plt.scatter(samples1[:,0], samples1[:,1], marker='o', label='samples1') 
plt.scatter(samples2[:,0], samples2[:,1], marker='o', label='samples2') 
plt.scatter(samples3[:,0], samples3[:,1], marker='o', label='samples3') 
plt.scatter(points[:,0], points[:,1], s=100, c='k', label='input') 
plt.axis('equal') 
plt.title('Interpolation') 
plt.legend() 
plt.show() 

Daraus ergibt sich die folgende Handlung: Cubic splines for different tangent magnitudes

Drei Dinge zu beachten:

  • Folgendes kann auch für mehr als zwei Dimensionen angewendet werden.
  • Der Abstand zwischen den Proben ist nicht festgelegt. Ein einfacher Weg, äquidistantes Abtasten zu erreichen, besteht darin, linear zwischen dem zurückgegebenen samples zu interpolieren, wie es beispielsweise in diskutiert wurde.
  • Die Spezifikation der Tangenten ist optional, BPoly.from_derivatives stellt jedoch keine weichen Übergänge zwischen den Splines an dieser Position sicher. Wenn zum Beispiel tangents[1] in dem obigen Beispiel zu None gesetzt, sampleCubicSplinesWithDerivative(points, tangents, resolution), wird das Ergebnis wie folgt aussehen: Cubic splines with only some tangents being prescribed