Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Архив1 / docx58 / Лаба вычмат4

.docx
Скачиваний:
15
Добавлен:
01.08.2013
Размер:
20.98 Кб
Скачать

num_integration.h

#ifndef NUM_INTEGRATION_H_INCLUDED

#define NUM_INTEGRATION_H_INCLUDED

double NI_method_center_rectangles(double(*F)(double), double e, double a, double b);

double NI_method_trapezes(double(*F)(double), double e, double a, double b);

double NI_method_parabols(double(*F)(double), double e, double a, double b);

double NI_method_Gauss(double(*F)(double), double N, double a, double b);

#endif // NUM_INTEGRATION_H_INCLUDED

num_integration.c

#include <stdio.h>

#include "num_integration.h"

#define EMPTY 0

//метод центральных прямоугольников, использующий принцип Рунге оценки погрешности

double NI_method_center_rectangles(double(*F)( double), double e, double a, double b){

size_t n=2,i; //колво частей, счетчик

double h,xj; //шаг, координата, сдвинутая от x[i] на h/2

double S_h1, S_h2; //суммы весов с шагом h и h/2

if (b == a) return 0; //если пределы интегрирования совпадают

else if (b<a){h=b; b=a; a=h;} //расположим в порядке пределы интегрирования

e*=3; //неравенство 1/3 * |I - I[h/2] | < eps переписано в |I - I[h/2] < 3*eps

do{

for (S_h1=0, i=0, h=(b-a)/n, xj=a-h/2; i<n-1; i++, xj+=h) S_h1+=(*F)(xj); //вычисляем с шагом h

S_h1*=h;

for (S_h2=0, i=0, n+=n, h=(b-a)/n, xj=a-h/2; i<n-1; i++, xj+=h) S_h2+=(*F)(xj); //и с шагом h/2

S_h2*=h;

}while (fabs(S_h1-S_h2) >= e);

return S_h2;

}

//метод трапеций, использующий принцип Рунге оценки погрешности

double NI_method_trapezes(double(*F)(double), double e, double a, double b){

size_t n=2,i; //колво частей, счетчик

double h,xi; //шаг, координата текущая

double S_h1, S_h2; //сумма весов с шагов h и h/2

double x1st_and_last; //полусумма первого и последнего элемента

if (b == a) return 0; //если пределы интегрирования совпадают

else if (b<a){h=b; b=a; a=h;} //расположим в порядке пределы интегрирования

e*=3; //неравенство 1/3 * |I - I[h/2] | < eps переписано в |I - I[h/2] < 3*eps

x1st_and_last = ((*F)(a) + (*F)(b))/2;

do{

S_h1 = S_h2 = x1st_and_last;

for (i=1, h=(b-a)/n, xi=a; i<n;i++, xi+=h) S_h1 += (*F)(xi);

S_h1*=h;

for (i=1, n+=n, h=(b-a)/n, xi=a; i<n; i++, xi+=h) S_h2 += (*F)(xi);

S_h2*=h;

}while (fabs(S_h1-S_h2) >= e);

return S_h2;

}

//метод парабол, использующий принцип Рунге оценки погрешности

double NI_method_parabols(double(*F)(double), double e, double a, double b){

size_t m=1,i; //колво частей/2, счетчик

double h; //шаг

double S_h1, S_h2; //сумма весов с шагов h и h/2

double x1st_and_last; //сумма первого и последнего элементов

double tmp;

if (b == a) return 0; //если пределы интегрирования совпадают

else if (b<a){h=b; b=a; a=h;} //расположим в порядке пределы интегрирования

e*=15; //неравенство 1/15 * |I - I[h/2] | < eps переписано в |I - I[h/2] < 15*eps

x1st_and_last = (*F)(a) + (*F)(b);

do{

S_h1 = S_h2 = x1st_and_last; h=(b-a)/(2*m);

for (i=1,tmp=0;i<=m;i++){ tmp += (*F)(a+h*(2*i-1));} tmp*=4; S_h1 += tmp;

for (i=1,tmp=0;i<m;i++){ tmp += (*F)(a+h*2*i); } tmp*=2; S_h1 += tmp;

S_h1*=h; S_h1/=3;

m*=2;

h=(b-a)/(2*m);

for (i=1,tmp=0;i<=m;i++){ tmp += (*F)(a+h*(2*i-1));} tmp*=4; S_h2 += tmp;

for (i=1,tmp=0;i<m;i++){ tmp += (*F)(a+h*2*i); } tmp*=2; S_h2 += tmp;

S_h2*=h; S_h2/=3;

}while (fabs(S_h1-S_h2) >= e);

return S_h2;

}

