Как работает аппроксимация сплайнами?
От: Аноним  
Дата: 05.06.17 01:07
Оценка:
Кто-нибудь может объяснить общую идею, как происходит подбор коэффициентов при аппроксимации функции сплайнами?
Какую хорошую книгу по этой теме можно почитать?
Re: Как работает аппроксимация сплайнами?
От: Nikе Россия  
Дата: 05.06.17 01:09
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Кто-нибудь может объяснить общую идею, как происходит подбор коэффициентов при аппроксимации функции сплайнами?

А>Какую хорошую книгу по этой теме можно почитать?

Метод наименьших квадратов?
Нужно разобрать угил.
Re: Как работает аппроксимация сплайнами?
От: MBo  
Дата: 05.06.17 03:40
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Кто-нибудь может объяснить общую идею, как происходит подбор коэффициентов при аппроксимации функции сплайнами?

А>Какую хорошую книгу по этой теме можно почитать?

Для интерполирующих кубических сплайнов требуется выбрать такие кубические полиномы на каждом интервале, чтобы они сшивались гладко,
переход между интервалами выглядел плавным.
Полиномы стыкуются концами без разрыва — гладкость нулевого порядка. F[i](1) = F[i+1](0) (значение i-го полинома при параметре t)
Направление не меняется — производная одинакова — гладкость первого порядка F[i]'(1) = F[i+1]'(0)
Вторая производная одинакова (как при изгибе стальной линейки) — гладкость второго порядка F[i]''(1) = F[i+1]''(0)
Производные от кубического полинома выглядят несложно, получается 3*N-2 линейных уравнения для 3*N коэффициентов.
Ещё пару уравнений добавляют из каких-либо практических соображений — например, нулевая вторая производная на крайних концах (ненапряженные концы линейки)
Итого получается ленточная система линейных уравнения, которая эффективно решается.


Numerical Recipes in C, 3 глава
Re[2]: Как работает аппроксимация сплайнами?
От: Serg27  
Дата: 05.06.17 05:04
Оценка: 1 (1) +1
Здравствуйте, MBo, Вы писали:


А>>Кто-нибудь может объяснить общую идею, как происходит подбор коэффициентов при аппроксимации функции сплайнами?

А>>Какую хорошую книгу по этой теме можно почитать?

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

MBo>переход между интервалами выглядел плавным.
....

ТС спрашивал про апроксимацию, а не про интерполяцию. Это разные вещи...

MBo>Numerical Recipes in C, 3 глава

Ну можно и эту книгу, только глава будет другая. Ключевые слова — апроксимация, наименьшие квадраты, линейная регрессия и т.п.
Re: Как работает аппроксимация сплайнами?
От: kov_serg Россия  
Дата: 05.06.17 08:33
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>Кто-нибудь может объяснить общую идею, как происходит подбор коэффициентов при аппроксимации функции сплайнами?

А>Какую хорошую книгу по этой теме можно почитать?

Общая идея построить аппроксимацию на участках с помощью полиномов (например 3-го порядка).
На границах участков требуют непрерывность функции (слева и справа должно быть равно), и для производных (в зависимости от порядка сплайна)
На концах ставят условие свободного закреплениея (для 3-го порядка первая производная = 0)
Потом строят целевую функцию S = среднеквадратичному отклониею исходных данных от нашей аппроксимации и ищут её минимум.
В зависимости от того чего мы хотим получаются разные системы уравнений, после решения которых мы получаем все коэффиценты для сплайна.

