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

fortran-90@yandex.ru

Язык программирования Фортран

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

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 - значение аргумента, в котором требуется вычислить значение функции, X[1] <= XX <= X[N];
Integer M - число узлов, которое разрешается использовать при интерполяции, 1 <= M <= N;
Real Eps - погрешность, с которой требуется вычислить значение функции;
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 - значение аргумента, в котором требуется вычислить значение функции, X[1] <= XX <= X[N];
Integer M - число узлов, которое разрешается использовать при интерполяции, 1 <= M <= N;
Real Eps - погрешность, с которой требуется вычислить значение функции;
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 попадает в тот же промежуток, то повторно промежуток можно не искать и сплайн вычисляется быстрее.

Вызов функции

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.

Замечание (Сен.2024) Если ваш компилятор не компилирует строчку call random_seed(put=seed), сделайте в ней вызов функции без аргумента call random_seed().

 

Пример

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

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

SPL1R

Программа SPL1R вычисляет коэффициенты кубического интерполяционного сплайна для функциональной зависимости yi = y(xi), i=1, 2, ..., n, заданной на сетке ω a = x1 < x2 < ... < xn-1 < xn = b. Кубический сплайн представляет собой многочлен третьей степени на каждом из отрезков [xi, xi+1], i=1, 2, ..., n-1. В отличии от программы SPL (см. выше), число величин, определяющих сплайн, равно n+1, а не 4n.
На каждом из промежутков [xi, xi+1], i=1, 2, ..., n-1, интерполяционная сплайн-функция ищется в виде [Б5]:
Si(x) = yi(1-t)2(1+2t) + yi+1t2(3-2t) + sihit(1-t)2 - si+1t2(1-t)
Здесь hi = xi+1 - xi, t = (x - xi)/hi, а числа si i=1, 2, ..., n являются решением системы линейных алгебраических уравнений, вид которой зависит от типа граничных (краевых) условий. Конкретный вид системы уранений для всех типов граничных условий и алгоритм её решения приведён в [Б5].

Граничные (краевые) условия 1-го типа

S'(a) = f'(a), S'(b) = f'(b)
- на концах промежутка [a,b] задаются значения 1-ой производной интерполируемой функции.

Граничные (краевые) условия 2-го типа

S"(a) = f"(a), S"(b) = f"(b)
- на концах промежутка [a,b] задаются значения 2-ой производной интерполируемой функции.

Граничные (краевые) условия 3-го типа

S(a) = S(b), S'(a) = S'(b), S"(a) = S"(b)
- называются периодическими. Выполнения этих условий естественно требовать в тех случаях, когда интерполируемая функция является периодической с периодом T = b-a.

Граничные (краевые) условия 4-го типа

S(3)(x1 - 0) = S(3)(x1 + 0), S(3)(xn-1 - 0) = S(3)(xn-1 + 0)
требуют особого комментария.
  Комментарий. Во внутренних узлах сетки 3-я производная функции S(x), вообще говоря, разрывна. Однако число разрывов 3-й производной можно уменьшить при помощи условий 4-го типа. В этом случае построенный сплайн будет трижды непрерывно дифференцируем на промежутках [x1, x3] и [xn-2, xn].

Окт.2024

 

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

call SPL1R(n,x,y,ind,ib,ax,bx,z,xx,sp,dsp,d2sp)

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

n,x,y,ind,ib,ax,bx,xx - входные параметры;
z - входной и выходной параметр;
sp,dsp,d2sp - выходные параметры.

integer n - число узлов;
real x[1:n] - массив дины n, содержит координаты узлов сетки;
real y[1:n] - массив дины n, содержит значения функции в узлах сетки;
integer ind - режим выполнения; ind=0 - программа вычисляет коэффициенты сплайна, ind=1 - программа вычисляет значение сплайна в заданной точке xx;
integer ib - тип граничных условий на границах x=ax, x=bx; ib = 1..4;
real ax,bx - параметры, задающие граничные значения для условий 1-го и 2-го типа;
real xx - координата точки, в которой будет вычислено значение сплайна;
real z[1:n] - массив дины n, после первого вызова с ind=0 содержит коэффициенты сплайна;
real sp - значение сплайна в точке xx;
real dsp - значение 1-й производной сплайна в точке xx;
real d2sp - значение 2-й производной сплайна в точке xx;
При работе программы SPL1R используется программа LA30.

 

Пример

