Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <math.h>
- #include <stdio.h>
- #define MAX(x, y) ((x) > (y) ? (x) : (y))
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
- #define EPSILON 0.000001
- // f0 = arctg(x)
- double f0(double x)
- {
- return atan(x);
- }
- // f1 = ch(x)
- double f1(double x)
- {
- return cosh(x);
- }
- // f2 = 1/(1+x^2)
- double f2(double x)
- {
- return 1 / (1 + x * x);
- }
- // Метод левых прямоугольников
- // Принимает: начало, конец, количество отрезков, указатель на функцию
- double method0(double _start, double _end, unsigned long partsAmount, double (*function)(double))
- {
- // Упорядочим начало и конец
- double start = MIN(_start, _end);
- double end = MAX(_start, _end);
- // Длина отрезка
- double partSize = (end - start) / partsAmount;
- double result = 0;
- for (double x = start; x < end; x += partSize) {
- result += function(x) * partSize;
- }
- return result;
- }
- // Метод правых прямоугольников
- // Принимает: начало, конец, количество отрезков, указатель на функцию
- double method1(double _start, double _end, unsigned long partsAmount, double (*function)(double))
- {
- // Упорядочим начало и конец
- double start = MIN(_start, _end);
- double end = MAX(_start, _end);
- // Длина отрезка
- double partSize = (end - start) / partsAmount;
- double result = 0;
- for (double x = start; x < end; x += partSize) {
- result += function(x + partSize) * partSize;
- }
- return result;
- }
- // Метод центральных прямоугольников
- // Принимает: начало, конец, количество отрезков, указатель на функцию
- double method2(double _start, double _end, unsigned long partsAmount, double (*function)(double))
- {
- // Упорядочим начало и конец
- double start = MIN(_start, _end);
- double end = MAX(_start, _end);
- // Длина отрезка
- double partSize = (end - start) / partsAmount;
- double result = 0;
- for (double x = start; x < end; x += partSize) {
- result += (function(x) + function(x + partSize)) / 2 * partSize;
- }
- return result;
- }
- // Формула Симпсона
- // Принимает: начало, конец, количество отрезков, указатель на функцию
- double method3(double _start, double _end, unsigned long partsAmount, double (*function)(double))
- {
- // Упорядочим начало и конец
- double start = MIN(_start, _end);
- double end = MAX(_start, _end);
- // Длина отрезка
- double partSize = (end - start) / partsAmount;
- double result = 0;
- for (double x = start; x < end; x += partSize) {
- result += partSize/6 * (function(x) + 4 * function((2 * x + partSize) / 2) + function(x + partSize));
- }
- return result;
- }
- int main()
- {
- //
- double start, end;
- unsigned int methodIndex;
- printf("Enter X start: ");
- scanf("%lf", &start);
- printf("Enter X end: ");
- scanf("%lf", &end);
- printf("Available methods: \n\t0: left rectangles\n\t1: center rectangles\n\t");
- printf("2: right rectangles\n\t3: Simpson's formula\n");
- printf("Enter method: ");
- scanf("%d", &methodIndex);
- // Указатель на функцию метода
- double (*method)(double, double, unsigned long, double(*)(double));
- switch (methodIndex) {
- case 0: {
- method = method0;
- break;
- }
- case 1: {
- method = method1;
- break;
- }
- case 2: {
- method = method2;
- break;
- }
- default: {
- method = method3;
- break;
- }
- }
- // Формируем массив из указателей на функции (для удобства обхода)
- double (*functions[3])(double) = {f0, f1, f2};
- // Массив из названий функций
- const char *functionsName[3] = {
- "arctg(x)",
- "ch(x)",
- "1 / (1 + x^2)",
- };
- for (unsigned int i = 0; i < 3; i++) {
- unsigned long partsAmount = 100; // Начальное количество отрезков
- unsigned long partsAdd = 100; // Прирост отрезков
- // Предыдущий результат (сохраняем для определения погрешности)
- double prevResult = method(start, end, partsAmount+=partsAdd, functions[i]);
- // Текущий результат
- double result = method(start, end, partsAmount+=partsAdd, functions[i]);
- // Пока абсолютная разница между результатами больше эпсилон - увеличиваем количество отрезков
- while (fabsl(prevResult - result) > EPSILON) {
- prevResult = result;
- result = method(start, end, partsAmount+=partsAdd, functions[i]);
- }
- printf("\nFunction: %s\n", functionsName[i]);
- printf("Result: %lf\n", result);
- printf("Delta: %lf\n", fabs(prevResult - result));
- printf("Parts amount: %lu\n", partsAmount);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement