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

Архив1 / docx57 / Л4

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

functions.h

#ifndef FUNCTIONS_H_INCLUDED

#define FUNCTIONS_H_INCLUDED

#include <math.h>

typedef struct cal

{

char c;

double r;

char s[100];

};

typedef struct per

{

char name;

double zna;

};

cal TABLI;

per PEREMENS[6];

short SIZE_PERE,SIZE_TABL;

int Length (char *s) //длина строки

{

int i=0;

while (s[i]!='\0')

i++;

return i;

}

int pri (char a) //приоритет операции

{

switch (a)

{

case '(': return 0;

case ')': return 1;

case '-': return 2;

case '+': return 2;

case '/': return 3;

case '*': return 3;

case '^': return 4;

}

}

void input_func(char *s,char *rez,per a[],short *numb_per) //заменяет оперции на буквы и заполняет массив именапи переменных

{

int i,j,size,n;

for (i=0,j=0; s[i]!='\0';)

{

if (s[i]=='S') { rez[j++]='s'; i+=3;}//Sin

else if (s[i]=='C') { rez[j++]='c'; i+=3;}//Cos

else if (s[i]=='t') { rez[j++]='t'; i+=2;}//tg

else if (s[i]=='c') { rez[j++]='T'; i+=3;}//ctg

else if (s[i]=='A')

{

if (s[i+3]=='S') { rez[j++]='S'; i+=6;}//ArcSin

else if (s[i+3]=='C') { rez[j++]='C'; i+=6;}//ArcCos

else if (s[i+3]=='t') { rez[j++]='p'; i+=5;}//Arctg

else if (s[i+3]=='c') { rez[j++]='P'; i+=6;}//Arcctg

}

else if (s[i]=='l')

{

if (s[i+1]=='n') { rez[j++]='L'; i+=2;}//ln

else if (s[i+1]=='g') { rez[j++]='l'; i+=2;}//lg

}

else if ((s[i]>='U')&&(s[i]<='Z')||(s[i]>='u')&&(s[i]<='z'))

{

n=0;

while ((n<(*numb_per))&&(s[i]!=a[n].name)&&(s[i]!=a[n].name+32)&&(s[i]!=a[n].name-32))

n++;

if (n==(*numb_per))

{

a[n].name=s[i];

(*numb_per)++;

}

(rez[j++]=s[i++]);

}

else (rez[j++]=s[i++]);

}

rez[j]='\0';

}

double scanf_number (int *start, char *s) //считывает вещественное число без плавающей точки

{

double d=0,r=0;

short p=0;

while ((s[*start]>='0')&&(s[*start]<='9'))

d=d*10+s[(*start)++]-'0';

if ((s[*start]==',')||(s[*start]=='.'))

{

(*start)++;

while ((s[*start]>='0')&&(s[*start]<='9'))

{

r=r*10+s[(*start)++]-'0';

p++;

}

}

return d+r/pow(10.0,p);

}

int zapis (cal *z, char *str,int start, int finish) //формирует таблицу переменных и значений

{

int i,j;

char c='0',h,p;

for (i=start, j=0; i<finish; )

{

if ((str[i]>='A')&&(str[i]<='Z')||(str[i]>='a')&&(str[i]<='z'))

{

z[j].c=c++;

p=0;

z[j].s[p++]=str[i++];

if (str[i]=='(')

{

h=1;

while (h!=0)

{

z[j].s[p++]=str[i++];

if (str[i]==')') h--;

else if (str[i]=='(') h++;

}

z[j].s[p++]=')';

i++;

}

z[j].s[p]='\0';

z[j].r=0;

}

else if ((str[i]=='+')||(str[i]=='-')||(str[i]=='*')||(str[i]=='/')||(str[i]=='^')||(str[i]=='(')||(str[i]==')'))

{

z[j].c=str[i++];

z[j].r=0;

z[j].s[0]='\0';

}

else if ((str[i]>='0')&&(str[i]<='9'))

{

z[j].c=c++;

z[j].r=scanf_number(&i,str);

z[j].s[0]='\0';

}

j++;

}

return j;

}

void cop(cal *b, cal *PS) //копирует таблицу PS в b

{

int i=0;

b->c=PS->c;

b->r=PS->r;

while (PS->s[i]!='\0')

b->s[i]=PS->s[i++];

b->s[i]='\0';

}

int ObratPoleZap (cal *PS,cal *b,int size) //формирует обратную польскую запись

