Кубическая сплайн экстраполяция

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

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

5 ответов

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

Для экстраполяции сплайна вы можете экстраполировать параметры первого и последнего сплайна.

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

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

Для простоты я собираюсь представить кубическую кривую Безье в виде 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" - это всегда ноль).

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

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

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

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

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


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

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

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

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

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

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

Другие вопросы по тегам