program Test_SPL1
    use NML, only: LA30, SPL1R
    implicit none

    integer, parameter:: n=21
    real:: x(n), y(n), z(n)
    integer:: ind, ib
    real:: ax, bx, xx, sp, dsp, d2sp
    real, parameter:: pi=3.14159265359
    real:: h, hd2, del0, del1, del2, yy, d1, d2
    integer:: j, nm1
!begin
    ind=0	! вычисляем коэффициенты сплайна
    ! На отрезке [0, 2π] стрлим равномерную сетку из n узлов
    ! и вычисляем значения функции y=sin(x) в этих узлах
    nm1 = n-1
    h=2.0*pi/nm1
    do j=1, n
        x(j)=h*(j-1)
        y(j)=sin(x(j))
    enddo
    ib=1	! граничные условия
    ax=1.0;  bx=1.0	! граничные значения
    call SPL1R(n,x,y,ind,ib,ax,bx,z,xx,sp,dsp,d2sp)
    ! В массиве z коэффициенты сплайна

    ind=1	! вычисляем значение сплайна в точке xx
    ! sp, dsp, d2sp - значения функции, 1-ой и 2-ой производной
    hd2=0.5*h
    del0=0.0;  del1=0.0;  del2=0.0
    ! Строим сетку со смещением на h/2 от исходной
    ! Вычисляем сплайн и производные в новой сетке
    do j=1, nm1
        xx=h*(j-1)+hd2
        yy=sin(xx);  d1=cos(xx);  d2=-yy
        call SPL1R(n,x,y,ind,ib,ax,bx,z,xx,sp,dsp,d2sp)
        if(abs(yy-sp) > del0) del0=abs(yy-sp)
        if(abs(d1-dsp) > del1) del1=abs(d1-dsp)
        if(abs(d2-d2sp) > del2) del2=abs(d2-d2sp)
    enddo
    ! Печать результатов
    print *,' n = ', n
    print *,' Boundary conditions, ib =', ib
    print *,' max|f(x) - S(x)|   = ', del0
    print *,' max|f''(x) - S''(x)| = ', del1
    print *,' max|f"(x) - S"(x)| = ', del2
end program Test_SPL1


  n =           21
  Boundary conditions, ib =           1
  max|f(x) - S(x)|   =    2.56896019E-05
  max|f'(x) - S'(x)| =    2.23517418E-05
  max|f"(x) - S"(x)| =    4.11111116E-03

 

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

SPL2R

Программа SPL2R вычисляет коэффициенты бикубического интерполяционного сплайна для функциональной зависимости zi = f(xi, yj), i=1, 2, ..., m, j=1, 2, ..., n, заданной на прямоугольной сетке ω a = x1 < x2 < ... < xm-1 < xm = b, c = y1 < y2 < ... < yn-1 < yn = d. Алгоритм нахождения коэффициентов интерполяционных сплайн-функций приведён в [Б5].

GRID

При построении интерполяционного бикубического сплайна наиболее часто используются граничные условия следующих 4-х типов.

Граничные (краевые) условия 1-го типа

bondary condition 1

- в граничных узлах сетки ω задаются значения первых частных производных по x и по y интерполируемой функции, а в угловых точках - значения 2-ой смешаной производной. На рисунке жирными точками отмечены внутренние узлы сетки, в которых задаются значения функции S, горизонтальными и вертикальными треугольниками-стелками указаны узлы, в которых задаются значения первых частных производных Sx и Sy соответственно, а ромбиком - значения смешанной производной Sxy.

Граничные (краевые) условия 2-го типа

bondary condition 2

- в граничных узлах сетки ω задаются значения вторых частных производных по x и по y интерполируемой функции, а в угловых точках - значения смешаной производной Sxxyy. На рисунке жирными точками отмечены внутренние узлы сетки, в которых задаются значения функции S, горизонтальными и вертикальными треугольниками-стелками указаны узлы, в которых задаются значения вторых частных производных Sxx и Syy соответственно, а ромбиком - значения смешанной производной Sxxyy.

Граничные (краевые) условия 3-го типа

bondary condition 3

называются периодическими. В этом случае сплайн S(x,y) и его частные производные должны быть двоякопериодическими функциями - с периодом Tx=b-a по переменной x и с пеиодом Ty=d-c по переменной y.

Граничные (краевые) условия 4-го типа

требуют, чтобы на линиях x=x1 и x=xm-1 были непрерывны следующие производные искомого сплайна:

bondary condition 4a

а на линиях y=y1 и y=yn-1 - производные

bondary condition 4b

