Текст подпрограммы и версий
is01r_c.zip , is01d_c.zip
Тексты тестовых примеров
tis01r_c.zip , tis01d_c.zip

Подпрограмма:  is01r_c

Назначение

Построение одномерного сглаживающего кубического сплайна.

Математическое описание

Пусть на сетке x1 < x2 < ... < xN заданы измеренные значения f1, f2, ..., fN некоторой гладкой функции. Требуется найти дважды непрерывно дифференцируемую функцию  s (x), которая минимизирует функционал

        xN
        ∫   ( g''(x) )2 dx
       xi
  среди всех функций g (x) таких, что
         N 
        ∑    [ ( g(xi) - fi ) / ( dfi ) ]2  ≤  SM ,
        i=1 

где  dfi > 0 и SM ≥ 0 - заданные числа.

Числа  dfi характеризуют точность задания дискретных данных  fi, а SM - требуемую меpу их сглаживания.

Решением задачи является сглаживающий кубический сплайн, который на каждом интервале [xi, xi + 1] представляется в виде

   s(x)  =  c3 i h3 + c2 i h2 + c1 i h + yi  ,    h = x - xi , 

где  c3 i , c2 i , c1 i ,  i = 1, 2, ..., N - 1 суть коэффициенты, а  yi - значения сглаживающего сплайна в узлах  xi ,  i = 1, 2, ..., N.

Reinsch C.H. Smoothing by Spline Functions. Numerishe Mathematik, 1967, v.10, 177 - 183.

Морозов B.A. O задаче дифференцирования и некоторых алгоритмах приближения экспериментальной информации, в сб. "Вычислительные методы и программирование", 1970, вып.ХIV, Изд - во МГУ, 46 - 62.

Использование

    int is01r_c (real *x, real *f, real *df, integer *nx, real *sm,
             real *y, real *c, real *rab, integer *ierr)

Параметры

x - вещественный массив длины nx, в котоpом задаются значения узлов сетки такие, что x (i) < x (i + 1),  i = 1, ..., nx - 1;
f - вещественный массив длины nx, в котоpом задаются значения сглаживаемой дискретной функции;
df - вещественный массив длины nx, в котоpом задаются значения весов df (i) > 0 ,  i = 1, ..., nx;
nx - заданное число узлов, nx ≥ 2 (тип: целый);
sm - неотрицательное число, задающее меpу сглаживания (тип: вещественный);
y - вещественный массив длины nx значений сглаживающего сплайна в узлах сетки;
c - двумерный вещественный массив размера 3* (nx - 1) значений коэффициентов сглаживающего сплайна;
rab - двумерный рабочий массив размера 7* (nx + 2) (тип: вещественный);
ierr - целая переменная, служащая для сообщения об ошибках, обнаруженных в ходе работы подпрограммы:
ierr=65 - если nx < 2;
ierr=66 - если массив x не упорядочен строго по возрастанию.

Версии

is01d_с - построение одномерного сглаживающего кубического сплайна с повышенной точностью.

Вызываемые подпрограммы

utis10_c - подпрограмма выдачи диагностических сообщений при работе подпрограммы is01r_c.
utis11_c - подпрограмма выдачи диагностических сообщений при работе подпрограммы is01d_c.

Замечания по использованию: нет

Пример использования

int main(void)
{
    /* Initialized data */
    static float x[5] = { 1.f,2.f,3.f,4.f,5.f };
    static float f[5] = { 1.f,4.f,20.f,16.f,25.f };
    static float df[5] = { .2f,.2f,10.f,.2f,.2f };

    /* Builtin functions */
    double sqrt(double);

    /* Local variables */
    extern int is01r_c(float *, float *, float *, int *, float *, float *,
                       float *, float *, int *);
    static int ierr;
    static float c__[12] /* was [3][4] */;
    static int i__;
    static float y[5], sm;
    static int nx;
    static float rab[49] /* was [7][7] */;

#define c___ref(a_1,a_2) c__[(a_2)*3 + a_1 - 4]

    nx = 5;
    sm = nx - 1.f - (float)sqrt((float)((float) (nx + nx)));
    is01r_c(x, f, df, &nx, &sm, y, c__, rab, &ierr);

    printf("\n %5i \n",ierr);
    for (i__ = 1; i__ <= 5; ++i__) {
           printf("\n %16.7e \n",y[i__-1]);
    }
    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %16.7e %16.7e %16.7e %16.7e \n",
          c___ref(i__, 1), c___ref(i__, 2), c___ref(i__, 3), c___ref(i__, 4));
        }
    return 0;
} /* main */


Результаты:

       ierr  =  0

       y(1) = .999 ; y(2) = 4.003 ; y(3) = 10.85 ; y(4) = 16.003 ; y(5) = 24.999

       c__(1, 1) =  1.785   c__(1, 2) =  5.442   c__(1, 3) =  6.000   c__(1, 4) =  6.558
       c__(2, 1) =  0.000   c__(2, 2) =  3.657   c__(2, 3) = -3.099   c__(2, 4) =  3.657
       c__(3, 1) =  1.219   c__(3, 2) = -2.252   c__(3, 3) =  2.252   c__(3, 4) = -1.219