Использование научной библиотеки GNU (GSL) для рисования двухмерной траектории B-сплайна с использованием неравномерно расположенных точек

Я пытаюсь использовать научную библиотеку GNU (GSL), чтобы нарисовать плавный путь от A до B. Я использую API, который возвращает небольшое количество (8 в данном случае) точек с неравномерным расстоянием (красным), что Вы можете увидеть на следующем рисунке:

возвращенные очки и желаемый результат от GSL

Фиолетовые точки представляют точки, которые я хотел бы видеть возвращенными из GSL.

Во-первых, можно ли получить этот вид 2D B-сплайна с помощью GSL? Я не знаю много о B-сплайнах, не говоря уже о 2D-B-сплайнах. Мне удалось показать пример B-Splines Вот без проблем запустить и создать гладкий файл .ps, но в этом примере используются единые точки останова со следующим кодом:

/* use uniform breakpoints on [0, 15] */
gsl_bspline_knots_uniform(0.0, 15.0, bw);

В моем случае, учитывая, что данные, которые я предоставляю, ошибочны и неравномерно распределены, придется ли мне использовать неоднородные узлы? Я пытался с помощью gsl_bspline_knots(), чтобы использовать неоднородные точки останова в следующем тестовом коде, но я действительно не уверен, является ли это правильным направлением или нет.

#define NCOEFFS 8 // not sure what this number should be - number of data points?
#define NBREAK   (NCOEFFS - 2)
const size_t nbreak = NBREAK;

int main (void) {

// (example code)...

gsl_vector *non_uniform = gsl_vector_alloc(nbreak);

// create some random breakpoint values
for (i=0; i<nbreak; i++) {
double val = gsl_ran_gaussian(r, 2.0);
printf("val: %f\n", val);
gsl_vector_set(non_uniform, i, val);
}

gsl_bspline_knots(non_uniform, bw);

// (more example code)...
}

Более того, как бы я перевел приведенный выше пример для рисования B-сплайнов в 2D координатном пространстве x / y? Если научная библиотека GNU не подходит для этого, может ли кто-нибудь дать рекомендацию для более подходящей библиотеки C / C ++?

Любая помощь или указатели в этом направлении будет высоко ценится.

7

Решение

Первый: 1D Базисные сплайны

Учитывая набор NBREAK контрольные точки (t_1, ..., t_{NBREAK}), имеются NCOEFFS=NBREAK+2 кубические компоненты b-сплайнов B_j(t), Эти функции и их первая и вторая производные всегда непрерывны, даже в точках останова. Следовательно, любое соответствие, данное линейной комбинацией f(t) = \sum m_j B_j(t) также поделится этими свойствами (аналогично естественным кубическим сплайнам). Количество компонентов b-сплайна, NCOEFFS, не должно быть равно количеству точек данных, NDATA, Если NCOEFFS < NDATA, вы должны использовать метод наименьших квадратов для подгонки (документация GSL содержит хороший пример расчета минимальной наименьшей площади для подбора b-сплайна Вот). NCOEFFS < NDATA это хороший выбор, когда данные содержат шум, который, кажется, не ваш случай

Причина, по которой количество коэффициентов не равно числу точек останова, NCOEFFS=NBREAK+2, связано с тем, что вы не указываете граничное условие при работе с базисными сплайнами. Учитывая, что люди обычно более знакомы с естественными кубическими сплайнами, стоит прокомментировать, что естественные кубические сплайны накладывать граничное условие d^2f(x)/dx^2=0, Вот почему любое представление натуральных кубических сплайнов с использованием кубического полиномиального базиса NCOEFFS=NBREAK, Вот ссылка к очень хорошему объяснению о подсчете степеней свободы, заданных коэффициентами кубических полиномов, которые представляют как естественные b-сплайны, так и число уравнений, необходимых для наложения непрерывности f(t), df(t)/dt а также d^2f(t)/dt^2).

В заключение: Подгоните параметрическую кривую, используя b-сплайны.

У вас есть набор «данных» точек (x_1, y_1)....(x_{NDATA},y_{NDATA}) и вы хотите построить параметрическую подгонку P(t)=( f_1(t), f_2(t) ), Подгонка B-сплайнов не будет проходить через все точки данных, если NCOEFFS<NDATA (вы можете потребовать, если вы тщательно выберете свои контрольные точки и NCOEFFS=N_DATA). В своем исследовании я работаю только с одномерными непараметрическими подгонками (y=f(x)) но я считаю, что этот параметрический случай похож. Я бы попробовал следующее

ШАГ 1: Создайте набор точек «данных» (t, x) = {(1, x_1), (2, x_2)...(NDATA, x_{NDATA})} и используйте gsl 1D b-сплайны, чтобы соответствовать им. Это подойдет вам f_1(t) = sum_{i=1}^{NCOEFFS} mx_j B_j(t) с t \in [1,NDATA],

ШАГ 2: Теперь создайте набор точек «данных» (t, y) = {(1, y_1), (2, y_2)...(NDATA, y_{NDATA})} и используйте b-сплайны, чтобы соответствовать им. Это даст вам f_2(t) = sum_{i=1}^{NCOEFFS} my_j B_j(t) с t \in [1,NDATA]

Сейчас сюжет P(t)=( f_1(t), f_2(t) ), t \in [1,NDATA], По сути, я поставил задачу о двухмерной параметрической кривой в двухмерных непараметрических подгонках (что и обеспечивает GSL).

Последний пункт — это выбор точек останова (и количества базовых компонентов NCOEFFS) в шаге 1 и шаге 2. Пока вы охватите диапазон t\in[1, NDATA] а также NCOEFFS <= NDATAвыбор точек останова производится произвольно. Я считаю, что если вы выберете контрольные точки {1, 3, ..., NDATA-2, NDATA } соответствие будет проходить через точки данных (обратите внимание, что я пропустил внутренние точки t=2 а также t=NDATA-1 такой, что NBREAK=NDATA-2 а также NCOEFFS=NDATA). Вот как NAG библиотека выбирает контрольные точки для получения интерполяционного соответствия (то есть соответствия, которое проходит через точки данных).

2

Другие решения


По вопросам рекламы [email protected]