Автор cайта:
Владимир
Потемкин

fortran-90@yandex.ru
Язык программирования Фортран

Интерполяция, сглаживание и аппроксимация

>PL10. Вычисление значения функции с помощью интерполяционного процесса Эйткена-Лагранжа.

>PL12. Вычисление значения функции с помощью интерполяционного процесса Эйткена-Эрмита.

>SPL. Вычисление коэффициентов кубического интерполяционного сплайна.

>SPS. Вычисление коэффициентов кубического сглаживающего сплайна.

>Hermite. Построение аппроксимирующей кирвой Эрмита.

>ORT. Аппроксимация функциональной зависимости полиномом заданной степени.

PL10

Программа PL10 вычисляет значение функции y(x) в заданной точке x с помощью интерполяционного процесса Эйткена-Лагранжа.
Функция y(x) задана таблично массивами Xi и Yi, i=1, 2, ..., n. Массив Xi должен быть упорядочен в возрастающем порядке, т.е. для всех его элементов xi<xi+1. Максимальное число узлов m, используемых для интерполяции, задается при вызове программы.
Процесс интерполяции построен по итерационной схеме. В качестве первого приближения используется значение функции в ближайшем узле интерполяции. Для получения более точных приближений используются последовательно вычисляемые значения многочлена Лагранжа L(k)(x), степень которого возрастает на каждом шаге итерации:

formula

где ω(k)(x) = (x-x1)(x-x2) ... (x-xk+1), k=1, 2, ..., n-1. Итерационный процесс продолжается до получения заданной точности интерполяции.
Вычисления проводятся по треугольной интерполяционной схеме Эйткена:
x1   y1
x2   y2   L12
x3   y3   L13   L123
x4   y4   L14   L124  L1234
. . . . . . . . . . . . . . . . . .
xm   ym   L1m   L12m  L123m ... L123...m
Каждый многочлен Лагранжа более высокой степени получается из двух предыдущих многочленов по рекуррентным формулам:

formula

formula

Элементы L12...k нисходящей диагонали этой схемы представляют собой интерполяционные многочлены Лагранжа L(k)(x) последовательно возрастающих степеней (k=2, ..., m).
Для определения значений многочлена L(k)(x) при росте k в вычислительный процесс вовлекаются все более удаленные от x узлы интерполяции. Поэтому значения xk и yk (k=1, 2, ..., m) предварительно упорядочиваются таким образом, чтобы модули разностей |xk - x| возрастали при росте индекса k:
|xk - x| ≤ |xk+1 - x|.

 

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

CALL PL10(X, Y, XX, M, Eps, YY, Error)

Параметры программы

X, Y, XX, M, Eps - входные параметры;
YY, Error - выходные параметры;

Real X(1:N), Y(1:N) - массивы, содержащие значения аргумента и функции. Массив X должен быть упорядочен в возрастающем порядке;
Real XX - значение аргумента, в котором требуется вычислить значение функции;
Integer M - число узлов, которое разрешается использовать при интерполяции, 1<=M<=N;
Real Eps - погрешность, с которой требуется вычислить значение функции, X[1]<=XX<=X[N];
Real YY - значение функции, вычисляемое программой;
Integer Error - индикатор ошибки, принимающий при выполнении программы одно из следующих значений:
Error=0 - заданная точность интерполяции достигнута, ошибок нет;
Error=1 - заданная точность не достигается или достигнутая точность не может быть проверена, т.к. мало значение M;
Error=2 - заданная точность не достигается из-за роста вычислительной погрешности или плохого поведения старших производных интерполируемой функции.

 

Пример

! Интерполяция функции многочленом Лагранжа
! по интерполяционной схеме Эйткена.
program TestPL10
use NML
implicit none
integer, parameter:: n=40
real:: X(n), Y(n), XX, YY, YE, Eps
integer:: M, Er
integer i
!begin
  M=6
  Eps=1.E-6
  do i=1, n
    X(i)=0.5*float(i-1)
    Y(i)=exp(-X(i))*sin(X(i))
  end do
  XX=4.2
  ! YE - точное значение по формуле
  YE=exp(-XX)*sin(XX)
  ! YY - значение, полученное интерполяцией
  call PL10(X, Y, XX, M, Eps, YY, Er)
  print 10, Er
  print 11, XX, YE, YY
10 format(/'     Error =',I2/)
11 format('   X = ',F6.2,'   YE =',F11.6,'   YY =',F11.6/)
end program TestPL10
────────────

     Error = 1

   X =   4.20   YE =  -0.013070   YY =  -0.013074

 

Вернуться к оглавлению    Скачать PL10

PL12

