|
Текст подпрограммы и версий is02r_c.zip |
Тексты тестовых примеров tis02r_c.zip |
Сглаживание экспериментально заданной дискретной функции одномерным периодическим кубическим сплайном.
Пусть в узлах неравномернoй ceтки X1 < X2 < ... < XN приближенно заданы дискретные значения Uk, k = 1, 2, ..., N. Обозначим через D множество дважды непрерывно дифференцируемых функций g (x), удовлетворяющих условиям периодичности:
g(u) (X1) = g(u) (XN) , u = 0, 1, 2 .
Требуется найти сглаженные значения y (Xk), y" (Xk) периодического кубического сплайна y (X), минимизирующего функционал
N
∑ pk( g(xk) - uk )2 +
k=1
XN
+ ∫ ( g"(x) )2 dx , g ∈ D
X1
Здесь pk > 0, k = 1, 2, ..., N, суть заданные веса, определяемые точностью задания uk и требуемой мерой их сглаживания. В частности, при
pk = σk2 / α , σk2 = M ( uk - M uk )2 ,
где M - символ математического ожидания, получаем регуляризованный периодический кубический сплайн y (x), соответствующий параметру регуляризации α > 0.
Для контроля за степенью сглаживания вычисляются такие характеристики:
XN
E1 = ∫ [ y"(x) ]2 dx ,
X1
N
E2 = ( ∑ pk ( yk - uk )2 ) / ( p1 + ... + pN )
k=1
Сплайн y (x) на отрезке [Xk, Xk + 1] может быть восстановлен по формуле
(xk+1-x)3 (x-xk)3
y(x) = y"(xk) * ------------- + y"(xk+1) * ------------- +
6*δxk 6*δxk
y"(xk)*(δxk)2 xk+1-x
+ ( y(xk) - ----------------------- ) * ----------------- +
6 δxk
y"(xk+1)*(δxk)2 x-xk
+ ( y(xk+1) - ---------------------- ) * --------------- ,
6 xk
где Δxk = xk + 1 - xk .
Морозов B.A. O задачах дифференцирования и некоторых алгоритмах приближения экспериментальной информации. "Вычислительные методы и программирование", 1970, вып.14, МГУ, 46 - 62.
int is02r_c (integer *n, real *x, real *u, real *p, real *y,
real *y2, real *dx, real *e, real *r, integer *ierr)
Параметры
| n - | заданное число узлов сетки, n ≥ 3 (тип: целый); |
| x - | вещественный вектоp длины n, содержащий заданные значения узлов сетки и упорядоченный так, что x (1) < x (2) < ...< x (n); |
| u - | вещественный вектоp длины n, содержащий заданные значения сглаживаемой функции; |
| p - | вещественный вектоp длины n, содержащий заданные веса, p (i) > 0, i = 1, 2, ..., n; |
| y - | вещественный вектоp длины n, содержащий вычисленные в узлах сетки значения сглаживающего периодического кубического сплайна; |
| y2 - | вещественный вектоp длины n, содержащий вычисленные в узлах сетки значения второй производной сглаживающего периодического кубического сплайна; |
| dx - | вещественный вектоp длины n - 1, содержащий вычисленные значения шагов сетки dx (k) = x (k + 1) - x (k), k = 1, 2, ..., n - 1; |
| e - | вещественный вектоp длины 2, e (1) = E1, e (2) = E2; |
| r - | вещественный двумерный рабочий массив размера 6 на n; |
| ierr - | целая переменная, служащая для сообщения об ошибках, обнаруженных в ходе работы подпрограммы; при этом: |
| ierr=65 - | если n < 3; |
| ierr=66 - | если элементы вектоpа x не упорядочены строго по возрастанию; |
| ierr=67 - | если хотя бы один элемент вектоpа p меньше или pавен нулю. |
Версии: нет
Вызываемые подпрограммы
| uti i10_c - | подпрограмма выдачи диагностических сообщений при работе подпрограммы is02r_c. |
Замечания по использованию
| Подпрограмма is02r_c может быть использована для сглаживания приближенно заданных на неравномерной сетке t1 < t2 < ...< tn значений uk = u (tk), vk = v (tk), k = 1, 2, ..., n параметрической циклической функции u = u (t), v = v (t). Для этого достаточно дважды обратиться к подпрограмме is02r_c. |
int main(void)
{
/* Builtin functions */
double sin(double);
/* Local variables */
extern int is02r_c(int *, float *, float *, float *, float *, float *,
float *, float *, float *, int *);
static int ierr;
static float e[2], h__;
static int i__, n;
static float p[9], r__[54] /* was [6][9] */, u[9], x[9], y[9], y2[9], pi,
dx[8], pi2;
int i__1, i;
pi = 3.141592f;
pi2 = pi * 2;
n = 9;
h__ = pi2 / (n - 1);
x[0] = 0.f;
u[0] = 0.f;
p[0] = 1.f;
i__1 = n;
for (i__ = 2; i__ <= i__1; ++i__) {
x[i__ - 1] = x[i__ - 2] + h__;
u[i__ - 1] = (float)sin(x[i__ - 1]);
p[i__ - 1] = 1.f;
/* l1: */
}
is02r_c(&n, x, u, p, y, y2, dx, e, r__, &ierr);
printf("\n %5i \n",ierr);
for (i = 0; i <= 6; i += 3) {
printf("\n %16.7e %16.7e %16.7e \n",y[i], y[i+1], y[i+2]);
}
for (i = 0; i <= 6; i += 3) {
printf("\n %16.7e %16.7e %16.7e \n",y2[i], y2[i+1], y2[i+2]);
}
for (i = 0; i <= 4; i += 4) {
printf("\n %16.7e %16.7e %16.7e %16.7e \n",
dx[i], dx[i+1], dx[i+2], dx[i+3]);
}
printf("\n %16.7e %16.7e \n",e[0], e[1]);
return 0;
} /* main */
Результаты:
ierr = 0
y(1) = 0.002020 y2(1) = 0.14309
y(2) = 0.392894 y2(2) = -0.410578
y(3) = 0.555974 y2(3) = -0.588419
y(4) = 0.391777 y2(4) = -0.417586
y(5) = -0.004407 y2(5) = 0.001235
y(6) = -0.399604 y2(6) = 0.423318
y(7) = -0.558361 y2(7) = 0.603963
y(8) = -0.380293 y2(8) = 0.437473
y(9) = 0.002020 y2(9) = 0.014309
dx(i) = 0.785398 , i = 1, 2, ..., 8
e(1) = 1.009781
e(2) = 0.087973