Замечание Кроме перечисленных, возможны и смешанные граничные условия, относящиеся по разным переменным к разным типам. При этом если, например, по переменной x заданы условия 1-го типа, а по переменной y - 2-го типа, то в вершинах прямоугольника R следует задавать частные проихводные Sxyy и т.д.

Окт.2024

 

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

call SPL2R(m,x,n,y,z,ind,ibx,iby,sl,sr,sd,su,sxy,zx,zy,zxy,xx,yy,spl)

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

m,n,x,y,z,ind,ibx,iby,sl,sr,sd,su,xx,yy - входные параметры;
zx,zy,zxy - входные и выходные параметры;
spl - выходной параметр.

integer m - число узлов сетки по оси x;
real x[1:m] - массив дины m, содержит координаты узлов сетки по оси x;
integer n - число узлов сетки по оси y;
real y[1:n] - массив дины n, содержит координаты узлов сетки по оси y;
real z[1:m*n] - массив дины m*n, содержит значения интерполируемой функции в узлах сетки; значение функции в узле (i,j) находится в элементе z[i+(j-1)*m];
integer ind - режим выполнения; ind=0 - программа вычисляет коэффициенты сплайна, ind=1 - программа вычисляет значение сплайна в заданной точке (xx,yy);
integer ibx - тип граничных условий на границах x=x1, x=xm; ibx = 1..4;
real sl[1:n] - массив дины n, элемент sl[j] содержит значение j-ой частной производной по x в узлах (1,j) для граничных условий 1-го или 2-го типа;
real sr[1:n] - массив дины n, элемент sr[j] содержит значение j-ой частной производной по x в узлах (m,j) для граничных условий 1-го или 2-го типа;
integer iby - тип граничных условий на границах y=y1, y=yn; iby = 1..4;
real sd[1:m] - массив дины m, элемент sd[i] содержит значение i-ой частной производной по y в узлах (i,1) для граничных условий 1-го или 2-го типа;
real su[1:m] - массив дины m, элемент su[i] содержит значение i-ой частной производной по y в узлах (i,n) для граничных условий 1-го или 2-го типа;
real sxy[1:4] - массив дины 4, содержит значения смешанных производных в угловых точках для граничных условий 1-го или 2-го типа;
real zx[1:m*n], zy[1:m*n], zxy[1:m*n] - массивы дины m*n, содержит значения параметров сплайна;
real xx,yy - координаты точки, в которой будет вычислено значение сплайна;
real spl - вычисленное значение сплайна в точке (xx,yy);
При работе программы SPL2R используются программы LA30 и SPL1R.

 

Пример

program Test_SPL2R
	use NML, only: LA30, SPL1R, SPL2R
	implicit none

	integer, parameter:: m=21, n=11, mn=m*n
	real:: x(m), y(n), z(mn)
	integer:: ind, ibx, iby
	real:: sl(n), sr(n), sd(m), su(m), sxy(4)
	real:: zx(mn), zy(mn), zxy(mn), xx, yy, spl
	real, parameter:: pi=3.14159265359
	integer, parameter:: ks=8
	real:: hx, hy, xs(ks), ys(ks), sc(ks), ss(ks), del(ks), hx2, hy2
	integer:: i, j, ihx, ihy, k
!begin
	ind=0	! вычисляем параметры сплайна
	! Вычисляем функцию f(x,y) = sin(x)*sin(y)
	! в прямоугольнике 0≤x≤π, 0≤y≤π/2
	ihx=40;  ihy=40      ! задают шаг сетки
	hx=2.0*pi/ihx;  hy=2.0*pi/ihy
	do i=1, m
		x(i)=hx*(i-1)
	enddo
	do j=1, n
		y(j)=hy*(j-1)
	enddo
	do j=1, n
		do i=1, m
			z(i+(j-1)*m)=sin(x(i))*sin(y(j))
		enddo
	enddo

	ibx=1; iby=1	! граничные условия
	do i=1, m
		sd(i)=sin(x(i));  su(i)=0.0
	enddo
	do j=1, n
		sl(j)=sin(y(j));  sr(j)=-sin(y(j))
	enddo
	sxy(1)=1.0;  sxy(2)=-1.0;  sxy(3)=0.0;  sxy(4)=0.0;

	call SPL2R(m,x,n,y,z,ind,ibx,iby,sl,sr,sd,su,sxy,zx,zy,zxy,xx,yy,spl)

	ind=1	! вычисляем значение сплайна в точке xx
	! xs и ys - координаты точек между узлами сетки
	hx2=0.5*hx;  hy2=0.5*hy
	do k=1, ks
		xs(k)=pi/2+hx2+hx*k;  ys(k)=hy2+hy*k
		sc(k)=sin(xs(k))*sin(ys(k))
		call SPL2R(m,x,n,y,z,ind,ibx,iby,sl,sr,sd,su,sxy,zx,zy,zxy,xs(k),ys(k),ss(k))
		del(k)=ss(k)-sc(k)
	enddo

	! Печать результатов
	print 10, m, n
	print 11, ibx, iby
	print 12
	print 13, (xs(k),ys(k),sc(k),ss(k),del(k), k=1,ks)
