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; } |