Кубическая сплайн экстраполяция - PullRequest
4 голосов
/ 19 мая 2009

У меня хороший кубический сплайн-код, но он только для интерполяции. Мне нужно экстраполировать чуть-чуть в будущее. Кто-нибудь знает хороший источник кода, а не библиотеку, для этого?

Это код Я написал базовый (теперь ASM) для интерполяции.

Ответы [ 5 ]

6 голосов
/ 19 мая 2009

Вам не нужен новый код для этого.

Чтобы экстраполировать сплайн, вы можете экстраполировать параметры первого и последнего сплайна.

В зависимости от существующего кода / библиотеки это может быть невозможно без изменения кода. В этом случае просто добавьте / добавьте две другие точки к началу / концу списка точек. Вы можете получить эти две точки путем линейной интерполяции между первыми / последними двумя точками.

Будьте осторожны: В зависимости от первоначального значения пунктов, экстраполяция может быть совершенно неуместной, особенно когда речь идет о статистических данных. В этом случае вам следует рассмотреть возможность использования регрессионного анализа .

3 голосов
/ 22 июня 2011

Для простоты я собираюсь представить кубическую кривую Безье как 4 балла (A, B, C, D), где A и D являются конечными точками кривой, B и C - это «точки управления». (Фактическая кривая обычно не касается точек управления).

См. "Библиотека кубических сплайнов в логове гуру дона Ланкастера" способы преобразования этого представления кубической кривой Безье в другие популярные представления.

интерполяция

Учитывая одну кубическую кривую Безье (P0, P1, P2, P3), мы используем алгоритм де Кастельжау нарезать кривую Безье в левая половина и правая половина. Это очень просто даже на микроконтроллере, который не имеет инструкции «умножения», потому что требуется только вычисление нескольких средних, пока мы не получим среднюю точку:

P0
   F0 := average(P0, P1)
P1                       S0 := average(F0, F1)
   F1 := average(P1, P2)         Midpoint := average(S0, S1)
P2                       S1 := average(F1, F2)
   F2 := average(P2, P3)
P3

Вся кривая Безье имеет вид (P0, P1, P2, P3).

Левая половина всей этой кривой Безье - это кривая Безье (P0, F0, S0, M).

Правая половина всей этой кривой Безье - это кривая Безье (M, S1, F2, P3).

Многие микроконтроллеры продолжают делить каждую кривую вверх в меньшие и меньшие маленькие кривые пока каждый кусок не станет достаточно маленьким, чтобы прямая линия.

Но мы хотим пойти другим путем - экстраполировать на большую кривую.

экстраполяция

Учитывая либо левую, либо правую половину, мы можем запустить это в обратном порядке, чтобы восстановить исходную кривую.

Давайте представим, что мы забыли исходные точки P1, P2, P3.

Учитывая левую половину кривой Безье (P0, F0, S0, M), мы можем экстраполировать вправо с помощью:

S1 := M + (M - S0)
F1 := S0 + (S0 - F0)
P1 := F0 + (F0 - P0)

затем используйте эти значения для вычисления

F2 := S1 + (S1 - F1)
P2 := F1 + (F1 - P1)

и, наконец,

P3 := F2 + (F2 - P2)

для экстраполяции и восстановления экстраполированной кривой Базье (P0, P1, P2, P3).

подробности

Экстраполированная кривая (P0, P1, P2, P3) проходит через каждую точку в исходной кривой (P0, F0, S0, M) - в частности, начиная с P0 и проходя через среднюю точку M - и продолжает идти, пока не достигнет P3.

Мы всегда можем экстраполировать из любых 4 точек (P0, F0, S0, M), были ли эти 4 балла изначально рассчитаны как левая половина (или правая половина) более крупного сплайна Безье.

Я уверен, что вы уже знаете это, но для ясности:

Midpoint = average(F0, F1)

означает «найти середину точно на полпути между точками F0 и F1», или, другими словами,

Midpoint.x = (F0.x + F1.x)/2
Midpoint.y = (F0.y + F1.y)/2
Midpoint.z = (F0.z + F1.z)/2

Выражение

S1 := M + (M - S0)

означает «Заданный отрезок линии с одним концом в S0 и средней точкой в ​​M, начинайте с S0 и бегите по прямой после M, пока не дойдете до другого конца на S1 ", или другими словами (если у вас нет приличной векторной библиотеки) 3 строки кода

S1.x := M.x + (M.x - S0.x)
S1.y := M.y + (M.y - S0.y)
S1.z := M.z + (M.z - S0.z)

. (Если вы делаете 2D, пропустите все элементы "z" - это всегда ноль).

2 голосов
/ 19 мая 2009

Тебе действительно придется немного расширить этот вопрос. Кроме того, «кубический сплайн» - это очень широкий термин.

Если вам интересны сплайны, я могу сердечно рекомендовать Карлу де Бурсу «Практическое руководство по сплайнам». Это, однако, немного математически ориентировано, но в него включены примеры кода (их можно скачать с домашней страницы автора). Поиск в Google и «вики» для «кубического сплайна» могут привести некоторые примеры, может быть, даже на определенных языках - еще одна вещь, которую нужно добавить в вопрос (если вы ищете код).

Если вы заинтересованы в экстраполяции и подгонке кривой, поиск в Google может помочь. Пакет Matlab имеет очень хороший набор инструментов для подгонки под кривой. В Википедии есть несколько ссылок на полезные ссылки

Действительно, это слишком широкий вопрос, чтобы даже начать угадывать ответ.

Кроме того, не могли бы вы объяснить, что именно вы пытаетесь сделать? Какие данные? Что-нибудь?


Edit1: здесь, попробуйте это: вы можете найти что-то полезное здесь - ссылка

1 голос
/ 19 мая 2009

Вы должны написать лучшие требования для запрашиваемого кода. Сплайны обычно используются для интерполяции некоторой неизвестной или сложной функции с использованием некоторого фиксированного набора данных. Если вы хотите получить оценку значения функции за пределами этого набора данных, вам не следует использовать сплайны.

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

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

Действительно, я предлагаю вам использовать какой-то алгоритм, более подходящий для экстраполяции, например, использование полинома Лагранжа , если все, что вам действительно нужно, - это одно значение, не очень далеко от точек исходного набора данных.

1 голос
/ 19 мая 2009

Обычно для сплайн-интерполяции вы используете переменную t для интерполяции по линии. Пока 0 <= t <= 1, вы интерполируете. Однако, когда t <0 или t> 1, вы просто экстраполируете сплайн.

...