{

char CPO[40]="";

char ch,j=0,l=0,i=1,t;

char n=0,r;

while (n<size)

{

if ((PS[n].c>='0')&&(PS[n].c<=']'))

cop(&b[j++],&PS[n++]);

else

{

if (PS[n].c=='(')

CPO[l++]=PS[n++].c;

else

if (PS[n].c!=')')

{

if ((l==0)||(pri(CPO[l-1])<pri(PS[n].c)))

CPO[l++]=PS[n++].c;

else

{

while ((l!=0)&&(pri(CPO[l-1])>=pri(PS[n].c))&&(CPO[l-1]!='('))

{

r=0;

while (PS[r].c!=CPO[l-1])

r++;

cop(&b[j++],&PS[r]);

l--;

}

CPO[l++]=PS[n++].c;

}

}

else

{

while (CPO[l-1]!='(')

{

r=0;

while (PS[r].c!=CPO[l-1])

r++;

cop(&b[j++],&PS[r]);

l--;

}

l--;

n++;

}

}

}

l--;

while (l>=0)

{

r=0;

while (PS[r].c!=CPO[l])

r++;

cop(&b[j++],&PS[r]);

l--;

}

return j;

}

double computing(cal *PS,int size,per a[], short sizeZna) //проводит вычисления по ОПЗ

{

cal n[100];

cal y[100];

double STAK[10];

int i=0,j,t=0,si,p;

double rez;

while (i<size)

{

if ((PS[i].c>='0')&&(PS[i].c<=']'))

{

if (PS[i].s[0]=='\0') STAK[t++]=PS[i].r;

else

{

if ((PS[i].s[0]=='s')||(PS[i].s[0]=='c')||(PS[i].s[0]=='t')||(PS[i].s[0]=='T')||(PS[i].s[0]=='S')||(PS[i].s[0]=='C')||(PS[i].s[0]=='p')||

(PS[i].s[0]=='P')||(PS[i].s[0]=='L')||(PS[i].s[0]=='l')||(PS[i].s[0]=='e'))

{

si=zapis(n,PS[i].s,2,Length(PS[i].s)-1);

si=ObratPoleZap(n,y,si);

rez=computing(y,si,a,sizeZna);

switch (PS[i].s[0])

{

case 's': {PS[i].r=sin(rez);} break; //Sin

case 'c': {PS[i].r=cos(rez);} break; //Cos

case 't': {PS[i].r=tan(rez);} break; //tg

case 'T': {PS[i].r=1/tan(rez);} break; //ctg

case 'S': {PS[i].r=atan(rez/sqrt(1-rez*rez));} break; //ArcSin

case 'C': {PS[i].r=2*atan(sqrt((1-rez)/(1+rez)));}break;//ArcCos

case 'p': {PS[i].r=atan(rez);} break; //Arctg

case 'P': {PS[i].r=3.141592654/2-atan(rez);} break; //Arcctg

case 'L': {PS[i].r=log(rez);} break; //ln

case 'l': {PS[i].r=log10(rez);} break; //lg

case 'e': {PS[i].r=exp(1.);} break; //Exp

}

STAK[t++]=PS[i].r;

}

else

{

p=0;

while ((p<sizeZna)&&(a[p].name!=PS[i].s[0])&&(a[p].name+32!=PS[i].s[0])&&(a[p].name-32!=PS[i].s[0]))

p++;

STAK[t++]=a[p].zna;

}

}

}

else

{

switch (PS[i].c)

{

case '*': {t-=2; STAK[t]=STAK[t]*STAK[t+1]; t++;} break;

case '/': {t-=2; STAK[t]=STAK[t]/STAK[t+1]; t++;} break;

case '+': {t-=2; STAK[t]=STAK[t]+STAK[t+1]; t++;} break;

case '-': {t-=2; STAK[t]=STAK[t]-STAK[t+1]; t++;} break;

case '^': {t-=2; STAK[t]=pow(STAK[t],STAK[t+1]); t++;} break;

}

}

i++;

}

return STAK[t-1];

}

void inp_zna_per (per a[],int size) //заполняем значения переменных

{

int i;

while (i<size)

{

printf("Enter zna %c :",a[i].name);

scanf("%lf",&a[i].zna);

i++;

}

}

int input_integr_preob (cal *x, per PEREMEN[],short *size_per) //ввод функции и преобразование в вид для вычислений финкций

{

char *s, *rez,k;

cal z[50];

rez=(char*) malloc (sizeof(char)*100);

s=(char*) malloc (sizeof(char)*100);

printf("Enter function: ");

gets(s);

input_func(s,rez,PEREMEN,size_per);

k=zapis (z, rez,0,Length(rez));

k=ObratPoleZap (z,x,k);

return k;

}

