Численные методы решения типовых математических задач

курсовая работа

3.7 Тестовый пример

Найти тригонометрический многочлен наилучшего среднеквадратичного приближения наименьшей степени со среднеквадратичным отклонением меньшим для функции

Введем функцию

Вычислим коэффициенты Фурье

Вычислим частичные суммы ряда Фурье

Вычислим среднеквадратичное отклонение

Найдем минимальное , при котором будет меньше

Следовательно многочлен степени является наименьшим многочленом, удовлетворяющим нашим условиям. Построим график этого многочлениа и исходной функции

Построим график среднеквадратичного отклонения

Найдем минимальное , при котором будет меньше

Следовательно, многочлен степени является наименьшим многочленом, удовлетворяющим нашим условиям. Построим график этого многочлениа и исходной функции

Построим график среднеквадратичного отклонения

4. Численное интегрирование функций методом Гаусса

4.1 Постановка задачи

Разработать схему алгоритма и написать программу на языке Turbo Pascal 7.0 для вычисления интегралов функции, используя метод Гаусса.

4.2 Математическая формулировка задачи

Пусть функция задана на стандартном интервале . Задача состоит в том, чтобы подобрать точки и коэффициенты так, чтобы квадратурная формула

была точной для всех полиномов наивысшей возможной степени.

4.3 Обзор существующих численных методов решения задачи

Одномерный случай

Основная идея большинства методов численного интегрирования состоит в замене подынтегральной функции на более простую, интеграл от которой легко вычисляется аналитически. При этом для оценки значения интеграла получаются формулы вида

где -- число точек, в которых вычисляется значение подынтегральной функции. Точки называются узлами метода, числа -- весами узлов. При замене подынтегральной функции на полином нулевой, первой и второй степени получаются соответственно методы прямоугольников, трапеций и парабол (Симпсона). Часто формулы для оценки значения интеграла называют квадратурными формулами.

Метод прямоугольников

Метод прямоугольников получается при замене подынтегральной функции на константу. В качестве константы можно взять значение функции в любой точке отрезка . Наиболее часто используются значения функции в середине отрезка и на его концах. Соответствующие модификации носят названия методов средних прямоугольников, левых прямоугольников и правых прямоугольников. Формула для приближенного вычисления значения определённого интеграла методом прямоугольников имеет вид

,

где , или , соответственно.

Метод трапеций

Если функцию на каждом из частичных отрезков аппроксимировать прямой, проходящей через конечные значения, то получим метод трапеций.

Площадь трапеции на каждом отрезке:

Погрешность аппроксимации на каждом отрезке:

, где

Полная формула трапеций в случае деления всего промежутка интегрирования на отрезки одинаковой длины h:

,

где

Погрешность формулы трапеций:

, где

Метод парабол (метод Симпсона)

Использовав три точки отрезка интегрирования можно заменить подынтегральную функцию параболой. Обычно в качестве таких точек используют концы отрезка и его среднюю точку. В этом случае формула имеет очень простой вид

.

Если разбить интервал интегрирования на 2N равных частей, то имеем

,

где .

Если разбить интервал интегрирования на 2N равных частей, то имеем

,

где .

Увеличение точности

Приближение функции одним полиномом на всем отрезке интегрирования, как правило, приводит к большой ошибке в оценке значения интеграла.

Для уменьшения погрешности отрезок интегрирования разбивают на части и применяют численный метод для оценки интеграла на каждой из них.

При стремлении количества разбиений к бесконечности, оценка интеграла стремится к его истинному значению для любого численного метода.

Приведённые выше методы допускают простую процедуру уменьшения шага в два раза, при этом на каждом шаге требуется вычислять значения функции только во вновь добавленных узлах. Для оценки погрешности вычислений используется правило Рунге.

Метод Гаусса

Описанные выше методы используют фиксированные точки отрезка (концы и середину) и имеют низкий порядок точности (0 --- методы правых и левых прямоугольников, 1 --- методы средних прямоугольников и трапеций, 3 --- метод парабол (Симпсона)). Если мы можем выбирать точки, в которых мы вычисляем значения функции , то можно при том же количестве вычислений подынтегральной функции получить методы более высокого порядка точности. Так для двух (как в методе трапеций) вычислений значений подынтегральной функции, можно получить метод уже не 1-го, а 3-го порядка точности:

.

В общем случае, используя точек, можно получить метод с порядком точности . Значения узлов метода Гаусса по точкам являются корнями полинома Лежандра степени .

Значения узлов метода Гаусса и их весов приводятся в справочниках специальных функций. Наиболее известен метод Гаусса по пяти точкам.

В общем случае, используя точек, можно получить метод с порядком точности . Значения узлов метода Гаусса по точкам являются корнями полинома Лежандра степени .

Значения узлов метода Гаусса и их весов приводятся в справочниках специальных функций. Наиболее известен метод Гаусса по пяти точкам.

