Как сделать плавные сплайновые производные настройки интерполяции только в указанных точках c, в Python? - PullRequest
1 голос
/ 10 февраля 2020

TL; DR

Очевидно, scipy не предоставляет метод, аналогичный MATLAB spapi, который позволяет устанавливать производные только в указанных точках c, , обеспечивая плавные переходы по всему интерполированному сплайну. Я хотел бы найти способ сделать это в Python.

В целом

Моя цель - выполнить сплайн-интерполяцию с использованием Python 3, но задавать нужные производные только в указанных c баллов. Например, скажем, массив X определяет положение объекта, точка-точка, я бы хотел, чтобы сплайн представлял допустимую траекторию, но также гарантировал, что скорость (первая производная) равна нулю как в начальной, так и в конечной точках, в других точках. не имеет ограничений на производные. В этом примере я мог бы также пожелать, чтобы ускорение (вторая производная) равнялось нулю в тех же точках.

То, что я хочу, это, другими словами, реализация сплайн-интерполяции, аналогичная MATLAB spapi функция, на которую ссылаются здесь :

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) } и Dmf mth производной f . Таким образом, r-кратное повторение сайта z в x соответствует заданному значению и первым r – 1 производным f при 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);

И соответствующий график контрольных точек вместе с интерполированным сплайном: imagespapi">

А вот производная 1-го порядка этого сплайна: 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);

И график исходных точек вместе со сплайном: imagespapi">

А вот производная 1-го порядка этого сплайна: 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]]

И график опорных точек вместе со сплайном: imageBPoly.from_derivatives">

А вот производная 1-го порядка этого сплайна: 1st derivative of the interpolated spline

1 Ответ

0 голосов
/ 10 марта 2020

Если вы просто хотите выполнить кубическую c сплайн-интерполяцию с нулевыми производными на обоих концах, этого достаточно ( документы здесь )

from scipy.interpolate import CubicSpline

CubicSpline(time_points, ref_points, bc_type="clamped")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...