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

ЛБ6 / main

.cpp
Скачиваний:
0
Добавлен:
20.12.2024
Размер:
3.7 Кб
Скачать
#include <iostream> 

constexpr double a = -4;
constexpr double b = -1;
constexpr double c = 1;
constexpr double d = -4;
constexpr double e = -4;

constexpr double h = 0.1;

static double f(double x) 
{
    return a * pow(x, 4) + b * pow(x, 3) + c * pow(x, 2) + d * x + e;
}

static double first_derivative(double x)
{
    return  4 * a * pow(x, 3) + 3 * b * pow(x, 2) + 2 * c * x + d;
}

static double second_derivative(double x)
{
    return 12 * a * pow(x, 2) + 6 * b * x + 2 * c;
}

static double third_derivative(double x)
{
    return 24 * a * x + 6 * b;
}

static double fourth_derivative(double x)
{
    return 24 * a;
}

static double difference_derivative(double x)
{
    return (f(x + h) - f(x)) / h;
}

static double central_difference_derivative(double x)
{
    return (f(x + h) - f(x - h)) / (2. * h);
}

static double second_difference_derivative(double x)
{
    return (f(x - h) - 2 * f(x) + f(x + h)) / pow(h, 2);
}

template<typename Method, typename Derivative>
static double absolute_error_calculation(Method formula, Derivative der, double x)
{
    return std::abs(formula(x) - der(x));
}

static double calculate_M1(double x0, double x1)
{
    double crit_point = -b / (4. * a);
    if (crit_point < x0 || crit_point > x1)
        crit_point = x0;

    return std::max({ std::abs(second_derivative(x0)), std::abs(second_derivative(x1)), std::abs(second_derivative(crit_point)) });
}

static double marginal_error_for_difference_derivative(double x)
{
    double x0 = x;
    double x1 = x + h;

    return calculate_M1(x0, x1) * h / 2.;
}

static double marginal_error_for_central_difference(double x)
{
    double x0 = x - h;
    double x1 = x + h;
    double M2 = std::max(std::abs(third_derivative(x0)), std::abs(third_derivative(x1)));

    return  M2 * pow(h, 2) / 6.;
}

static double marginal_error_for_second_difference(double x)
{
    return pow(h, 2) / 12. * std::abs(fourth_derivative(24 * a)) + 0.000000001;
}

static void calculate_values()
{
    double exact_value, value, absolute_error, marginal_error, x, x0 = 0;
    int i;
    static auto print = [&](std::string str) {
        std::cout << "x_" << i << " = " << x <<
            "\n" << str <<
            "\n\tExact value: " << exact_value <<
            "\n\tValue: " << value <<
            "\n\tAbsolute error: " << absolute_error <<
            "\n\tMarginal error: " << marginal_error <<
            "\nDoes absolute error exceed marginal error? - " << std::boolalpha << 
            (absolute_error > marginal_error) << "\n\n"; };

    for (i = -2; i <= 2; ++i)
    {
        x = x0 + i * h;

        exact_value = first_derivative(x);
        value = difference_derivative(x);
        absolute_error = absolute_error_calculation(difference_derivative, first_derivative, x);
        marginal_error = marginal_error_for_difference_derivative(x);
        print("difference derivative");

        exact_value = first_derivative(x);
        value = central_difference_derivative(x);
        absolute_error = absolute_error_calculation(central_difference_derivative, first_derivative, x);
        marginal_error = marginal_error_for_central_difference(x);
        print("central difference derivative");

        exact_value = second_derivative(x);
        value = second_difference_derivative(x);
        absolute_error = absolute_error_calculation(second_difference_derivative, second_derivative, x);
        marginal_error = marginal_error_for_second_difference(x);
        print("second difference derivative");
    }
}

int main() 
{
    calculate_values();

    return 0;
}
Соседние файлы в папке ЛБ6