Метод Гаусса-Кронрода

Недостаток метода Гаусса состоит в том, что он не имеет лёгкого (с вычислительной точки зрения) пути оценки погрешности полученного значения интеграла. Использование правила Рунге требует вычисления подынтегральной функции примерно в таком же числе точек, не давая при этом практически никакого выигрыша точности, в отличие от простых методов, где точность увеличивается в разы при каждом новом разбиении. Кронродом был предложен следующий метод оценки значения интеграла

,

где -- узлы метода Гаусса по точкам, а параметров , , подобраны таким образом, чтобы порядок точности метода был равен .

Тогда для оценки погрешности можно использовать эмпирическую формулу:

,

где -- приближённое значение интеграла, полученное методом Гаусса по точкам.

4.4 Численный метод решения задачи

Пусть функция задана на стандартном интервале . Задача состоит в том, чтобы подобрать точки и коэффициенты так, чтобы квадратурная формула

(4.1)

была точной для всех полиномов наивысшей возможной степени.

Ввиду того, что имеется параметров и , а полином степени определяется коэффициентами, эта наивысшая степень в общем случае .

Запишем полином в виде и подставим в (4.1). Получим

,

.

Приравнивая выражения при одинаковых коэффициентах получим

, ,

, .

Итак, и находят из системы уравнений

,

,

, (4.2)

. . . . . . .

.

Система (4.2) нелинейная, и ее решение найти довольно трудно. Рассмотрим еще один прием нахожденияи . Свойства полиномов Лежандра

,

таковы:

1) , ;

2) ;

3) полином Лежандра имеет различных и действительных корней, расположенных на интервале .

Составим по узлам интегрирования многочлен -й степени

.

Функция при есть многочлен степени не выше . Значит для этой функции формула Гаусса справедлива:

, (4.3)

так как .

Разложим в ряд по ортогональным многочленам Лежандра:

,

,

,

т.е. все коэффициенты при . Значит с точностью до численного множителя совпадает с . Таким образом, узлами формулы Гаусса являются нули многочлена Лежандра степени .

Зная , из линейной теперь системы первых (4.2) легко найти коэффициенты являются нули многочлена Лежандра степени .

Зная , из линейной теперь системы первых (4.2) легко найти коэффициенты . Определитель этой системы есть определитель Вандермонда.

Формулу , в которой - нули полинома Лежандра , а определяют из (3.3), называют квадратурной формулой Гаусса.

4.5 Схема алгоритма

Рис. 4.1 Основная программа метода

Рис .4.2 Интегрирование методом Гаусса

Рис 4.3 Процедура подсчета коэффициентов по методу Гаусса

4.6 Текст программы

uses crt,graph;

var aaa,bbb,kkk:real;

const

g10c1=0.9739065285/6.2012983932;

g10c2=0.8650633667/6.2012983932;

g10c3=0.6794095683/6.2012983932;

g10c4=0.4333953941/6.2012983932;

g10c5=0.1488743390/6.2012983932;

g10x1=0.0666713443/6.2012983932;

g10x2=0.1494513492/6.2012983932;

g10x3=0.2190863625/6.2012983932;

g10x4=0.2692667193/6.2012983932;

g10x5=0.2955242247/6.2012983932;

function F(x:real):real;{интегрируемая функция}

begin

F:= ln(1+x*x*x);

end;

function gauss_calc(a,b:real):real; {метод Гаусса}

var n,m,s,s1,s2,s3,s4,s5 :real;

begin

m:=(b+a)/2; n:=(b-a)/2;

s1:=g10c1*(f(m+n*g10x1)+f(m-n*g10x1));

s2:=g10c2*(f(m+n*g10x2)+f(m-n*g10x2));

s3:=g10c3*(f(m+n*g10x3)+f(m-n*g10x3));

s4:=g10c4*(f(m+n*g10x4)+f(m-n*g10x4));

s5:=g10c5*(f(m+n*g10x5)+f(m-n*g10x5));

s:=s1+s2+s3+s4+s5;

gauss_calc:=s*(b-a);

end;

{рекурсивная ф-ция подсчета с заданной точностью}

{ gc - ранее посчитаный интеграл на интервале (a,b)}

function gauss(a,b,eps,gc:real):real;

var t,ga,gb :real;

begin

t:=(a+b)/2; {разбиваем интервал на две половинки}

ga:=gauss_calc(a,t); {в каждой половинке считаем интеграл}

gb:=gauss_calc(t,b);

if abs(ga+gb-gc)>eps then {проверяем точность вычислений}

begin

ga:=gauss(a,t,eps/2,ga); {рекурсия для первой половинки}

gb:=gauss(t,b,eps/2,gb); {рекурсия для второй половинки}

end; {при этом точность повышаем, чтобы }

{при сложении ошибка не накапливалась}

gauss:=ga+gb; {интеграл = сумме интегралов половинок}

end;