Программа PL12 вычисляет значение функции y(x) в заданной точке x с помощью интерполяционного процесса Эйткена-Эрмита.
Функция y(x) задана таблично массивами Xi и Yi, i=1, 2, ..., n. Массив Xi должен быть упорядочен в возрастающем порядке, т.е. для всех его элементов xi<xi+1. Максимальное число узлов m, используемых для интерполяции, задается при вызове программы.
Процесс интерполяции построен по итерационной схеме. В качестве первого приближения используется интерполяционный многочлен Эрмита первой степени. На каждой новой итерации степень многочлена увеличивается на 1. Итерационный процесс продолжается до получения заданной точности.
Для построения многочленов Эрмита нечетной степени 2k-1 используются значения функции и ее производной во всех k узлах, для построения многочленов четной степени 2k используется значение функции в k узлах и значение производной в k-1 узле.
Вычисления производятся по треугольной итерационной схеме Эйткена:
x1   y1   V1   V12   V13   V14   V15  ... V1,2m-1
     y1'  V2   V23   V24   V25   ...
x2   y2   V3   V34   V35   ...
     y2'  V4   V45   ...
x3   y3   V5   ...
     y3'  ...
. . . . . . . . . . . . . . . . . .
xm   ym   V2m-1
     ym'
Элементы V1, V12, ..., V2m-1 первой строки этой схемы представляют собой значения многочленов Эрмита последовательно возрастающих степеней:
V1 = H(1)(x), V12 = H(2)(x), ..., V1,2n-1 = H(2m-1)(x).
Элементы первого столбца V1, V2, ..., V2m-1 вычисляются по формулам:
Vi = yj + yj'(x - xj)
Vi+1 = yj + (yj+1 - yj)[(x - xj)/(xj+1 - xj)],
где i=1, 3, 5, ..., 2m-1, и j=(i+1)/2. Остальные элементы этой схемы вычисляются (вверх по диагонали) по следующей рекуррентной формуле:

formula
где j=(i+1)/2, l=(k+3)/2.
Для определения значений многчлена H(k)(x) при росте k в вычислительный процесс вовлекаются все более удаленные от x узлы интерполяции. Поэтому значения xk, yk и yk' (k=1, 2, ..., m) предварительно упорядочиваются таким образом, чтобы модули разностей |xk - x| возрастали при росте индекса k:
|xk - x| ≤ |xk+1 - x|.

 

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

CALL PL12(X, Y, DY, XX, M, Eps, YY, Error)

Параметры программы

X, Y, DY, XX, M, Eps - входные параметры;
YY, Error - выходные параметры;

Real X(1:N), Y(1:N), DY(1:N) - массивы, содержащие значения аргумента, функции и производной. Массив X должен быть упорядочен в возрастающем порядке;
Real XX - значение аргумента, в котором требуется вычислить значение функции;
Integer M - число узлов, которое разрешается использовать при интерполяции, 1<=M<=N;
Real Eps - погрешность, с которой требуется вычислить значение функции, X[1]<=XX<=X[N];
Real YY - значение функции, вычисляемое программой;
Integer Error - индикатор ошибки, принимающий при выполнении программы одно из следующих значений:
Error=0 - заданная точность интерполяции достигнута, ошибок нет;
Error=1 - заданная точность не достигается или достигнутая точность не может быть проверена, т.к. мало значение M;
Error=2 - заданная точность не достигается из-за роста вычислительной погрешности или плохого поведения старших производных интерполируемой функции.

 

Пример

! Интерполяция функции многочленом Эрмита
! по интерполяционной схеме Эйткена.
program TestPL12
use NML_PL12
implicit none
integer, parameter:: n=40
real:: X(n), Y(n), DY(n), XX, YY, YE, Eps
integer:: M, Er
integer i
!begin
  M=6
  Eps=1.E-8
  do i=1, n
    X(i)=0.5*float(i-1)
    Y(i)=exp(-X(i))*sin(X(i))
    DY(i)=exp(-X(i))*(-sin(X(i))+cos(X(i)))
  end do
  XX=5.2
  YE=exp(-XX)*sin(XX)
  call PL12(X, Y, DY, XX, M, Eps, YY, Er)
  print 10, Er
  print 11, XX, YE, YY
10 format(/'     Error =',I2/)
11 format('   X = ',F6.2,'   YE =',F11.6,'   YY =',F11.6/)
end program TestPL12
────────────

     Error = 0

   X =   5.20   YE =  -0.004874   YY =  -0.004874

 

Вернуться к оглавлению    Скачать PL12

SPL

Программа SPL вычисляет коэффициенты кубического интерполяционного сплайна для функциональной зависимости yi = y(xi), i=1, 2, ..., n. Кубический сплайн представляет собой многочлен третьей степени на каждом из отрезков [xi, xi+1], i=1, 2, ..., n-1:
│s1(x) = y1 + b1(x - x1) + c1(x - x1)2 + d1(x - x1)3
│ . . . . . . . . . . . . . . . . . . . .(1)
│sn-1(x) = yn-1 + bn-1(x - xn-1) + cn-1(x - xn-1)2 + dn-1(x - xn-1)3

Для нахождения коэффициентов сплайна bi, ci, di используют условия сшивания для самих многочленов и для их первой и второй производной в точке xi:

│s1(x2) = y1 + b1h1 + c1h12 + d1h13 = y2
│ . . . . . . . . . . . . . . . . . . . .(2)
│sn-1(xn) = yn-1 + bn-1hn-1 + cn-1hn-12 + dn-1hn-13 = yn

