gpt4 book ai didi

python - 如何在 Python 中仅在特定点进行平滑样条插值设置导数?

转载 作者:行者123 更新时间:2023-12-04 04:18:08 25 4
gpt4 key购买 nike

长话短说

显然 scipy不提供类似于 MATLAB 的 spapi 的方法这允许仅在特定点设置导数,确保平滑过渡沿着插值样条曲线。我想找到一种在 Python 中执行此操作的方法。

总体

我的目标是使用 Python 3 进行样条插值,但仅在特定点设置所需的导数。例如,假设数组 X 定义了一个对象的位置,点到点,我想要一个样条曲线来表示一个可行的轨迹,但也要确保速度(一阶导数)在起点和终点处都为零,其他点对衍生品没有限制。在此示例中,我还可能希望加速度(二阶导数)在相同点处等于零。

换句话说,我想要的是类似于 MATLAB 的 spapi 的样条插值实现。功能,引用here :

spline = spapi(knots,x,y) returns the spline f (if any) of order

k = length(knots) - length(x)

with knot sequence knots for which

(*) f(x(j)) = y(:,j), all j.

If some of the entries of x are the same, then this is taken in the osculatory sense, i.e., in the sense that Dm(j)f(x(j)) = y(:, j), with m(j) : = #{ i < j : x(i) = x(j) }, and Dmf the mth derivative of f. Thus r-fold repetition of a site z in x corresponds to the prescribing of value and the first r – 1 derivatives of f at z.

我尝试过的

我知道这个方法 from_derivativesBPolyscipy.interpolate ,但这会带来一个关键问题,即当在任何时候都没有指定导数时,该算法不能保证平滑过渡,如前所述here .我也尝试了建议的内容 here , 但不出所料,同样的问题出现了。

因此,接下来我将展示我正在尝试实现的目标(无论成功与否)的简单再现。

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

以及相应的引用点图以及插值样条: Spline interpolation without setting derivatives, using <code>spapi</code>

这里是该样条的一阶导数: 1st derivative of the interpolated 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);

引用点图和样条曲线: Spline interpolation setting derivatives as zero at start and end, using <code>spapi</code>

这里是该样条的一阶导数: 1st derivative of the interpolated 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 的第一个和最后一个元素通过包含索引 0 处原始值的数组, 和一个 0在索引 1 :

>>> ref_points
[0, 2, 1, 4, 2, 0]
>>> ref_complete
[[0, 0], [2], [1], [4], [2], [0, 0]]

引用点图和样条曲线: Spline interpolation setting derivatives as zero at start and end, using <code>BPoly.from_derivatives</code>

这里是该样条的一阶导数: 1st derivative of the interpolated spline

最佳答案

如果您只想在两端进行零导数的三次样条插值,这就足够了 (docs here)

from scipy.interpolate import CubicSpline

CubicSpline(time_points, ref_points, bc_type="clamped")

关于python - 如何在 Python 中仅在特定点进行平滑样条插值设置导数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60147542/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com