void input_integr_func () //ввод функции и преобразование в вид для вычислений финкций F(X)

{

char *s, *rez;

cal z[50];

rez=(char*) malloc (sizeof(char)*100);

s=(char*) malloc (sizeof(char)*100);

printf("Enter function: ");

gets(s);

input_func(s,rez,PEREMENS,&SIZE_PERE);

SIZE_TABL=zapis (z, rez,0,Length(rez));

SIZE_TABL=ObratPoleZap (z,&TABLI,SIZE_TABL);

}

double functio (double y) //возращает значение функции

{

PEREMENS[0].zna=y;

return computing(&TABLI,SIZE_TABL,PEREMENS,1);

}

#endif // FUNCTIONS_H_INCLUDED

integration.h

#ifndef INTEGRATION_H_INCLUDED

#define INTEGRATION_H_INCLUDED

#include "functions.h"

double centr_rect(double(*F)(double), double e, double a, double b) //метод центральных прямоугольников, использующий принцип Рунге оценки погрешности

{

int n=2,i,step=0;

double h,x,S1, S2;

if (b==a) return 0;

else

if (b<a)

{

h=b;

b=a;

a=h;

}

e*=3;

for (S2=0, i=0, h=(b-a)/n, x=a+h/2; i<n; i++, x+=h)

S2+=F(x);

S2*=h;

do

{

S1=S2;

h=h/2;

n+=n;

for (S2=0, i=0, x=a+h/2; i<n; i++, x+=h)

S2+=F(x);

S2*=h;

step++;

}

while ((fabs(S1-S2)>=e)&&(step<100));

if (step<100)

return S2;

else

{

printf("Error, input other Epsilon: ");

return -1;

}

}

double trapez(double(*F)(double), double e, double a, double b) //метод трапеций, использующий принцип Рунге оценки погрешности

{

int n=2,i,step=0;

double h,x,S1,S2,medium;

if (b == a) return 0;

else if (b<a)

{

h=b;

b=a;

a=h;

}

e*=3;

S2=medium=(F(a)+F(b))/2;

for (i=1, h=(b-a)/n, x=a; i<n; i++, x+=h)

S2+=F(x);

S2*=h;

do

{

S1=S2;

S2=medium;

n+=n;

for (i=1, h=h/2, x=a; i<n; i++, x+=h)

S2+=F(x);

S2*=h;

step++;

}

while ((fabs(S1-S2)>=e)&&(step<100));

if (step<100)

return S2;

else

{

printf("Error, input other Epsilon: ");

return -1;

}

}

double parabol(double(*F)(double), double e, double a, double b) //метод парабол, использующий принцип Рунге оценки погрешности

{

int m=1,i,step=0;

double h,S1, S2,medium,tmp,tms;

if (b==a) return 0;

else if (b<a)

{

h=b;

b=a;

a=h;

}

e*=15;

S2=medium=(F(a)+F(b))/2;

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

tmp=0; tms=0;

for (i=1; i<m; i++)

{

tmp+=F(a+h*(2*i-1));

tms+=F(a+h*2*i);

}

tmp+=F(a+h*(2*i-1));

S2+=4*tmp+2*tms;

S2*=h/3;

do

{

S1=S2;

S2=medium;

m*=2;

h=h/2;

tmp=0; tms=0;

for (i=1; i<m; i++)

{

tmp+=F(a+h*(2*i-1));

tms+=F(a+h*2*i);

}

tmp+=F(a+h*(2*i-1));

S2+=4*tmp+2*tms;

S2*=h/3;

step++;

}

while ((fabs(S1-S2)>=e)&&(step<100));

if (step<100)

return S2;

else

{

printf("Error, input other Epsilon: ");

return -1;

}

}

double Gauss(double(*F)(double), double e, double a, double b) //метод Гаусса

{

short i;

double S,ex1,ex2;

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

double T[4][4]=

{

{0 ,0 ,0 ,0 }, //e=1

{-0.57735027 , 0.57735027,0 ,0 }, //e=2

{-0.77459667 , 0 ,0.77459667 ,0 }, //e=3

{-0.86113631 ,-0.33998104,0.33998104 ,0.86113631 }, //e=4

};

double A[4][4]=

{

{2 ,0 ,0 ,0 }, //e=1

{1 ,1 ,0 ,0 }, //e=2

{0.55555556 ,0.88888889 ,0.55555556 ,0 }, //e=3

{0.34785484 ,0.65214516 ,0.65214516 ,0.34785484 }, //e=4

};

if (b==a) return 0;

else if (b<a)

{

S=b;

b=a;

a=S;

}

ex1=(b+a)/2;

ex2=(b-a)/2;

S=0;

for (i=0; i<=(int)e ;i++)

S+=F(ex1+ex2*T[(int)e][i])*A[(int)e][i];

S*=ex2;

return S;

}

