Загрузка данных


#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

// Точная функция для Варианта 3: f(x) = 2.1 * sin(0.37 * x)
double exactFunc(double x) {
    return 2.1 * sin(0.37 * x);
}

// Автоматический выбор 3 ближайших узлов для квадратичной интерполяции
void selectNodes(double x, const double X[], const double Y[], int n, double x_nodes[], double y_nodes[]) {
    // Создаем массив индексов
    int idx[7];
    for (int i = 0; i < n; i++) {
        idx[i] = i;
    }

    // Простая сортировка пузырьком индексов по расстоянию от X[i] до точки x
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (abs(X[idx[j]] - x) > abs(X[idx[j + 1]] - x)) {
                int temp = idx[j];
                idx[j] = idx[j + 1];
                idx[j + 1] = temp;
            }
        }
    }

    // Берем первые 3 самых близких узла и упорядочиваем их по возрастанию X
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2 - i; j++) {
            if (idx[j] > idx[j + 1]) {
                int temp = idx[j];
                idx[j] = idx[j + 1];
                idx[j + 1] = temp;
            }
        }
    }

    for (int i = 0; i < 3; i++) {
        x_nodes[i] = X[idx[i]];
        y_nodes[i] = Y[idx[i]];
    }
}

// Вычисление квадратичного многочлена Лагранжа L2(x) по 3 узлам
double lagrangeQuadratic(double x, const double x_nodes[], const double y_nodes[]) {
    double sum = 0.0;
    for (int i = 0; i < 3; i++) {
        double p = 1.0;
        for (int j = 0; j < 3; j++) {
            if (i != j) {
                p = p * (x - x_nodes[j]) / (x_nodes[i] - x_nodes[j]);
            }
        }
        sum = sum + y_nodes[i] * p;
    }
    return sum;
}

// Оценка теоретической погрешности R2(x) <= (M3 / 3!) * |(x - x0)(x - x1)(x - x2)|
// Третья производная: f'''(x) = -2.1 * (0.37)^3 * cos(0.37 * x)
double estimateError(double x, const double x_nodes[]) {
    double a = x_nodes[0];
    double b = x_nodes[2];
    if (x < a) a = x;
    if (x > b) b = x;

    // Находим максимум |f'''(t)| на отрезке [a, b]
    double M3 = 0.0;
    double coef = 2.1 * pow(0.37, 3); // ~ 0.1063713
    int steps = 1000;
    double step = (b - a) / steps;
    for (int i = 0; i <= steps; i++) {
        double t = a + i * step;
        double d3 = abs(-coef * cos(0.37 * t));
        if (d3 > M3) {
            M3 = d3;
        }
    }

    double omega = abs((x - x_nodes[0]) * (x - x_nodes[1]) * (x - x_nodes[2]));
    return (M3 / 6.0) * omega; // 3! = 6
}

int main() {
    setlocale(LC_ALL, "Russian");

    const int N = 7;
    // Исходная таблица Варианта 3
    double X[N] = {-3.2, -0.8, 0.4, 2.8, 4.0, 6.4, 7.6};
    double Y[N] = {-1.9449, -0.6126, 0.3097, 1.8068, 2.0913, 1.4673, 0.6797};

    double x;
    cout << "Введите значение x для интерполяции (например, 1.5): ";
    if (!(cin >> x)) return 0;

    double x_nodes[3], y_nodes[3];
    selectNodes(x, X, Y, N, x_nodes, y_nodes);

    double approx_val = lagrangeQuadratic(x, x_nodes, y_nodes);
    double exact_val = exactFunc(x);
    double exact_err = abs(exact_val - approx_val);
    double est_err = estimateError(x, x_nodes);

    cout << fixed << setprecision(6);
    cout << "\n--- Результаты вычислений (Вариант 3) ---\n";
    cout << "Выбранные узлы интерполяции:\n";
    for (int i = 0; i < 3; i++) {
        cout << "  x" << i << " = " << setw(6) << setprecision(2) << x_nodes[i]
             << ", y" << i << " = " << setw(8) << setprecision(4) << y_nodes[i] << "\n";
    }

    cout << setprecision(6);
    cout << "\nТочка интерполяции x          = " << x << "\n";
    cout << "Приближенное значение L2(x)   = " << approx_val << "\n";
    cout << "Точное значение функции f(x)  = " << exact_val << "\n";
    cout << "Точная (фактическая) погр.    = " << exact_err << "\n";
    cout << "Оценка погрешности R2(x)      = " << est_err << "\n";

    return 0;
}