//метод Гаусса

double NI_method_Gauss(double(*F)(double), double N, double a, double b){

//таблицы квадратурных коофициентов Гаусса

double t[8][8]={

{0 ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=1

{-0.57735027 , 0.57735027,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=2

{-0.77459667 , 0 ,0.77459667 ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=3

{-0.86113631 ,-0.33998104,0.86113631 ,0.33998104 ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=4

{-0.906113631,-0.53846931,0 ,0.53846931 ,0.906113631,EMPTY ,EMPTY ,EMPTY }, //n=5

{-0.93246951 ,-0.66120939,-0.23861919,0.23861919 ,0.66120939 ,0.93246951,EMPTY ,EMPTY }, //n=6

{-0.94910791 ,-0.74153119,-0.40584515,0 ,0.40584515 ,0.74153119,0.94910791,EMPTY }, //n=7

{-0.96028986 ,-0.79666648,-0.52553242,-0.18343464,0.18343464 ,0.52553242,0.79666648,0.96028986} //n=8

};

double C[8][8]={

{2 ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=1

{1 ,1 ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=2

{0.55555556,0.88888889,0.55555556,EMPTY ,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=3

{0.34785484,0.65214516,0.65214516,0.34785484,EMPTY ,EMPTY ,EMPTY ,EMPTY }, //n=4

{0.23692688,0.47862868,0.56888889,0.47862868,0.23692688,EMPTY ,EMPTY ,EMPTY }, //n=5

{0.17132450,0.36076158,0.46791394,0.46791394,0.36076158,0.17132450,EMPTY ,EMPTY }, //n=6

{0.12948496,0.27970540,0.38183006,0.41795918,0.38183006,0.27970540,0.12948496,EMPTY }, //n=7

{0.10122854,0.22238104,0.31370664,0.36268379,0.36268379,0.31370664,0.22238104,0.10122854} //n=8

};

double S;

double expr1, expr2; //(b+a)/2 (b-a)/2

char i;

if (b == a) return 0; //если пределы интегрирования совпадают

else if (b<a){S=b; b=a; a=S;} //расположим в порядке пределы интегрирования

expr1 = (b+a)/2; expr2 = (b-a)/2;

for (i=0,S=0;i<=(int)N;i++) S+= ((*F)(expr1 + expr2 * t[(int)N][i]) * C[(int)N][i]);

S*=expr2;

return S;

}

main.c

#include <stdio.h>

#include <math.h>

#include "num_integration.h"

double funct_A(double x){

return (cos(0.6*x*x+0.4))/(1.4 + pow((sin(x+0.7)),2));

}

double funct_B(double x){

return 1/(sqrt(2*x*x + 0.3));

}

double funct_C(double x){

return (x + 0.5)/(sqrt(x*x+1.5));

}

int main(){

double (*Functionz[3])(double) = {funct_A, funct_B, funct_C};

double (*Methodz[4])(double(double), double, double, double) = \ {NI_method_center_rectangles,NI_method_trapezes,NI_method_parabols,NI_method_Gauss};

int select_func=0, select_method=0;

double e;

double a=0,b=10;

double result;

printf("Input number of function [1-3]:\n\nChoice:\t"); scanf("%d",&select_func); select_func--;

printf("Input low limit:\t"); scanf("%f",&a);

printf("Input high limit:\t"); scanf("%f",&b);

printf("Input method of numerical integration");

printf("\n\t1)Method center rectangles");

printf("\n\t2)Method of trapezes");

printf("\n\t3)Method of parabols");

printf("\n\t4)Gauss Method");

printf("\nChoice:\t"); scanf("%d",&select_method); select_method--;

if (select_method!=3) printf("Input needed accuracy:\t"); else printf("Input n [0-7]:");

scanf("%f",&e);

result = (Methodz[select_method])(Functionz[select_func],e,a,b);

printf("\nResult:\t%f",result);

return 0;

}