Задача на вычисление определенного интеграла - C (СИ)
Формулировка задачи:
Помогите исправить ошибку.
В методе Симпсона кол-во итераций почему-то больше, чем в других, хотя он наиболее точен.
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double F(double x){
return sqrt(1+cos(x)*cos(x));
}
double prm(double a, double b, int n){
double dx= fabs(a-b)/n,x=a,f=0;
int i=0;
while(i<=n-1){
f += F(x);
x += dx;
i++;
}
f *= dx;
return f;
}
double trp(double a, double b, int n){
double dx= fabs(a-b)/n,x=a,f=0;
int i=0;
while(i<=n-1){
f += (F(x)+F(x+dx))/2;
x += dx;
i++;
}
f *= dx;
return f;
}
double smp(double a, double b, int n){
double dx= fabs(a-b)/n,x=a,f=0;
int i=1;
while(i<=n-1){
x += dx;
if (i%2 == 1) f += F(x)*4;
else f += F(x)*2;
i++;
}
f += (F(a) + F(b));
f /= 3;
f *= dx;
return f;
}
//вычисление при заданном E
void EPS(double eps, double a, double b, int *I1, double *y1, int *I2, double *y2, int *I3, double *y3, int n){
int n_0 = n;
double f1_1, f1_2, f2_1, f2_2, f3_1, f3_2;
f1_1 = prm(a,b, n);
f1_2 = prm(a,b, n+2);
(*I1)++;
while (fabs(f1_2 - f1_1) > eps){
n += 2;
f1_1 = prm(a,b, n);
f1_2 = prm(a,b, n+2);
(*I1)++;
}
*y1 = f1_2;
n = n_0;
f2_1 = trp(a,b, n);
f2_2 = trp(a,b, n+2);
(*I2)++;
while (fabs(f2_2 - f2_1) > eps){
n += 2;
f2_1 = trp(a,b, n);
f2_2 = trp(a,b, n+2);
(*I2)++;
}
*y2 = f2_2;
n = n_0;
f3_1 = smp(a,b, n);
f3_2 = smp(a,b, n+2);
(*I3)++;
while (fabs(f3_2 - f3_1) > eps){
n += 2;
f3_1 = smp(a,b, n);
f3_2 = smp(a,b, n+2);
(*I3)++;
}
*y3 = f3_2;
}
int main(void){
double eps = 0.1, a = 0, b = M_PI, y1=0, y2=0, y3 = 0;
int I1, I2, I3, i;
printf("E prm I1 trp I2 Smp I3\n");
for (i=0;i<5;i++){
I1 = 0; I2 = 0; I3 = 0;
EPS(eps, a, b, &I1, &y1, &I2, &y2, &I3, &y3, 2);
printf("%lf %lf %d %lf %d %lf %d\n",eps, y1,I1,y2,I2, y3, I3);
eps /= 10;
}
return 0;
}Решение задачи: «Задача на вычисление определенного интеграла»
textual
Листинг программы
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
#define FORMULA sqrt(1+cos(x)*cos(x))
#define STEP 1000
using namespace std;
double Integ(float a, float b)
{
float x,h,s=0;
h=(b-a)/STEP;
x=a+h/2;
for(int i=0; i<STEP; i++)
{
s+=FORMULA;
x+=h;
}
s*=h;
return s;
}
int main()
{
cout<<Integ(0,M_PI)<<endl;
system("pause");
return 0;
}
Объяснение кода листинга программы
- Подключение необходимых библиотек для работы с математикой и вводом/выводом данных.
- Определение формулы для вычисления значения определенного интеграла (в данном случае это sqrt(1+cos(x)*cos(x))).
- Определение шага интегрирования (в данном случае это 1000).
- Использование пространства имен std для удобства работы с функциями ввода/вывода.
- Создание функции Integ, которая принимает два аргумента типа float - a и b, и возвращает значение определенного интеграла от a до b.
- Внутри функции Integ инициализируются переменные x, h и s. Значение h равно (b-a)/STEP, где STEP - это шаг интегрирования. Значение x равно a + h/2. Переменная s инициализируется как 0 и используется для накопления суммы значений функции FORMULA.
- Запускается цикл for, который выполняется STEP раз. На каждой итерации значение функции FORMULA добавляется к переменной s, а значение x увеличивается на h.
- После завершения цикла значение переменной s умножается на h, чтобы получить итоговое значение определенного интеграла.
- Функция Integ возвращает полученное значение.
- В функции main вызывается функция Integ с аргументами 0 и M_PI (это константа, равная 3.14159...).
- Результат вычисления определенного интеграла выводится на экран.
- Программа ожидает нажатия клавиши для завершения работы.
- Возвращается 0, что означает успешное завершение работы программы.