10	format(/4x,'m =',I4,'    n =',I4)
11	format(4x,'Boundary conditions, ibx =',I3,'    iby =',I3)
12	format(6x,'X',9x,'Y',9x,'Exact',11x,'Spline',10x,'Delta')
13	format(2F10.5,3E16.7)
end program Test_SPL2R

    m =  21    n =  11
    Boundary conditions, ibx =  1    iby =  1
      X         Y         Exact           Spline          Delta
   1.80642   0.23562   0.2269953E+00   0.2269945E+00  -0.7450581E-06
   1.96350   0.39270   0.3535534E+00   0.3535523E+00  -0.1162291E-05
   2.12058   0.54978   0.4455032E+00   0.4455017E+00  -0.1460314E-05
   2.27765   0.70686   0.4938442E+00   0.4938426E+00  -0.1639128E-05
   2.43473   0.86394   0.4938442E+00   0.4938425E+00  -0.1609325E-05
   2.59181   1.02102   0.4455032E+00   0.4455018E+00  -0.1430511E-05
   2.74889   1.17810   0.3535532E+00   0.3535521E+00  -0.1102686E-05
   2.90597   1.33518   0.2269950E+00   0.2269943E+00  -0.7599592E-06

 

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

SPS1R

Программа SPS1R вычисляет коэффициенты кубического сглаживающего сплайна для функциональной зависимости yi = y(xi), i=1, 2, ..., n, заданной на сетке ω a = x1 < x2 < ... < xn-1 < xn = b. Кубический сплайн представляет собой многочлен третьей степени на каждом из отрезков [xi, xi+1], i=1, 2, ..., n-1.
На каждом из промежутков [xi, xi+1], i=1, 2, ..., n-1, интерполяционная сплайн-функция ищется в виде [Б5]:
Si(x) = zi(1-t) + zi+1t - (hi2/6)t(1-t)((2-t)si + (1+t)si+1)
Здесь hi = xi+1 - xi, t = (x - xi)/hi, а числа zi и si i=1, 2, ..., n являются решением системы линейных алгебраических уравнений, вид которой зависит от типа граничных (краевых) условий. Конкретный вид системы уранений для всех типов граничных условий и алгоритм её решения приведён в [Б5].

Граничные (краевые) условия 1-го типа

S'(a) = f'(a) = y1, S'(b) = f'(b) = yn
- на концах промежутка [a,b] задаются значения 1-ой производной интерполируемой функции.

Граничные (краевые) условия 2-го типа

S"(a) = 0, S"(b) = 0
- на концах промежутка [a,b] 2-е производные интерполируемой функции равны нулю.

Граничные (краевые) условия 3-го типа

S(a) = S(b), S'(a) = S'(b), S"(a) = S"(b)
- называются периодическими. Выполнения этих условий естественно требовать в тех случаях, когда интерполируемая функция является периодической с периодом T = b-a.

Выбор весовых коэффициентов

Выбор весовых коэффициентов ρi позволяет управлять сглаживающим свойством сплайна. Если все ρi=0, то zi=yi и сглаживающий сплайн становится интерполяционым. Чем больше весовой множитель некоторой конкретной точки отличается от нуля, тем менее значение функции в этой точке учитывается при вычислении коэффициентов сплайна.

Окт.2024

 

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

call SPS1R(n,x,y,ind,ib,ax,bx,rho,zs,zm,xx,sp,dsp,d2sp)

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

n,x,y,ind,ib,ax,bx,xx,rho - входные параметры;
zs,zm - входные и выходные параметры;
sp,dsp,d2sp - выходные параметры.