#endif // INTEGRATION_H_INCLUDED

main.c

// Labs4_Number_Inte.cpp: главный файл проекта.

#include "stdafx.h"

#include <iostream>

#include <stdio.h>

#include "functions.h"

#include "integration.h"

using namespace System;

using namespace std;

int main(array<System::String ^> ^args)

{

double (*Methods[4])(double(double), double, double, double)={centr_rect,trapez,parabol,Gauss};

short method;

double a,b,e,result;

input_integr_func ();

printf("Enter left lim a: ");

scanf("%lf",&a);

printf("Enter right lim b: ");

scanf("%lf",&b);

printf("Enter method numerical integration");

printf("\nMethod center rectangles=0 \nMethod of trapezes=1 \nMethod of parabols=2 \nGauss Method=3");

printf("\nMethod: ");

scanf("%d",&method);

if (method==3)

printf("Enter n [0-3]: ");

else printf("Enter Epsilon: ");

scanf("%lf",&e);

result=(Methods[method])(functio,e,a,b);

printf("\nResult: %lf\n",result);

system("pause");

return 0;

}

Федеральное агентство по образованию РФ

Государственное образовательное учреждение высшего профессионального образования

Белгородский Государственный Технологический Университет им. В. Г. Шухова.

Кафедра программного обеспечения вычислительной техники и

автоматизированных систем.

Лабораторная работа №4

Численное интегрирование

Выполнил студент группы ПВ-22

Воробьев Р.В.

Проверила Брусенцева В.С.

Белгород 2011г.

Задания к работе

  1. Вычислить «вручную» для соответствующего варианта интегралы

- по формуле средних прямоугольников, используя для оценки точности двойной просчет при n1=8; n2=10;

- по формуле Ньютона-Лейбница и по формуле трапеций с тремя десятичными знаками;

- по формуле Симпсона при n=8. Оценить погрешность результата, составив таблицу конечных разностей.

2. Описать в модуле функции, которые возвращают приближенные значения интегралов от функции f(x) с оценкой точности по принципу Рунге для методов

- центральных прямоугольников

- трапеций

- парабол

3. Описать в модуле функцию для вычисления приближенного значения интеграла от функции f(x) по формуле Гаусса с n=1,2,3,4. Узлы t0 и веса a0 приведены в таблице

4. Составить программу для вычислений приближенных значений интегралов от функций п.1-3 с использованием всех функции описанных в модуле.

Задание:

Спецификации подпрограмм:

Спецификация функции centr_rect:

  1. Заголовок: double centr_rect(double(*F)(double), double e, double a, double b)

  2. Назначение: возвращает приближенно значение интеграла от функции double(*F)(double) с левым приделом a и правым приделом b, с точностью е, решенный методом центральных прямоугольников.

  3. Входные параметры: (*F)(double),e,a,b;

  4. Выходных параметров нет.

Спецификация функции trapez:

  1. Заголовок: double trapez (double(*F)(double), double e, double a, double b)

  2. Назначение: возвращает приближенно значение интеграла от функции double(*F)(double) с левым приделом a и правым приделом b, с точностью е, решенный методом трапеций.

  3. Входные параметры: (*F)(double),e,a,b;

  4. Выходных параметров нет.

Спецификация функции parabol:

  1. Заголовок: double parabol (double(*F)(double), double e, double a, double b)

  2. Назначение: возвращает приближенно значение интеграла от функции double(*F)(double) с левым приделом a и правым приделом b, с точностью е, решенный методом парабол.

  3. Входные параметры: (*F)(double),e,a,b;

  4. Выходных параметров нет.

Спецификация функции Gauss:

  1. Заголовок: double Gauss (double(*F)(double), double e, double a, double b)

  2. Назначение: возвращает приближенно значение интеграла от функции double(*F)(double) с левым приделом a и правым приделом b, с точностью е, решенный методом Гаусса.

  3. Входные параметры: (*F)(double),e,a,b;

  4. Выходных параметров нет.

Соседние файлы в папке docx57