我想计算一个三次多项式,它由函数值和指定点的导数定义。
https://en.wikipedia.org/wiki/Cubic_Hermite_spline
我知道scipy的插值方法。具体地
splprep插入一个N维样条曲线 和 splev来贬低其衍生物。
是否有一个python例程,它接受与 x 值对应的函数值 f(x)和衍生词 f'(x)并计算适合给定数据的样条曲线表示。
举个例子:
我在空间中有两个由坐标 x,y,z 定义的物体位置,我知道物体在这些位置的速度 x',y',z'。我现在可以插入物体随时间t在两点之间所经过的路径。考虑所有给定的参数。
答案 0 :(得分:3)
扩展ev-br's answer,这里有一些示例代码,用于举例说明使用BPoly.from_derivatives
在 n 维度中的点之间插入规定的导数。
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
为了演示此功能的使用,我们指定了点和切线。该例子进一步证明了切线的“幅度”改变后的效果。
# 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()
需要注意三点:
samples
之间进行线性插值,如this post中所述。BPoly.from_derivatives
不能确保此位置的样条曲线之间的平滑过渡。如果上例中的tangents[1]
设置为None
,sampleCubicSplinesWithDerivative(points, tangents, resolution)
,则结果如下所示:
答案 1 :(得分:2)
您可以使用{{1}}。结果是Bernstein基础上的多项式。