integer n - число узлов;
real x[1:n] - массив дины n, содержит координаты узлов сетки;
real y[1:n] - массив дины n, содержит значения функции в узлах сетки;
integer ind - режим выполнения; ind=0 - программа вычисляет коэффициенты сплайна, ind=1 - программа вычисляет значение сплайна в заданной точке xx;
integer ib - тип граничных условий на границах x=ax, x=bx; ib = 1..3;
real ax,bx - параметры, задающие граничные значения для условий 1-го и 2-го типа;
real rho[1:n] - массив дины n, содержит весовые коэффициенты значений функции;
real xx - координата точки, в которой будет вычислено значение сплайна;
real zs[1:n], zm[1:n] - массивы дины n, после первого вызова с ind=0 содержат коэффициенты сплайна;
real sp - значение сплайна в точке xx;
real dsp - значение 1-й производной сплайна в точке xx;
real d2sp - значение 2-й производной сплайна в точке xx;
При работе программы SPS1R используются программы LA31 и SPL1R.

 

Пример

program Test_SPS1
	use NML, only: LA31, SPS1R
	implicit none

	integer, parameter:: n=21
	real:: x(n), y(n), z(n), rho(n), zs(n), zm(n), R(n)
	integer:: ind, ib
	real:: ax, bx, xx, sp, dsp, d2sp
	real, parameter:: pi=3.14159265359
	real:: h, hd2, del0, del1, del2, yy, d1, d2, Am
	integer:: j, nm1
!begin
	! Заполнение массива ρ случайными числами из диапазона [0:1)
	call random_seed()
	call random_number(R)  ! pseudo-random number generator (PRNG)

	ind=0	! вычисляем параметры сплайна
	! Весовые коэффициенты
	rho(:)=0.1
	! Амплитуда отклонения значения функции
	Am=0.1
	! На отрезке [0, 2π] стрлим равномерную сетку из n узлов
	! и вычисляем значения функции y=sin(x) в этих узлах
	nm1 = n-1
	h=2.0*pi/nm1
	do j=1, n
		x(j)=h*(j-1)
		y(j)=sin(x(j))+Am*(R(j)-0.5)
	enddo
	ib=1	! граничные условия
	ax=1.0;  bx=1.0	! граничные значения

	call SPS1R(n,x,y,ind,ib,ax,bx,rho,zs,zm,xx,sp,dsp,d2sp)    	!SPS1R(n,x,y,rho,zs,zm,ind,ib,ax,bx,xx,sp,dsp,d2sp)
	! В массиве zs параметры сплайна

	ind=1	! вычисляем значение сплайна в точке xx
	! sp, dsp, d2sp - значения функции, 1-ой и 2-ой производной
	hd2=0.5*h
	del0=0.0;  del1=0.0;  del2=0.0
	! Строим сетку со смещением на h/2 от исходной
	! Вычисляем сплайн и производные в новой сетке
	do j=1, nm1
		xx=h*(j-1)+hd2
		yy=sin(xx);  d1=cos(xx);  d2=-yy
		call SPS1R(n,x,y,ind,ib,ax,bx,rho,zs,zm,xx,sp,dsp,d2sp)   !SPS1R(n,x,y,rho,zs,zm,ind,ib,ax,bx,xx,sp,dsp,d2sp)
		if(abs(yy-sp) > del0) del0=abs(yy-sp)
		if(abs(d1-dsp) > del1) del1=abs(d1-dsp)
		if(abs(d2-d2sp) > del2) del2=abs(d2-d2sp)
	enddo

	! Печать результатов
	print *,' n = ', n
	print *,' Amplitude = ', Am
	print *,' Weighting factors = ', rho(1)
	print *,' Boundary conditions, ib =', ib
	print *,' max|f(x) - S(x)|   = ', del0
	print *,' max|f''(x) - S''(x)| = ', del1
	print *,' max|f"(x) - S"(x)| = ', del2
end program Test_SPS1

  n =           21
  Amplitude =    0.00000000
  Weighting factors =    0.00000000
  Boundary conditions, ib =           1
  max|f(x) - S(x)|   =    2.57492065E-05
  max|f'(x) - S'(x)| =    2.24113464E-05
  max|f"(x) - S"(x)| =    4.11099195E-03

  n =           21
  Amplitude =   0.100000001
  Weighting factors =   0.100000001
  Boundary conditions, ib =           1
  max|f(x) - S(x)|   =    4.64271307E-02
  max|f'(x) - S'(x)| =    6.58317208E-02
  max|f"(x) - S"(x)| =   0.141094089

  n =           21
  Amplitude =   0.200000003
  Weighting factors =   0.200000003
  Boundary conditions, ib =           1
  max|f(x) - S(x)|   =    9.76079702E-02
  max|f'(x) - S'(x)| =   0.104151309
  max|f"(x) - S"(x)| =   0.238730460

 

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

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], а также в [Б15]. Данный метод более устойчив к накоплению ошибок вычислений, чем метод наименьших квадратов.

 

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

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