python - 如何在 Python 中仅在特定点进行平滑样条插值设置导数?
问题描述
TL;博士
显然scipy
没有提供类似于 MATLAB 的方法,该方法spapi
允许仅在特定点设置导数,从而确保沿插值样条的平滑过渡。我想找到一种在 Python 中做到这一点的方法。
全面的
我的目标是使用 Python 3 进行样条插值,但仅在特定点设置所需的导数。例如,假设数组 X 定义了一个对象的位置,点对点,我想要一个样条曲线来表示一个可行的轨迹,但还要确保速度(一阶导数)在起点和终点都为零,其他点对衍生品没有限制。在此示例中,我还希望在相同点处使加速度(二阶导数)为零。
换句话说,我想要的是类似于 MATLABspapi
函数的样条插值的实现,如下所示:
spline = spapi(knots,x,y)
返回顺序的样条f(如果有)
k = length(knots) - length(x)
带有结序列的结
(*) f(x(j)) = y(:,j), all j.
如果 的某些条目
x
是相同的,那么这是在接触意义上的,即在Dm(j)f(x(j)) = y(:, j)
、m(j) : = #{ i < j : x(i) = x(j) }
和fDmf
的mth
导数的意义上。因此,位点in的 r 倍重复对应于值的规定和f at的一阶导数。z
x
r – 1
z
我试过的
我知道 的 类的方法from_derivatives
,BPoly
但这scipy.interpolate
带来了一个关键问题,即当未在任何点指定导数时,该算法不能保证平滑过渡,如此处所述。我也尝试了这里提出的建议,但正如预期的那样,出现了同样的问题。
所以,接下来我将简单复制我想要实现的目标,无论成功与否。
spapi
没有衍生品
spapi
这里是在 MATLAB 中使用方法的示例,没有设置任何导数。不是我想要的,因为导数在起点和终点都很高:
xi = linspace(0, 10, 6);
xnew = linspace(0, 10, 100);
yi = [0 2 1 4 2 0];
knots = optknt(xi, order);
ref_spline = spapi(knots, xi, yi);
spline = fnval(xnew, ref_spline);
der_spline = gradient(spline);
spapi
与衍生品
在这里,使用spapi
MATLAB 中的方法的示例,将导数设置为0
起点和终点。完全符合预期结果,沿样条曲线平滑过渡,导数等于0
起点和终点:
xi = linspace(0, 10, 6);
xnew = linspace(0, 10, 100);
xder = [0 xi 10];
yi = [0 2 1 4 2 0];
ynew = [0 yi 0];
knots = optknt(xder, order);
ref_spline = spapi(knots, xder, ynew);
spline = fnval(xnew, ref_spline);
der_spline = gradient(spline);
BPoly.from_derivatives
与衍生品
在这里,使用BPoly.from_derivatives
将导数设置为0
起点和终点的示例。不成功,即使导数0
在起点和终点,也不能保证沿样条线平滑过渡:
ref_points = [0, 2, 1, 4, 2, 0]
time_vector = np.linspace(0, 10, 100)
time_points = np.linspace(0, 10, 6)
ref_complete = [[ref_points[j] if (i == 0) else 0 for i in range(2)] if (
(j == 0) or (j == len(ref_points) - 1)) else [ref_points[j]] for j in range(len(ref_points))]
ref_spline = BPoly.from_derivatives(time_points, ref_complete)
spline = ref_spline(time_vector)
der_spline = ref_spline.derivative(1)
der_y = der_spline(time_vector)
澄清一下,定义的行ref_complete
简单地将 的第一个和最后一个元素替换为ref_points
一个数组,该数组包含 index 处的原始值和 index处0
的 a :0
1
>>> ref_points
[0, 2, 1, 4, 2, 0]
>>> ref_complete
[[0, 0], [2], [1], [4], [2], [0, 0]]
解决方案
如果您只想在两端使用零导数进行三次样条插值,这就足够了(此处的文档)
from scipy.interpolate import CubicSpline
CubicSpline(time_points, ref_points, bc_type="clamped")
推荐阅读
- java - 在文本的下一行和中心设置图像跨度
- c# - 在 SQL 表中使用 Html 并在 foreach 语句中检索它
- authentication - 过期时间在 ASP.Net Core 中不起作用
- c# - 如何在 Blob 存储中创建文件夹
- python - 在 sklearn RandomForestClassifier 中移动假想的决策边界
- google-tag-manager - dataLayer 变量在 GTM 自定义 HTML 标记内没有动态变化
- github - 有什么方法可以在没有第三方服务器的情况下,在新问题出现时自动构建 GitHub 页面?
- facebook - 使用 Facebook 评论社交插件 - 新创建页面的许多不相关评论
- caching - 什么是间接费用百分比?
- android - 使用意图打开音频文件...(“audio/wav”)