│s1'(x2) = s2'(x2)
│ . . . . . . . . . . .(3)
│sn-2'(xn-1) = sn-1'(xn-1)

│s1"(x2) = s2"(x2)
│ . . . . . . . . . . .(4)
│sn-2"(xn-1) = sn-1"(xn-1)

где h1 = x2 - x1, ..., hn-1 = xn - xn-1. Из (4) получаем:

│c1 + 3d1h1 = c2
│ . . . . . . .
│cn-2 + 3dn-2hn-2 = cn-1

и дополняем уравнением cn-1 + 3dn-1hn-1 = cn. Вводим обозначения

│c1 = 3σ1
│ . . .
│cn = 3σn

│∆1 = (y2 - y1)/h1
│ . . . . . . .
│∆n-1 = (yn - yn-1)/hn-1

Имеем с помощью (2):

│bi = ∆i - hii+1 + 2σi)
│ci = 3σi i=1, ..., n-1
│di = (σi+1 - σi)/hi

Подставляем в (3) с учетом (2):

│h1σ1 + 2(h1 + h22 + h2σ3 = ∆2 - ∆1
│h2σ2 + 2(h2 + h33 + h3σ4 = ∆3 - ∆2
│ . . . . . . . . . . . . . . . . . . . .(5)
│hn-3σn-3 + 2(hn-3 + hn-2n-2 + hn-2σn-1 = ∆n-2 - ∆n-3
│hn-2σn-2 + 2(hn-2 + hn-1n-1 + hn-1σn = ∆n-1 - ∆n-2

Мы получили систему из n-2 уравнений и n неизвестных.
Дополним полученную систему (5) уравнениями s1"(x1) = 0 и sn-1"(xn) = 0, или, что то же самое, σ1n=0. Тогда получаем полную систему для определения неизвестных bi, ci, di коэффициентов сплайна (1). Матрица полученной системы является симметричной и с диагональным преобладанием.
Построенный сплайн минимизирует функционал
b
J(s) = (s"(x))2dx,
a
где a=x1,  b=xn.
Применение краевых условий s1"(x1)=0 и sn-1"(xn)=0 не является оптимальным, поскольку в этом случае значение сплайна вблизи граничных точек может сильно отличаться от значения интерполируемой функции. Поэтому в программе применяются следующие типы краевых условий:
   - краевые условия 1-го типа. s'(a) = y'(a), s'(b) = y'(b) - на концах промежутка [a,b] задаются значения 1-ой производной интерполируемой функции;
   - краевые условия 2-го типа. s"(a) = y"(a), s"(b) = y"(b) - на концах промежутка [a,b] задаются значения 2-ой производной интерполируемой функции;
   - краевые условия 3-го типа. s'(a) = s'(b), s"(a) = s"(b) - периодические краевые условия, которые применяются в случае, если интерполируемая функция является периодической с периодом T=b-a;
   - краевые условия 4-го типа. Применяются, когда неизвестны ни первые, ни вторые производные в граничных точках и функция не является периодической. В этом случае недостающие два уравнения получаются из аппроксимации третьих производных на концах промежутка по четырем первым и четырем последним из заданных точек.
Недостающие уравнения выглядят следующим образом:
для краевых условий 1 типа
2h1σ1 + h1σ2 = ∆1 - y'(x1),
hn-1σn-1 + 2hn-1σn = y'(xn) - ∆n-1;
для краевых условий 2 типа
1 = y"(x1), n = y"(xn);
для краевых условий 3 типа
2(h1 + hn-11 + h1σ2 + hn-1σn-1 = ∆1 - ∆n-1,
σ1 = σn;
для краевых условий 4 типа
-h1σ1 + h1σ2 = h121(3),
hn-1σn-1 - hn-1σn = hn-12n-3(3),
где 1(3) = [(∆3 - ∆2)/(x4 - x2) - (∆2 - ∆1)/(x3 - x1)]/(x4 - x1), n-3(3) = [(∆n-1 - ∆n-2)/(xn - xn-2) - (∆n-2 - ∆n-3)/(xn-2 - xn-3)]/(xn - xn-3) - аппроксимации третьих производных.

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

CALL SPL(X, Y, ib, D1, DN, B, C, D)

Параметры программы

X, Y, ib, D1, DN - входные параметры;
B, C, D - выходные параметры.

Real X(1:N), Y(1:N) - массивы, содержащие значения аргумента и функции. Массив X должен быть упорядочен в возрастающем порядке;
Integer Ib - параметр, который задает тип граничных условий, 1<=Ib<=4;
Real D1, DN - значения этих параметров используются в граничных условиях 1 и 2 типа;
Real B(1:N), C(1:N), D(1:N) - массивы, содержащие коэффициенты сплайна;
При работе программы SPL используется программа LA30.

 

Вернуться к оглавлению    Скачать SPL

SPF

Программа SPF вычисляет значение интерполяционного (SPL) или сглаживающего (SPS) сплайна в заданной точке X.
Для поиска прмежутка [xi..xi+1], в который попадает точка X, применяется двоичный поиск. Программа запоминает во внутренней переменной L номер промежутка, в котором вычислялся сплайн при предыдущем вызове. Если при последующем вызове точка X попадает в тот же промежуток, то новый промежуток можно не искать и сплайн вычисляется быстрее.

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

CALL SPF(X, Y, B, C, D, XX, Id)

Параметры программы

X, Y, B, C, D, XX, Id - входные параметры;
Real Spf - возвращаемое значение.

Real X(1:N), Y(1:N) - массивы, содержащие значения аргумента и функции;
Real B(1:N), C(1:N), D(1:N) - массивы, содержащие значения коэффициентов сплайна;
Real XX - значение аргумента, в котором требуется вычислить значение функции;
Integer Id - параметр, задающий режим вычисления:
id=0 - программа вычисляет значение функции;
id=1 - программа вычисляет значение первой производной;
id=2 - программа вычисляет значение второй производной.

 

Пример

!Сплайн - интерполяция
program TestSPL
use NML
implicit none
integer, parameter:: n=60
real:: X(n), Y(n), B(n), C(n), D(n), XX, YY, YD, SY, SD
real, parameter:: pi=3.14159265359
integer:: ib=4
real:: H, D1, DN
integer i
!begin
  H=2.0*pi/float(n-1)
  do i=1, n
    X(i)=H*float(i-1)
    Y(i)=exp(-X(i))*sin(X(i))
  end do
  XX=1.2
  YY=exp(-XX)*sin(XX)
  YD=exp(-XX)*(cos(XX)-sin(XX))
  if (ib==1) then
    D1=1.0            ! D1=exp(0)*(cos(0)-sin(0))
    DN=exp(-2.*pi)    ! DN=exp(-2pi)*(cos(2pi)-sin(2pi))
  else if (ib==2) then
    D1=-2.0             ! D1=-2*exp(0)*cos(0);
    DN=-2.*exp(-2.*pi)  ! DN=-2*exp(-2pi)*cos(2pi)
  else
    D1=0.0; DN=0.0
  end if
  call SPL(X, Y, ib, D1, DN, B, C, D)
  SY=SPF(X, Y, B, C, D, XX, 0)
  SD=SPF(X, Y, B, C, D, XX, 1)
  print 10, XX, YY, YD
  print 11, SY, SD
10 format(/'   X = ',F6.2,'   YY =',F12.7,'   YD =',F12.7)
11 format(/16x,'SY =',F12.7,'   SD =',F12.7)
end program TestSPL

   X =   1.20   YY =   0.2807248   YD =  -0.1715847

                SY =   0.2807250   SD =  -0.1715749

 

Вернуться к оглавлению    Скачать SPF

SPS

Программа SPS вычисляет коэффициенты кубического сглаживающего сплайна для функциональной зависимости yi = y(xi), i=1, 2, ..., n. Предполагается, что точные значения yi неизвестны, а заданы с некоторой погрешностью ρi, 0 ≤ ρi ≤ 1. В случае, если все ρi=0, то коэффициенты ai совпадают с yi и сглаживающий сплайн превращается в интерполяционный. Это означает, что чем точнее заданы величины yi, тем меньше должны быть соответствующие значения ρi. Если же требуется, чтобы сплайн прошел в точности через точку (xi,yi), то соответствующую ей погрешность ρi следует положить равной нулю.
Кубический сплайн представляет собой многочлен третьей степени на каждом из отрезков [xi, xi+1], i=1, 2, ..., n-1:
si(x) = ai + bi(x - xi) + ci(x - xi)2 + di(x - xi)3.
Для нахождения коэффициентов сплайна ai, bi, ci, di используются условия сшивания для самих многочленов и для их первой и второй производной в точках xi:

│s1(x2) = a1 + b1h1 + c1h12 + d1h13 = s2(x2) = a2
│ . . . . . . . . . . . . . . . . . . . .
│sn-1(xn) = an-1 + bn-1hn-1 + cn-1hn-12 + dn-1hn-13 = sn(xn) = an

│s1'(x2) = b1 + 2c1h1 + 3d1h12 = s2'(x2) = b2
│ . . . . . . . . . . . . . . . . . . . .
│sn-2'(xn-1) = bn-2 + 2cn-2hn-2 + 3dn-2hn-22 = sn-1'(xn-1) = bn-1

│s1"(x2) = 2c1 + 6d1h1 = s2"(x2) = 2c2
│ . . . . . . . . . . . . . . . . . . . .
│sn-2"(xn-1) = 2cn-2 + 6dn-2hn-2 = sn-1"(xn-1) = 2cn-1

где h1 = x2 - x1, ..., hn-1 = xn - xn-1. Дополнительно n уравнений получают из условия минимизации функционала
bn
J(s) = (s"(x))2dx + (1/ρi)(si - yi)2,    x1=a,   xn=b,
ai=1
которые имеют вид [Б5]:

│s1(x1) + ρ1s1'''(x1+) = y1
│s2(x2) + ρ2(s2'''(x2+) - s2'''(x2-)) = y2
│ . . . . . . . . . . . . . . . . . . . .
│sn-1(xn-1) + ρn-1(sn-1'''(xn-1+) - sn-1'''(xn-1-)) = yn-1
│sn(xn) - ρnsn'''(xn-) = yn

где si'''(xi+) и si'''(xi-) означают третью производную в точке xi справа и слева.
   Введя обозначения
│c1 = 3σ1
│ . . .
│cn = 3σn

│∆1 = (y2 - y1)/h1
│ . . . . . . .
│∆n-1 = (yn - yn-1)/hn-1

и выполнив элементарные преобразования (см. прогр. SPL), получаем следующую систему уравнений:

│D2σ1 + A2σ2 + B2σ3 + C2σ4 = G2
│E3σ1 + D3σ2 + A3σ3 + B3σ4 + C3σ5 = G3
│ . . . . . . . . . . . .(*)
│En-2σn-4 + Dn-2σn-3 + An-2σn-2 + Bn-2σn-1 + Cn-2σn = Gn-2
│En-1σn-3 + Dn-1σn-2 + An-1σn-1 + Bn-1σn = Gn-2
где
Ai = 2(hi-1 + hi) + pi-1/(hi-1)2 + pi(1/hi-1 + 1/hi)2 + pi+1/(hi)2,   i=2, ..., n-1
Bi = hi - (1/hi)[pi(1/hi-1 + 1/hi) + pi+1(1/hi + 1/hi+1)],   i=2, ..., n-2
Bn-1 = hn-1 - (1/hn-1)[pn-1(1/hn-2 + 1/hn-1) + pn/hn-1]
Ci = pi+1/(hihi+1),   i=2, ..., n-2
D2 = h1 - (1/h1)[p1/h1 + p2(1/h1 + 1/h2)]
Di = hi-1 - (1/hi-1)[pi-1(1/hi-2 + 1/hi-1) + pi(1/hi-1 + 1/hi)],   i=3, ..., n-1
Ei = pi-1/(hi-2hi-1),   i=3, ..., n-1
Gi = ∆i - ∆i-1,   i=2, ..., n-1
Здесь pi = 6ρi.
Мы получили систему n-2 уравнений относительно n неизвестных. Недостающие два уравнения получаются из того или иного типа краевых условий.
   Краевые условия 1-го типа. s'(a)=y'(a), s'(b)=y'(b) - на концах промежутка [a,b] задаются значения 1-ой производной сглаживаемой функции.
   Краевые условия 2-го типа. s"(a)=y"(a), s"(b)=y"(b) - на концах промежутка [a,b] задаются значения 2-ой производной сглаживаемой функции.
   Краевые условия 3-го типа. s(a)=s(b), s'(a)=s'(b), s"(a)=s"(b) - периодические краевые условия, которые применяются в случае, если сглаживаемая функция является периодической с периодом T=b-a.
Если значения ни первых, ни вторых производных на концах промежутка не известны и функция не является периодической, то следует положить s"(a)=s"(b)=0, в этом случае достигается эффект наилучшего сглаживания исходной таблично-заданной зависимости.
Недостающие уравнения выглядят следующим образом.
Для краевых условий 1-го и 2-го типа:

│A1σ1 + B1σ2 + + C1σ3 = G1
│Enσn-2 + Dnσn-1 + Anσn = Gn

Значения коэффициентов для краевых условий первого типа:

A1 = 2h1 + (p1 + p2)/(h1)2
B1 = h1 - p1/(h1)2 - p2(1/h1)(1/h1) + 1/h2)
C1 = p2/(h1h2)
En = pn-1/(hn-2hn-1)
Dn = hn-1 - pn-1(1/hn-1)(1/hn-2) + 1/hn-1) - pn/(hn-1)2
An = 2hn-1 + (pn-1 + pn)/(hn-1)2
G1 = ∆1 - y'(a),   Gn = y'(b) - ∆n-1.

Значения коэффициентов для краевых условий второго типа:

A1=An=6,   B1=C1=En=Dn=0,   G1=y"(a),   Gn=y"(b).

Краевые условия 3-го типа образуют сисему n-1 уравнений относительно n-1 неизвестного, поскольку в этом случае σ1n.
│A1σ1 + B1σ2 + C1σ3 + E1σn-1 + D1σn = G1
│D2σ1 + A2σ2 + B2σ3 + C2σ4 + E2σn = G2
│E3σ1 + D3σ2 + A3σ3 + B3σ4 + C3σ5 = G3
│ . . . . . . . . . . . . . . . .
│En-3σn-5 + Dn-3σn-4 + An-3σn-3 + Bn-3σn-2 + Cn-3σn-1 = Gn-3
│Cn-2σ1 + En-2σn-4 + Dn-2σn-3 + An-2σn-2 + Bn-2σn-1 + = Gn-2
│Bn-1σ1 + Cn-1σ2 + En-1σn-3 + Dn-1σn-2 + An-1σn-1 = Gn-1,

где
A1 = 2(hn-1 + h1) + pn-1/(hn-1)2 + p1(1/hn-1 + 1/h1)2 + p2/(h1)2,
An-1 = 2(hn-2 + hn-1) + pn-2/(hn-2)2 + pn-1(1/hn-2 + 1/hn-1)2 + p1/(hn-1)2,
B1 = h1 - (1/h1)[p1(1/hn-1 + 1/h1) + p2(1/h1 + 1/h2)],
Bn-1 = hn-1 - (1/hn-1)[pn-1(1/hn-2 + 1/hn-1) + p1(1/hn-1 + 1/h1)],
C1 = p2/(h1h2), Cn-1 = p1/(hn-1h1),
Ai, Bi, Ci,   i=2, ..., n-2 совпадает с (*),
D1 = Bn-1, D2 = B1, E1 = Cn-2, E2 = Cn-1,
Di+1 = Bi, Ei+1 = Ci-1,   i=2, ..., n-2.

Коэффициенты сплайна находятся из уравнений:

│ai = yi - ρiHi
│bi = ∆i - hii+1 + 2σi) - (1/hi)(pi+1Hi+1 - piHi)
│ci = 3σi
│di = (σi+1 - σi)/hi,   i=1, ..., n-1,
an = yn - ρnHn,
где H1 = (σ2 - σ1)/h1,   Hi = (σi+1 - σi)/hi - (σi - σi-1)/hi-1   i=2, ..., n-1,   Hn = (σn - σn-1)/hn.

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

CALL SPS(X, Y, P, ib, D1, DN, A, B, C, D)

Параметры программы

X, Y, P, ib, D1, DN - входные параметры;
A, B, C, D - выходные параметры.

Real X(1:N), Y(1:N) - массивы, содержащие значения аргумента и функции. Массив X должен быть упорядочен в возрастающем порядке;
Real P(1:N) - массив, содержащий значения весовых коэффициентов, 0<=P(i)<=6. Значение P(i) должно быть равно 0, если значение ординаты Y(i) известно точно и должно равняться 6, если значение Y(i) нужно игнорировать;
Integer Ib - параметр, который задает тип граничных условий, 1<=Ib<=4;
Real D1, DN - значения этих параметров используются в граничных условиях 1 и 2 типа;
Real A(1:N), B(1:N), C(1:N), D(1:N) - массивы, содержащие коэффициенты сплайна;
При работе программы SPS используется программа LA31.

 

Пример

! Построение сглаживающего сплайна
! и графика сглаженной функции.

module SplPar
integer, parameter:: n=20
real:: X(n), Y(n), P(n), A(n), B(n), C(n), D(n)
integer:: ib
real:: D1, DN
end module SplPar

program TestSPS
$objcomment lib: "D:/Fortran/Bib_GR/Debug/Graphica"
use SplPar
use NML
implicit none
real, parameter:: pi=3.14159265359
integer:: seed(1)
real:: Q(n)
real:: H, AX=0.0, BX=2.0*pi
real, external:: FS
integer i, j
!begin
  ib=2
  P(:)=0.4
  seed(1)=6
  call random_seed(put=seed)
  call random_number(Q)

  H=(BX-AX)/float(n-1)
  do i=1, n
    X(i)=H*float(i-1)
    Y(i)=sin(X(i))+0.2*(Q(i)-0.5)
  end do

  if (ib==1) then
    D1=1.0
    DN=1.0
  else if (ib==2) then
    D1=0.0
    DN=0.0
  else
    D1=0.0; DN=0.0
  end if

  call SPS(X, Y, P, ib, D1, DN, A, B, C, D)
  call Graphic(X(1), X(n), FS)
  !график выведен в файл 'gf.txt'

end program TestSPS

real function FS(XX)
use SplPar
use NML
real, intent(in):: XX
  FS=SPF(X, A, B, C, D, XX, 0)
  return
end

 

Вернуться к оглавлению    Скачать SPS

Hermite

Задано некоторое множество точек (вершин) P1 ... Pn на плоскости или в пространстве, n>1. Программа Hermite строит составную аппроксимирующую кривую Эрмита γ(1)ᑌ ... ᑌγ(n), которая является объединением элементарных кубических кривых γ(i), i = 1, ..., n-1. Элементарная кубическая кривая Эрмита определяется двумя вершинами Pi и Pi+1 и ненулевыми касательными векторами в этих точках Qi и Qi+1 (Рис 1).

Кубическая кривая Эрмита

Координаты точек кривой между вершинами Pi и Pi+1 можно найти из векторного уравнения

R(t) = (1 - 3t2 + 2t3) Pi + t2(3 - 2t) Pi+1 + t(1 - 2t + t2) Qi - t2(1 - t) Qi+1, 0 ≤ t ≤ 1

Это уравнение в координатной (матричной) форме может быть записано как

R(t) = GMT, 0 ≤ t ≤ 1

где (для точек P1 и P2)

Кривая Эрмита в координатной форме

Матрица M называется базисной матрицей кубической кривой Эрмита, а матрица G - её геометрической матрицей. Здесь x, y и z - пространственные координаты вершин P1 и P2, u, v, w - координаты касательных векторов Q1 и Q2.

Составная кривая Эрмита

Составная кривая Эрмита (Рис. 2) является объединением элементарных кривых Эрмита и определяется массивом вершин P1 ... Pn, n>1. Каждая i-ая кривая описывается уравнением

R(i)(t) = (Pi Pi+1 Qi Qi+1)MT, 0 ≤ t ≤ 1

где M - базисная матрица, а промежуточные векторы Q2 ... Qn-1 можно найти из условий равенства вторых производных в базисных точках P2 ... Pn-1, которые сводятся к матричному уравнению

Система для вторых производных

Свойства составной кривой Эрмита описаны в [Б5].

Программная реализация

Для начала вычислений нужно задать вершины, через которые должна пройти кривая, и векторы касательных в конечных вершинах. Программа HermiteTangents вычисляет значения касательных в промежуточных вершинах. Программа Hermite вычисляет координаты заданной точки на построенной кривой. Точка на кривой задаётся параметром t, который должен лежать в пределах от 0 до n-1. Целая часть параметра определяет номер i элементарной кривой Эрмита, а дробная часть задаёт положение точки на этой кривой.

[Б5]

 

Вызов программы HermiteTangents

call HermiteTangents(XP, xq1, xqN, XQ)

Параметры программы

XP(1:n), xq1, xqN - входные параметры;
XQ(1:n) - выходной параметр.

Real XP(1:n) - массив, содержащий x-, y- или z-координаты точек Pi, i=1, ..., n;
Real xq1, xqN - x-, y- или z-координаты касательных векторов в точках P1 и Pn:
Real XQ(1:n) - массив, содержащий x-, y- или z-координаты касательных векторов Qi в точках Pi, i=1, ..., n;
integer n - задаёт количество точек P и размерность массивов XP и XQ;

 

Вызов программы Hermite

Hermite(XP, XQ, t)
Программа Hermite должна быть вызвана после вызова программы HermiteTangents

Параметры программы

XP(1:n), XQ(1:n), t - входные параметры;
Real Hermite - возвращаемое значение;

Real XP(1:n) - массив, содержащий x-, y- или z-координаты точек Pi, i=1, ..., n;
Real XQ(1:n) - массив, содержащий x-, y- или z-координаты касательных векторов Qi в точках Pi, i=1, ..., n (вычислены с помощью программы HermiteTangents);
integer n - задаёт количество точек P и размерность массивов XP и XQ;
Real t - значение параметра, в котором нужно найти x-, y- или z-координату составной кривой Эрмита, 0 ≤ t ≤ n-1

 

Примеры

program TestHermit
! Построение аппроксимирующей кривой Эрмита
use GRAPHICA
use NML
implicit none

    integer, parameter:: n=8, div=32
    real XP(n), YP(n), XQ(n), YQ(n), xq1, yq1, xqN, yqN
    real T(div), XT(div), YT(div), dt
    integer i
    data XP/0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.80, 0.95/
    data YP/0.90, 0.50, 0.40, 0.50, 0.25, 0.10, 0.50, 0.90/
    data xq1/0.1/, yq1/-0.02/, xqN/0.1/, yqN/0.01/
    ! Вычисление X и Y координат касательных во внутренних точках
    call HermiteTangents(XP, xq1, xqN, XQ)
    call HermiteTangents(YP, yq1, yqN, YQ)
    ! Заполнение массива с параметром
    dt=float(n-1)/float(div)
    do i=1,div
        T(i)=(i-1)*dt
    enddo
    ! Построение аппроксимирующей кривой
    do i=1,div
        XT(i)=Hermite(XP, XQ, T(i))
        YT(i)=Hermite(YP, YQ, T(i))
    enddo
    ! Вывод результатов вычислений
    print 10
    print 11, (T(i), XT(i), YT(i), i=1, div)
    call Graphar(XT, YT)
10  format(8X,'t',10X,'x',14X,'y')
11  format(2X,F10.7,2E15.7)

end program TestHermit

График построен программой Advanced Grapher

график аппроксимации

program TestHermit2
! Построение кривой Эрмита c самопересечением
use GRAPHICA
use NML
implicit none

    integer, parameter:: n=8, div=64
    real XP(n), YP(n), XQ(n), YQ(n), xq1, yq1, xqN, yqN
    real T(div), XT(div), YT(div), dt
    integer i
    data XP/0.10, 0.30, 0.50, 0.70, 0.95, 0.70, 0.40, 0.10/
    data YP/0.30, 0.50, 0.65, 0.55, 0.45, 0.30, 0.30, 0.45/
    data xq1/0.05/, yq1/0.02/, xqN/-0.05/, yqN/-0.04/
    call HermiteTangents(XP, xq1, xqN, XQ)
    call HermiteTangents(YP, yq1, yqN, YQ)
    dt=float(n-1)/float(div)
    do i=1,div
        T(i)=(i-1)*dt
        XT(i)=Hermite(XP, XQ, T(i))
        YT(i)=Hermite(YP, YQ, T(i))
    enddo
    ! Вывод результатов вычислений
    print 10
    print 11, (T(i), XT(i), YT(i), i=1, div)
    call Graphar(XT, YT)
10  format(8X,'t',10X,'x',14X,'y')
11  format(2X,F10.7,2E15.7)

end program TestHermit2

 

Вернуться к оглавлению    Скачать Hermite

ORT

Программа ORT осуществляет разложение таблично-заданной зависимости yi=y(xi), i=1, ..., n в ряд по системе многочленов, ортогональных на множестве точек {xi}:
m
y(x) = αkuk(x),
k=0
где αk - коэффициенты этого разложения, а uk(x) - ортогональные многочлены последовательно возрастающих степеней:
k
uk(x) = βj(k)xj   k=0, ..., m.
j=0
Предполагается, что значения yi заданы с некоторой неопределённостью (с весовыми коэффициентами) pi, 0 < pi ≤ 1. Значение pi=1 означает, что соответствующее значение yi задано точно, и наоборот, чем ближе pi к нулю, тем менее учитывается данная точка при аппроксимации. Весовые коэффициенты легко вычислить, если известна погрешность i величин yi, т.е. yi ± ∆i. Тогда весовые коэффициенты будут равны

pi = 1 - (∆i/∆max),

где max - максимальное значение погрешности.
Система ортогональных многочленов строится по рекуррентному соотношению

A*uk+1(x) = (x-A)uk(x) - Buk-1(x),   u0=0,   u1=1/SQRT(pi),

где A=pixiuk2(xi), B=pixiuk(xi)uk-1(xi). A* находится из условия нормировки
n
piuk+12(xi) = 1.
i=1
Коэффициент разложения αk определяется из формулы
n
αk = piyiuk(xi).
i=1
Программа последовательно увеличивает количество ортогональных многочленов, участвующих в аппроксимации заданной дискретной зависимости y(xi), пока степень старшего многочлена не достигнет заданного значения m (m≥0) или пока из-за накопления вычислительной погрешности среднеквадратичное отклонение

formula
не перестанет уменьшаться. Достигнутая программой степень старшего многочлена возвращается в переменной Order.
Для упрощения дальнейших расчетов коэффициенты всех многочленов при одинаковых степенях x суммируются и результатом выполнения программы является массив коэффициентов c0, c1, ..., COrder. Значение функции в точке x (x1 ≤ x ≤ xn) можно вычислить по формуле
Order
y(x) = ckxk.
k=0
Краткое описание алгоритма построения многочленов, ортогональных на множестве точек, можно найти в [А4]. Данный метод более устойчив к накоплению ошибок вычислений, чем метод наименьших квадратов.

 

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

CALL ORT(X, Y, P, C, M, Order, Sigma)

Параметры программы

X, Y, P, M - входные параметры;
C, Order, Sigma - выходные параметры.

Real X(1:N), Y(1:N) - массивы, содержащие значения аргумента и функции. Массив X должен быть упорядочен в возрастающем порядке;
Real P(1:N) - массив, содержащий значения весовых коэффициентов, 1>=P(i)>0. Значение P(i) должно быть равно 1, если значение ординаты Y(i) известно точно и стремиться к 0, если значение Y(i) можно игнорировать;
Real C(0:M) - массив, содержащий коэффициенты многочлена, аппроксимирующего исходную зависимость;
Integer M - наибольшая степень многочлена, которую разрешается достигнуть программе;
Integer Order - наибольшая степень многочлена, которую удалось достигнуть программе, Order ≤ M;
Real Sigma - среднеквадратичное отклонение, достигнутое при аппроксимации.

 

Пример

! Аппроксимация функции многочленами,
! ортогональными на множестве точек.

module OrtPar
integer, parameter:: M=20
real:: C(0:M)
integer:: Order
end module OrtPar

program TestORT
$objcomment lib: "D:/Fortran/Bib_GR/Debug/Graphica"
use OrtPar
use NML
implicit none
integer, parameter:: n=40
real:: X(n), Y(n), P(n)
data P/n*1.0/
real, external:: OrtPol
real, parameter:: pi=3.1415926
real:: H, XX, YY, YYY, Sigma
integer:: i
!begin
  H=2.0*pi/float(n-1)
  do i=1, n
    X(i)=H*float(i-1)
    Y(i)=sin(X(i))
  end do
  XX=0.5
  YY=sin(XX)
  call ORT(X, Y, P, C, M, Order, Sigma)
  YYY=OrtPol(XX)
  print 10, XX, YY, YYY, Order, Sigma
10 format(/'   X = ',F6.2,'   YY =',F12.7,'   YYY =',F12.7  &
          /'      Order =',I3,'       Sigma =',E15.7/)
  call Graphic(X(1), X(n), OrtPol)
  print 20, (i, C(i), i=0, Order)
20 format(8x,I2,4x,E14.6)

end program TestORT

real function OrtPol(X)
use OrtPar
real, intent(in):: X
real:: S
integer i
S=0.0
do i=Order, 1, -1
  S=(S+C(i))*X
end do
OrtPol=S+C(0)
return
end function OrtPol

   X =   0.50   YY =   0.4794255   YYY =   0.4794317
      Order =  9       Sigma =  0.2819624E-04

         0      0.361258E-05
         1      0.999756E+00
         2      0.152848E-02
         3     -0.170313E+00
         4      0.445399E-02
         5      0.517216E-02
         6      0.138082E-02
         7     -0.574159E-03
         8      0.610403E-04
         9     -0.215886E-05

 

Вернуться к оглавлению    Скачать ORT