Как я могу изменить количество базовых функций при выполнении подгонки B-Spline в scipy (python)? - PullRequest
0 голосов
/ 05 июля 2018

У меня есть дискретный набор точек (x_n, y_n), которые я хотел бы аппроксимировать / представить как линейную комбинацию базисных функций B-сплайна. Мне нужно иметь возможность вручную изменять количество базовых функций B-сплайнов, используемых методом, и я пытаюсь реализовать это в python, используя scipy. Чтобы быть точным, ниже приведен фрагмент кода, который я использую:

import scipy
spl = scipy.interpolate.splrep(x, y)

Однако, если я что-то не понял или пропустил в документации, похоже, я не могу изменить количество базовых функций B-сплайна, которые использует scipy. Кажется, это определяется размером х и у. Итак, мои конкретные вопросы:

  1. Могу ли я изменить количество базисных функций B-сплайна, используемых scipy в функции "splrep", которую я использовал выше?

  2. Как только я выполнил преобразование, показанное в приведенном выше коде, как я могу получить доступ к коэффициентам линейной комбинации? Правильно ли я считаю, что эти коэффициенты хранятся в векторе spl [1]?

  3. Есть ли лучший метод / набор инструментов, который я должен использовать?

Заранее благодарим за любую помощь / руководство, которое вы можете предоставить.

Ответы [ 2 ]

0 голосов
/ 11 июля 2018

Вы можете изменить количество базовых функций B-сплайна, указав вектор узла с параметром t. Поскольку существует соединение number of knots = number of coefficients + degree + 1, количество узлов также будет определять количество коэффициентов (== количество базисных функций).

Использование параметра t не так интуитивно понятно, поскольку данные узлы должны быть только внутренними узлами. Так, например, если вы хотите 7 коэффициентов для кубического сплайна, вам нужно дать 3 внутренних узла. Внутри функции он дополняет первый и последний (градус + 1) узлы xb и xe (условия зажимного конца см., Например, здесь ). Кроме того, как говорится в документации, узлы должны удовлетворять условиям Шенберга-Уитни.

Вот пример кода, который делает это:

# Input:
x = np.linspace(0,2*np.pi, 9)
y = np.sin(x)

# Your code:
spl = scipy.interpolate.splrep(x, y)
t,c,k = spl  # knots, coefficients, degree (==3 for cubic)

# Computing the inner knots and using them:
t3 = np.linspace(x[0],x[-1],5)  # five equally spaced knots in the interval
t3 = t3[1:-1]  # take only the three inner values

spl3 = scipy.interpolate.splrep(x, y, t=t3)

Что касается вашего второго вопроса, вы правы, что коэффициенты действительно хранятся в spl[1]. Однако обратите внимание, что (как сказано в документации) последние (градус + 1) значения дополняются нулями и должны игнорироваться.

Для оценки результирующего B-сплайна вы можете использовать функцию splev или класс BSpline. Ниже приведен пример кода, который оценивает и рисует вышеупомянутые сплайны (в результате на следующем рисунке):

enter image description here

xx = np.linspace(x[0], x[-1], 101)  # sample points
yy = scipy.interpolate.splev(xx, spl) # evaluate original spline
yy3 = scipy.interpolate.splev(xx, spl3)  # evaluate new spline

plot(x,y,'b.')  # plot original interpolation points
plot(xx,yy,'r-', label='spl')
plot(xx,yy3,'g-', label='spl3')
0 голосов
/ 10 июля 2018

Да, spl [1] - коэффициенты, а spl [0] содержит вектор узла.

Однако, если вы хотите иметь лучший контроль, вы можете манипулировать объектами BSpline и создавать их с помощью make_interp_spline или make_lsq_spline, который принимает вектор узла и который определяет используемые базовые функции b-spline.

...