Всякие варианты есть тут ( http://www.netlib.org/pppack/ http://folk.uio.no/in329/nchap5.pdf )

Для наглядности вот
  псевдокод одномерной аппроксимации кубическими сплайнами с весами (погрешностями измерения точек)
// ispline.cpp 
#include <math.h>

typedef double flt;
typedef flt flt4[4];
typedef flt flt7[7];

inline flt sqr(flt x) { return x*x; }

bool ispline3_build( // ispline3_build - строит аппроксимирующий сплайн 3-го порядка
    int n,   // кол-во точек
    const flt *x,const flt *f,const flt *df, // [n]
    flt sm,  // критерий гладкости 
    flt4 *c, // [n]   результат (коэф. для сплайна)
    flt7 *t  // [n+2] временные данные
) 
// n - кол-во точек
// x,f,df - x-сетка f зн ф-и, df погр f (n штук)
// c - результат (коэф. для сплайна)
// t - рабочий массив (n+2 элементов)                         
// sm - критерий гладкости (0..inf)
{
    flt g=0;
    t[0  ][0]=0; t[1  ][0]=0;
    t[n  ][2]=0; t[n+1][2]=0;
    t[n  ][1]=0;
    t[0  ][5]=0; t[n  ][5]=0;
    t[1  ][5]=0; t[n+1][5]=0;
    flt p=0,h=x[1]-x[0]; if (h<=0) return false;
    flt f2=-sm, ff=(f[1]-f[0])/h;
    {for(int i=2;i<n;i++) {
        g=h; h=x[i]-x[i-1]; if (h<=0) return false;
        flt ldh=1/h;
        flt e=ff; ff=(f[i]-f[i-1])*ldh;
        c[i][0]=ff-e;
        t[i][3]=(g+h)*2.0/3.0;
        t[i][4]=h/3.0;
        t[i][2]=df[i-2]/g;
        t[i][0]=df[i]*ldh;
        t[i][1]=-df[i-1]*(1.0/g+ldh);
    }}
    {for(int i=2;i<n;i++) {
        c[i-1][1]=sqr(t[i][0])+sqr(t[i][1])+sqr(t[i][2]);
        c[i-1][2]=t[i][0]*t[i+1][1]+t[i][1]*t[i+1][2];
        c[i-1][3]=t[i][0]*t[i+2][2];
    }}
    for(;;) {
        {for(int i=2;i<n;i++) {
          t[i-1][1]=ff*t[i-1][0];
          t[i-2][2]= g*t[i-2][0];
          t[i  ][0]=1.0/(p*c[i-1][1]+t[i][3]-ff*t[i-1][1]-g*t[i-2][2]);
          t[i  ][5]=c[i][0]-t[i-1][1]*t[i-1][5]-t[i-2][2]*t[i-2][5];
          ff=p*c[i-1][2]+t[i][4]-h*t[i-1][1];
          g=h; h=c[i-1][3]*p;
        }}
        {for(int i=2;i<n;i++) {
          int j=n+1-i;
          t[j][5]=t[j][0]*t[j][5]-t[j][1]*t[j+1][5]-t[j][2]*t[j+2][5];
        }}
        flt e=0; h=0;
        {for(int i=1;i<n;i++) {
          g=h; h=(t[i+1][5]-t[i][5])/(x[i]-x[i-1]);
          flt hmg=h-g;
          t[i][6]=hmg*sqr(df[i-1]);
          e=e+t[i][6]*hmg;
        }}
        g=-h*sqr(df[n-1]);
        t[n][6]=g;
        e=e-g*h;
        g=f2;
        f2=e*p*p;
        if (f2>=sm || f2<=g)  break;
        ff=0;
        h=(t[2][6]-t[1][6])/(x[1]-x[0]);
        {for(int i=2;i<n;i++) {
          g=h; h=(t[i+1][6]-t[i][6])/(x[i]-x[i-1]);
          g=h-g-t[i-1][1]*t[i-1][0]-t[i-2][2]*t[i-2][0];
          ff=ff+g*t[i][0]*g;
          t[i][0]=g;
        }}
        h=e-p*ff;
        if (h<=0) break;
        p=p+(sm-f2)/((sqrt(sm/e)+p)*h);
    }
    {for(int i=0;i<n-1;i++) {
        c[i][0]=f[i]-p*t[i+1][6];
        c[i][2]=t[i+1][5];
        t[i][0]=c[i][0];
    }}
    t[n-1][0]=f[n-1]-p*t[n][6];
    c[n-1][0]=t[n-1][0];
    {for(int i=1;i<n;i++) {
        h=x[i]-x[i-1];
        c[i-1][3]=(t[i+1][5]-c[i-1][2])/h/3.0;
        c[i-1][1]=(t[i  ][0]-c[i-1][0])/h - (h*c[i-1][3]+c[i-1][2])*h;
    }}
    return true;
}

inline flt spln(flt t,const flt4 &s) { return ((s[3]*t+s[2])*t+s[1])*t+s[0]; } // poly3

flt spline(flt x,int n,const flt *xn,const flt4* c) 
// x - расчетная точка
// xn - сетка : xn[i]<xn[i+1]
// с - коэф. сплайна (строятся с помощью ispline3_build)
{
    int i=0,j=n-1;
    if (x<xn[i  ]) j=i+1;
    if (x>xn[j-1]) i=j-1;
    while ((j-i)>1) {
        int m=(i+j)>>1;
        if (x<xn[m]) j=m; else i=m;
    }
    return spln(x-xn[i],c[i]);
}             

/*
    void example() {
        enum { n=4 };
        flt  x[n]={1,2,3,4};
        flt  y[n]={4,2,0,4};
        flt dy[n]={0.1,1,3,0.1};
        flt7 tmp[n+2]; flt4 c[n];
        flt sm=10.0;
        ispline3_build(n,x,y,dy,sm,c,tmp);
        flt xo=2.5;
        flt fo=spline(xo,n,x,c);
    }
*/
Отредактировано 05.06.2017 9:17 kov_serg . Предыдущая версия .
Re[3]: Как работает аппроксимация сплайнами?
От: MBo  
Дата: 06.06.17 07:26
Оценка:
Здравствуйте, Serg27, Вы писали:

S>ТС спрашивал про апроксимацию, а не про интерполяцию. Это разные вещи...


Интерполяция — один из видов аппроксимации, так что существенных противоречий здесь нет.
Re[2]: Как работает аппроксимация сплайнами?
От: CoderMonkey  
Дата: 09.06.17 14:55
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Всякие варианты есть тут ( http://www.netlib.org/pppack/ http://folk.uio.no/in329/nchap5.pdf )


Важное уточнение — алгоритм должен работать для z = f(x,y)
Где-нибудь можно почитать про алгоритм, который работает в этом случае?
Re[3]: Как работает аппроксимация сплайнами?
От: CoderMonkey  
Дата: 12.06.17 15:14
Оценка:
CM>Важное уточнение — алгоритм должен работать для z = f(x,y)
CM>Где-нибудь можно почитать про алгоритм, который работает в этом случае?

Неужели никто не знает?
Re[4]: Как работает аппроксимация сплайнами?
От: kov_serg Россия  
Дата: 12.06.17 16:50
Оценка: 1 (1)
Здравствуйте, CoderMonkey, Вы писали:


CM>>Важное уточнение — алгоритм должен работать для z = f(x,y)

CM>>Где-нибудь можно почитать про алгоритм, который работает в этом случае?

CM>Неужели никто не знает?

Уточни что именно тебе надо.
Если просто построить гладкую поверхность на нарегулярной сетке то B-spline.
Если аппроксимировать участок из облака точек просто полиномами Чебышева (или обычными если степень небольшая ~3) — самое простое в твоём случае.
А если надо именно 2d поверхность из набраную лоскутками из сплайнов то тебе предётся видимо самому решать эти уравнения
ибо не многие решаются на подобное (На каждой клетке у тебя будет для 3-ей степени не 4 коэф, а 17 и выражать их придётся через две переменные, а не через одну)
Более того сама постановка задачи может быль различна что приводит к разным упрощениям или усложнениям. (Например если взять шаг сетки постоянный будет значительно легче, если не вводить веса для точек если точки расположены узлах или как попало ..., требуется точная аппроксимация или достаточно просто гладкой поверхности, и потом сетка прямоугольная, треугольная или не регулярная, граничные условия свободные концы или циклические условия).
Соответственно и готовое решение по этим причинам трудно найти.

Так что опиши свою задачу со всеми условиями и требованиями.
Re[5]: Как работает аппроксимация сплайнами?
От: CoderMonkey  
Дата: 12.06.17 20:41
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Так что опиши свою задачу со всеми условиями и требованиями.


Итак, дано: функция f(x, y), задана большим дискретным набором точек. Функция гладкая, более-менее. Нужна нерегулярная сетка (из-за того самого "более-менее"). Нужно найти разбиение для сетки и вычислить коэффициенты для набора сплайнов, которые аппроксимируют данный набор точек с заданной максимальной погрешностью.
Какие готовые алгоритмы можно для этого приспособить?
Re[6]: Как работает аппроксимация сплайнами?
От: kov_serg Россия  
Дата: 13.06.17 02:13
Оценка:
Здравствуйте, CoderMonkey, Вы писали:

CM>Здравствуйте, kov_serg, Вы писали:


_>>Так что опиши свою задачу со всеми условиями и требованиями.


CM>Итак, дано: функция f(x, y), задана большим дискретным набором точек. Функция гладкая, более-менее. Нужна нерегулярная сетка (из-за того самого "более-менее"). Нужно найти разбиение для сетки и вычислить коэффициенты для набора сплайнов, которые аппроксимируют данный набор точек с заданной максимальной погрешностью.

CM>Какие готовые алгоритмы можно для этого приспособить?
А для чего будет использована аппроксимация вашей f(x,y)? Если вы хотите значения за областью ваших точек, то сплайны и другие полиминомиальные аппроксимации обычно не годятся, тут в идеале надо иметь модель функции и подбирать её параметры.
А вообще вы ставите очень своеобразную задачу. Надо найти разбиение для заданной максимальной погрешности. Скорее всего вы просто переусложняете задачу.
Думаю вам следует начать с аппроксимации полиномами (хотя всё зависит от вашей f(x,y) много-ли в ней перегибов сёдел и т.п.)
Re[6]: Как работает аппроксимация сплайнами?
От: iriska2  
Дата: 13.06.17 12:14
Оценка: 1 (1)
Здравствуйте, CoderMonkey, Вы писали:

CM>Здравствуйте, kov_serg, Вы писали:


_>>Так что опиши свою задачу со всеми условиями и требованиями.


CM>Итак, дано: функция f(x, y), задана большим дискретным набором точек. Функция гладкая, более-менее. Нужна нерегулярная сетка (из-за того самого "более-менее"). Нужно найти разбиение для сетки и вычислить коэффициенты для набора сплайнов, которые аппроксимируют данный набор точек с заданной максимальной погрешностью.

CM>Какие готовые алгоритмы можно для этого приспособить?

http://hyperfun.org/FHF_Log/Juettler_fitting.pdf
Задача не простая, надо поискать готовые решения
Re[7]: Как работает аппроксимация сплайнами?
От: CoderMonkey  
Дата: 13.06.17 15:53
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>А для чего будет использована аппроксимация вашей f(x,y)? Если вы хотите значения за областью ваших точек, то сплайны и другие полиминомиальные аппроксимации обычно не годятся,


Должно сгодится.

_>тут в идеале надо иметь модель функции и подбирать её параметры.


Невозможно.

_>А вообще вы ставите очень своеобразную задачу. Надо найти разбиение для заданной максимальной погрешности. Скорее всего вы просто переусложняете задачу.

_>Думаю вам следует начать с аппроксимации полиномами (хотя всё зависит от вашей f(x,y) много-ли в ней перегибов сёдел и т.п.)

Упрощаем задачу. Допустим, разбиение сетки я сделал. Нужно подобрать коэффициенты для полиномиальной поверхности, которая аппроксимирует заданный набор точек в прямоугольной области. Какой алгоритм использовать?
Re[8]: Как работает аппроксимация сплайнами?
От: kov_serg Россия  
Дата: 13.06.17 17:36
Оценка: 1 (1)
Здравствуйте, CoderMonkey, Вы писали:

CM>Здравствуйте, kov_serg, Вы писали:


_>>А для чего будет использована аппроксимация вашей f(x,y)? Если вы хотите значения за областью ваших точек, то сплайны и другие полиминомиальные аппроксимации обычно не годятся,

CM>Должно сгодится.

_>>тут в идеале надо иметь модель функции и подбирать её параметры.

CM>Невозможно.

_>>А вообще вы ставите очень своеобразную задачу. Надо найти разбиение для заданной максимальной погрешности. Скорее всего вы просто переусложняете задачу.

_>>Думаю вам следует начать с аппроксимации полиномами (хотя всё зависит от вашей f(x,y) много-ли в ней перегибов сёдел и т.п.)

CM>Упрощаем задачу. Допустим, разбиение сетки я сделал. Нужно подобрать коэффициенты для полиномиальной поверхности, которая аппроксимирует заданный набор точек в прямоугольной области. Какой алгоритм использовать?

Можно для поднятия боевого духа почитать эту книжку
Re[9]: Как работает аппроксимация сплайнами?
От: CoderMonkey  
Дата: 13.06.17 23:30
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Можно для поднятия боевого духа почитать эту книжку


Мне бы что попроще. Но, видимо, придется рыть.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.