Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Реалізація інтерполяції функції сплайнами за допомогою мови програмування object Pascal↑ ⇐ ПредыдущаяСтр 3 из 3 Содержание книги
Поиск на нашем сайте
Лінійна інтерполяція Для вирішення системи лінійних алгебраїчних рівнянь використовувалась алгоритмічна мова Паскаль. program Spline; uses Crt, Graph; { Структура, що описує сплайн на кожному сегменті сітки} type SplineTuple=record a, b, c, d, x:real; end; const n_max=100; {Максимальний розмір масиву} var Gd,Gm: integer; {Графічний драйвер і мод} PathToDriver: string; splines: array[0..n_max-1] of SplineTuple; {Сплайн} x,y: array[0..n_max-1] of real; cur_x: real; n:integer; { Побудова сплайна } {x – вузли сітки, впорядковані за зростанням } {y – значення функції у вузлах сітки } {n – кількість вузлів сітки } Procedure BuildSpline; var i:integer; alpha:array[0..n_max-1] of real; beta:array[0..n_max-1] of real; h_i:real; h_i1:real; A:real; C:real; B:real; F:real; z:real; begin { Ініціалізація масиву сплайнів} for i:=0 to n-1 do begin splines[i].x:= x[i]; splines[i].a:= y[i]; end; splines[0].c:=0; splines[n – 1].c:=0; { Рішення системи лінійних рівнянь щодо коефіцієнтів сплайнів } { Обчислення прогоночних коефіцієнтів - прямий хід методу } alpha[0]:=0; beta[0]:=0; for i:=1 to n-2 do begin h_i:= x[i] – x[i – 1]; h_i1:= x[i + 1] – x[i]; A:= h_i; C:= 2.0 * (h_i + h_i1); B:= h_i1; F:= 6.0 * ((y[i + 1] – y[i]) / h_i1 – (y[i] – y[i – 1]) / h_i); z:= (A * alpha[i – 1] + C); alpha[i]:= -B / z; beta[i]:= (F – A * beta[i – 1]) / z; end; { Знаходження рішення - зворотний хід методу прогонки } for i:=n-2 downto 1 do splines[i].c:= alpha[i] * splines[i + 1].c + beta[i]; {По відомим коефіцієнтам c[i] знаходимо значення b[i] i d[i]} for i:=n-1 downto 1 do begin h_i:= x[i] – x[i – 1]; splines[i].d:= (splines[i].c – splines[i – 1].c) / h_i; splines[i].b:= h_i * (2.0 * splines[i].c + splines[i – 1].c) / 6.0 + (y[i] – y[i – 1]) / h_i; end; end; { Обчислення значення інтерполяційної функції у довільній точці} function Func(x:real):real; var s:SplineTuple; i,j,k:Integer; dx:real; begin if (x <= splines[0].x) then {Если x меньше точки сетки x[0]} s:= splines[1] else if (x >= splines[n – 1].x) then { Якщо x більше точки сітки x [n - 1] - користуємося останнім елементом масиву} s:= splines[n – 1] else { Інакше x лежить між граничними точками сітки, то виробляємо бінарний пошук потрібного елемента масиву} begin i:= 0; j:= n – 1; while (i + 1 < j) do begin k:= i + (j – i) div 2; if (x <= splines[k].x) then j:= k else i:= k; end; s:= splines[j]; end; dx:= (x – s.x); { Обчислення значення сплайна в заданій точці за схемою Горнера} Func:=s.a + (s.b + (s.c / 2.0 + s.d * dx / 6.0) * dx) * dx; end; begin ClrScr; Gd:=Detect; Gm:=0; PathToDriver:=''; InitGraph(gd,gm,PathToDriver); {Ініціалізуємо графіку} if GraphResult<>grok then halt; n:=16; x[0]:=0;y[0]:=260; x[1]:=20;y[1]:=260; x[2]:=40;y[2]:=300; x[3]:=60;y[3]:=270; x[4]:=80;y[4]:=330; x[5]:=100;y[5]:=230; x[6]:=120;y[6]:=250; x[7]:=140;y[7]:=220; x[8]:=160;y[8]:=210; x[9]:=180;y[9]:=170; x[10]:=200;y[10]:=150; x[11]:=220;y[11]:=230; x[12]:=240;y[12]:=180; x[13]:=260;y[13]:=190; x[14]:=280;y[14]:=220; x[15]:=300;y[15]:=150; BuildSpline; cur_x:=100; MoveTo(Round(cur_x),Round(Func(cur_x))); while (cur_x<300) do begin cur_x:=cur_x+0.1; LineTo(Round(cur_x),Round(Func(cur_x))); MoveTo(Round(cur_x),Round(Func(cur_x))); end; ReadKey; CloseGraph; END. Алгоритм побудови інтерполяційного кубічного сплайна Нехай кожному значенню аргументу xi, i=0,...,n відповідають значення функції f(xi)=yi і потрібно знайти функціональну залежність у вигляді сплайна S3(x)=аi0 +аi1(x – xi)+аi2(x – xi)2 +аi3(x – xi)3, x Î[ xi, xi+1 ] (1.1), задовольняє перерахованим нижче вимогам: 1. функція S3(xi) неперервна разом зі своїми похідними до другого порядку включно; 2. S3(xi) = yi, i=0,1,...,n; 3. S"3(x0)=S"3(xn)=0. Сформульована вище задача має єдине рішення. Друга похідна S"3(x) неперервна і, як видно з виразу (1.1), лінійна на кожному відрізку [ xi-1, xi ], (i=1,...,n), тому подамо її у вигляді , (1.2) де hi = xi - xi-1, mi = S"3(xi). Інтегруючи обидві частини рівності (1.2), отримаємо , (1.3) де Ai и Bi – постійні інтегрування. Нехай в (1.3) x=xi и x=xi-1, тоді використовуючи умови 2, отримаємо , i=1,...,n. З цих рівнянь знаходимо Ai і Bi, і остаточно формула (1.3) приймає вигляд . (1.4) З формули (1.4) знаходимо односторонні межі похідної в точках x1,x2,...,xn-1: , (1.5) . (1.6) Прирівнюючи вирази (1.5) і (1.6) для i=1,...,n-1, отримаємо n-1 рівняння (1.7) з n-1 невідомими mi (i=1,...,n-1). згідно з умовою (1.2) m0=mn=0. Система лінійних алгебраїчних рівнянь (1.7) має трьохдіагональну матрицю з діагональним переважанням. Такі матриці є неособливими. Тому невідомі m1 , m2 ,..., mn-1 знаходяться із системи (1.7) однозначно. Після визначення mi функція S3(x) відновлюється за формулою (1.4). Метод прогонки Нехай є система рівнянь, записана в матричному вигляді: . (1.8) У нашому випадку згідно (1.7) Рішення системи шукається у вигляді mi = li mi+1 + mi, i=1,...,N-1, (1.9) де Ai, Bi – прогоночні коефіцієнти. Використовуючи вираз для m i-1 із (1.9), виключимо це невідоме з i -го рівняння системи. отримуємо (ai +ci li-1)mi + bi mi+1 = di -cimi-1. Порівнюючи це співвідношення з (1.9), виводимо рекурентні формули для прогоночних коефіцієнтів li, mi (пряма прогонка): l0=m0=0, . (1.10) Очевидно, що mn-1=mn-1 (при сn-1=0). Всі інші невідомі знаходимо за формулами (1.9), використовуючи вирази для прогоночние коефіцієнтів (1.10). Величини li і ai +cili-1 не залежать від правої частини системи. Тому якщо обчислити їх і запам'ятати, то для вирішення систем, що відрізняються тільки правими частинами, потрібно 5 (n-1) арифметичних операцій. Код програми на Pascal #include <iostream.h> #include <math.h> #include <conio.h> #include<iomanip.h> using namespace std; const int N=5121; int main() { cout.setf(ios::left); int i, n; double max,max2,dK,oc,x1,A,B,h,x[N],a[N],b[N],c[N],d[N],y[N],mu[N],m[N],S3[N]; A=0; B=3.141592653589; max=0; max2=0; cout<<" ================="<<endl; cout<<" | n | max | d ocenka | dk |"<<endl; cout<<" -----------------------------"<<endl; for(n=5;n<=5120;n=2*n) { h=(B-A)/n; for(i=0; i<=n; i++) x[i]=A+i*h; a[0]=a[n]=1; b[0]=c[n]=0; d[0]=-sin(A); d[n]=-sin(B); for(i=1; i<n; i++) { a[i]=2*h/3; b[i]=h/6; c[i]=h/6; d[i]=(sin(x[i+1])-2*sin(x[i])+sin(x[i-1]))/h; } y[0]=-b[0]/a[0]; //прогоночні коефіціенти mu[0]=d[0]/a[0]; // прогоночні коефіціенти for(i=1; i<n; i++) //пряма прогонка { y[i]=-b[i]/(a[i]+c[i]*y[i-1]); mu[i]=(d[i]-c[i]*mu[i-1])/(a[i]+c[i]*y[i-1]); } m[n]=mu[n]; for(i=n-1; i>0; i--) m[i]=y[i]*m[i+1]+mu[i]; //Розв’язок системи for(i=1; i<=n; i++) // Визначення кінцевої формули { x1=x[i-1]+h/2; S3[i]=((x[i]-x1)*sin(x[i-1])+(x1-x[i-1])*sin(x[i]))/h+(pow((x[i]-x1),3)- h*h*(x[i]-x1))*m[i-1]/(6*h)+(pow((x1-x[i-1]),3)-h*h*(x1-x[i-1]))*m[i]/(6*h); } max=fabs(S3[1]-sin(x[0]+h/2)); // максимальна похибка for(i=1; i<=n; i++) { x1=x[i-1]+h/2; if(fabs(S3[i]-sin(x1))>max) max=fabs(S3[i]-sin(x1)); } if(n>5) { dK=max2/max; oc=max2/16; } if(n==5) cout<<" |"<<setw(8)<<n<<"|"<<setw(15)<<max<<"|"<<setw(15)<<"- "<<"|"<<setw(15)<<"-"<<"|"<<endl; if(n>5) cout<<" |"<<setw(8)<<n<<"|"<<setw(15)<<max<<"|"<<setw(15)<<oc <<"|"<<setw(15)<<dK<<"|"<<endl; max2=max; } getch(); }
|
||||
Последнее изменение этой страницы: 2016-04-19; просмотров: 402; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.181.194 (0.006 с.) |