procedure inputnum(prm:string;var num:real;lb,ub:real);

var q:boolean;

begin

repeat

write(Введите ,prm, );readln(num);

q:=(lb>=num) or (num>ub);

if q then writeln(Число должно быть от , lb:0:0, до ,ub:0:0);

until not q;

end;

function main_menu:integer;

var i:integer;

begin

Writeln(==========================================================);

Writeln(0 - выход);

Writeln(1 - решать тестовый пример a=0 b=1.2 k=10 eps = 0.0001);

Writeln(2 - решать пример с произвольными a, b, k, eps);

Writeln(----------------------------------------------------------);

Write(Выбор >>> );readln(i);

Writeln(==========================================================);

main_menu:=i;

end;

{Вывод графика}

procedure outputgraph(a,b,a1,b1:real;n:integer);

var i,j,j1,k:integer;t,y1,y2,x1,x2,x,y:double;s:string;

begin

clearviewport;

x1:=a1-1;x2:=b1+1;

if x1<0.5 then x1:=-0.5;

y2:=f(ln(bbb/aaa)/(bbb-aaa))*1.2;

y1:=-y2;

{Линия y=0}

setcolor(15);

y:=0;

j:=trunc(480*(y-y2)/(y1-y2));

line(0,j,639,j);

{Линии x=a,x=b}

setcolor(5);

j:=trunc(480*(-y2)/(y1-y2));

i:=trunc(640*(a-x1)/(x2-x1));

j1:=trunc(480*(f(a)-y2)/(y1-y2));

line(i,j,i,j1);

i:=trunc(640*(b-x1)/(x2-x1));

j:=trunc(480*(-y2)/(y1-y2));

j1:=trunc(480*(f(b)-y2)/(y1-y2));

line(i,j,i,j1);

{Сам график}

setcolor(14);

setlinestyle(0,0,3);

t:=(b-a)/n;

k:=0;

j1:=trunc(480*(-y2)/(y1-y2));

for i:=0 to 640 do begin

x:=(x2-x1)*i/640+x1;

y:=f(x);

j:=trunc(480*(y-y2)/(y1-y2));

if j>479 then j:=479;

if j<0 then j:=0;

setcolor(14);

setlinestyle(0,0,3);

if i=0 then moveto(i,j) else lineto(i,j);

setcolor(8);

if (x>t*k+a) then begin

k:=k+1;

setcolor(15);

end;

k:=0;

j1:=trunc(480*(-y2)/(y1-y2));

for i:=0 to 640 do begin

x:=(x2-x1)*i/640+x1;

y:=f(x);

j:=trunc(480*(y-y2)/(y1-y2));

if j>479 then j:=479;

if j<0 then j:=0;

setcolor(14);

setlinestyle(0,0,3);

if i=0 then moveto(i,j) else lineto(i,j);

setcolor(8);

if (x>t*k+a) then begin

k:=k+1;

setcolor(15);

end;

setlinestyle(0,0,1);

if (x>=a) and (x<=b) then line(i,j,i,j1);

end;

setcolor(15);

y:=f(b);

i:=trunc(640*(b-x1)/(x2-x1));

j:=trunc(480*(y-y2)/(y1-y2));

line(i,j,i,j1);

setlinestyle(0,0,1);

setcolor(12);

{Подписи}

setcolor(13);

str(a:6:6,s);

s:=a=+s;

i:=trunc(640*(a-x1)/(x2-x1));

outtextxy(i,j1+2,s);

str(b:6:6,s);

s:=b=+s;

i:=trunc(640*(b-x1)/(x2-x1));

outtextxy(i-10,j1+2,s);

setcolor(15);

y:=0;

j:=trunc(480*(y-y2)/(y1-y2));

outtextxy(5,j+3,y=0);

readkey;

end;

procedure equateit(eps:real);

var integral,a,b:real;i,j:integer;

begin

a:=0;b:=1;

Integral:=gauss(a,b,eps,gauss_calc(a,b));

writeln(Интеграл = ,integral:0:6);

readkey;

i:=vga;j:=vgahi;

initgraph(i,j,..gi);

outputgraph(a,(b+a)/2,a,b,1);

outputgraph((b+a)/2,b,a,b,1);

outputgraph(a,b,a,b,1);

closegraph;

end;

var sel:integer;

eps:real;

begin

repeat

clrscr;

sel:=main_menu;

case sel of

1:begin

aaa:=0.1;bbb:=1.2;kkk:=10;

eps:=1e-4;

equateit(eps);

end;

2:begin

inputnum(a,aaa,0,1000);

inputnum(b,bbb,-1000,1000);

inputnum(k,kkk,-1000,1000);

inputnum(точность,eps,0.000000001,1);

equateit(eps);

end;

end;

until sel=0;

end.

i:=vga;j:=vgahi;

initgraph(i,j,..gi);

outputgraph(a,(b+a)/2,a,b,1);

Делись добром ;)