#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h> // Для параллельных вычислений
// Целевая функция
double target_function(double x) {
return (x
* x
- sin(x
)) * cos(2.5 * x
); }
// Вычисление полиномов Лежандра
void compute_legendre_polynomials(double* polynomials, int degree, double x) {
polynomials[0] = 1; // P0(x)
if (degree > 0) {
polynomials[1] = x; // P1(x)
}
for (int n = 2; n <= degree; n++) {
polynomials[n] = ((2 * n - 1) * x * polynomials[n - 1] - (n - 1) * polynomials[n - 2]) / n;
}
}
// Интегрирование методом трапеций
double trapezoidal_integration(double (*func)(double, int, int), int i, int j, double a, double b, int steps) {
double h = (b - a) / steps;
double sum = 0.0;
for (int k = 0; k <= steps; k++) {
double x = a + k * h;
double weight = (k == 0 || k == steps) ? 0.5 : 1.0;
sum += weight * func(x, i, j);
}
return sum * h;
}
// Вычисление произведения полиномов Лежандра
double legendre_product(double x, int i, int j) {
double polynomials[50]; // Ограничение на степень
compute_legendre_polynomials(polynomials, fmax(i, j), x);
return polynomials[i] * polynomials[j];
}
// Вычисление произведения целевой функции и полинома Лежандра
double target_product(double x, int i, int j) {
double polynomials[50]; // Ограничение на степень
compute_legendre_polynomials(polynomials, i, x);
return target_function(x) * polynomials[i];
}
// Построение нормальной матрицы и вектора правой части
void build_normal_matrix(double* matrix, double* rhs, int degree, double a, double b, int steps) {
#pragma omp parallel for
for (int i = 0; i <= degree; i++) {
for (int j = i; j <= degree; j++) { // Используем симметрию
double value = trapezoidal_integration(legendre_product, i, j, a, b, steps);
matrix[i * (degree + 1) + j] = value;
if (i != j) {
matrix[j * (degree + 1) + i] = value;
}
}
rhs[i] = trapezoidal_integration(target_product, i, 0, a, b, steps);
}
}
// Метод Гаусса с выбором главного элемента
void gauss_elimination(double* matrix, double* rhs, double* solution, int size) {
for (int i = 0; i < size; i++) {
int max_row = i;
for (int k = i + 1; k < size; k++) {
if (fabs(matrix
[k
* size
+ i
]) > fabs(matrix
[max_row
* size
+ i
])) { max_row = k;
}
}
for (int k = i; k < size; k++) {
double temp = matrix[i * size + k];
matrix[i * size + k] = matrix[max_row * size + k];
matrix[max_row * size + k] = temp;
}
double temp = rhs[i];
rhs[i] = rhs[max_row];
rhs[max_row] = temp;
for (int k = i + 1; k < size; k++) {
double factor = matrix[k * size + i] / matrix[i * size + i];
rhs[k] -= factor * rhs[i];
for (int j = i; j < size; j++) {
matrix[k * size + j] -= factor * matrix[i * size + j];
}
}
}
for (int i = size - 1; i >= 0; i--) {
solution[i] = rhs[i] / matrix[i * size + i];
for (int k = i - 1; k >= 0; k--) {
rhs[k] -= matrix[k * size + i] * solution[i];
}
}
}
// Оценка среднеквадратичной ошибки
double calculate_error(double* coeffs, int degree, double a, double b, int steps) {
double error = 0;
double step = (b - a) / steps;
for (int i = 0; i <= steps; i++) {
double x = a + i * step;
double approx = 0;
double polynomials[50];
compute_legendre_polynomials(polynomials, degree, x);
for (int j = 0; j <= degree; j++) {
approx += coeffs[j] * polynomials[j];
}
error
+= pow(target_function
(x
) - approx
, 2); }
return sqrt(error
/ (steps
+ 1)); }
// Сохранение коэффициентов в файл
void save_coefficients_to_file(const double* coeffs, int degree) {
FILE
* file
= fopen("coefficients.txt", "w"); if (!file) {
printf("Не удалось открыть файл для записи коэффициентов.\n"); return;
}
fprintf(file
, "Коэффициенты многочлена Лежандра (степень %d):\n", degree
); for (int i = 0; i <= degree; i++) {
fprintf(file
, "a[%d] = %lf\n", i
, coeffs
[i
]); }
printf("Коэффициенты успешно сохранены в файл coefficients.txt\n"); }
int main() {
int max_degree = 40;
double a = 0, b = 7;
int steps = 1000;
double tolerance = 0.01;
for (int degree = 1; degree <= max_degree; degree++) {
double* matrix
= (double*)malloc((degree
+ 1) * (degree
+ 1) * sizeof(double)); double* rhs
= (double*)malloc((degree
+ 1) * sizeof(double)); double* coeffs
= (double*)malloc((degree
+ 1) * sizeof(double));
build_normal_matrix(matrix, rhs, degree, a, b, steps);
gauss_elimination(matrix, rhs, coeffs, degree + 1);
double error = calculate_error(coeffs, degree, a, b, steps);
printf("Degree: %d, Error: %lf\n", degree
, error
);
if (error <= tolerance) {
printf("Optimal degree: %d\n", degree
); save_coefficients_to_file(coeffs, degree);
break;
}
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KI2luY2x1ZGUgPG9tcC5oPiAvLyDQlNC70Y8g0L/QsNGA0LDQu9C70LXQu9GM0L3Ri9GFINCy0YvRh9C40YHQu9C10L3QuNC5CgovLyDQptC10LvQtdCy0LDRjyDRhNGD0L3QutGG0LjRjwpkb3VibGUgdGFyZ2V0X2Z1bmN0aW9uKGRvdWJsZSB4KSB7CiAgICByZXR1cm4gKHggKiB4IC0gc2luKHgpKSAqIGNvcygyLjUgKiB4KTsKfQoKLy8g0JLRi9GH0LjRgdC70LXQvdC40LUg0L/QvtC70LjQvdC+0LzQvtCyINCb0LXQttCw0L3QtNGA0LAKdm9pZCBjb21wdXRlX2xlZ2VuZHJlX3BvbHlub21pYWxzKGRvdWJsZSogcG9seW5vbWlhbHMsIGludCBkZWdyZWUsIGRvdWJsZSB4KSB7CiAgICBwb2x5bm9taWFsc1swXSA9IDE7IC8vIFAwKHgpCiAgICBpZiAoZGVncmVlID4gMCkgewogICAgICAgIHBvbHlub21pYWxzWzFdID0geDsgLy8gUDEoeCkKICAgIH0KICAgIGZvciAoaW50IG4gPSAyOyBuIDw9IGRlZ3JlZTsgbisrKSB7CiAgICAgICAgcG9seW5vbWlhbHNbbl0gPSAoKDIgKiBuIC0gMSkgKiB4ICogcG9seW5vbWlhbHNbbiAtIDFdIC0gKG4gLSAxKSAqIHBvbHlub21pYWxzW24gLSAyXSkgLyBuOwogICAgfQp9CgovLyDQmNC90YLQtdCz0YDQuNGA0L7QstCw0L3QuNC1INC80LXRgtC+0LTQvtC8INGC0YDQsNC/0LXRhtC40LkKZG91YmxlIHRyYXBlem9pZGFsX2ludGVncmF0aW9uKGRvdWJsZSAoKmZ1bmMpKGRvdWJsZSwgaW50LCBpbnQpLCBpbnQgaSwgaW50IGosIGRvdWJsZSBhLCBkb3VibGUgYiwgaW50IHN0ZXBzKSB7CiAgICBkb3VibGUgaCA9IChiIC0gYSkgLyBzdGVwczsKICAgIGRvdWJsZSBzdW0gPSAwLjA7CgogICAgZm9yIChpbnQgayA9IDA7IGsgPD0gc3RlcHM7IGsrKykgewogICAgICAgIGRvdWJsZSB4ID0gYSArIGsgKiBoOwogICAgICAgIGRvdWJsZSB3ZWlnaHQgPSAoayA9PSAwIHx8IGsgPT0gc3RlcHMpID8gMC41IDogMS4wOwogICAgICAgIHN1bSArPSB3ZWlnaHQgKiBmdW5jKHgsIGksIGopOwogICAgfQoKICAgIHJldHVybiBzdW0gKiBoOwp9CgovLyDQktGL0YfQuNGB0LvQtdC90LjQtSDQv9GA0L7QuNC30LLQtdC00LXQvdC40Y8g0L/QvtC70LjQvdC+0LzQvtCyINCb0LXQttCw0L3QtNGA0LAKZG91YmxlIGxlZ2VuZHJlX3Byb2R1Y3QoZG91YmxlIHgsIGludCBpLCBpbnQgaikgewogICAgZG91YmxlIHBvbHlub21pYWxzWzUwXTsgLy8g0J7Qs9GA0LDQvdC40YfQtdC90LjQtSDQvdCwINGB0YLQtdC/0LXQvdGMCiAgICBjb21wdXRlX2xlZ2VuZHJlX3BvbHlub21pYWxzKHBvbHlub21pYWxzLCBmbWF4KGksIGopLCB4KTsKICAgIHJldHVybiBwb2x5bm9taWFsc1tpXSAqIHBvbHlub21pYWxzW2pdOwp9CgovLyDQktGL0YfQuNGB0LvQtdC90LjQtSDQv9GA0L7QuNC30LLQtdC00LXQvdC40Y8g0YbQtdC70LXQstC+0Lkg0YTRg9C90LrRhtC40Lgg0Lgg0L/QvtC70LjQvdC+0LzQsCDQm9C10LbQsNC90LTRgNCwCmRvdWJsZSB0YXJnZXRfcHJvZHVjdChkb3VibGUgeCwgaW50IGksIGludCBqKSB7CiAgICBkb3VibGUgcG9seW5vbWlhbHNbNTBdOyAvLyDQntCz0YDQsNC90LjRh9C10L3QuNC1INC90LAg0YHRgtC10L/QtdC90YwKICAgIGNvbXB1dGVfbGVnZW5kcmVfcG9seW5vbWlhbHMocG9seW5vbWlhbHMsIGksIHgpOwogICAgcmV0dXJuIHRhcmdldF9mdW5jdGlvbih4KSAqIHBvbHlub21pYWxzW2ldOwp9CgovLyDQn9C+0YHRgtGA0L7QtdC90LjQtSDQvdC+0YDQvNCw0LvRjNC90L7QuSDQvNCw0YLRgNC40YbRiyDQuCDQstC10LrRgtC+0YDQsCDQv9GA0LDQstC+0Lkg0YfQsNGB0YLQuAp2b2lkIGJ1aWxkX25vcm1hbF9tYXRyaXgoZG91YmxlKiBtYXRyaXgsIGRvdWJsZSogcmhzLCBpbnQgZGVncmVlLCBkb3VibGUgYSwgZG91YmxlIGIsIGludCBzdGVwcykgewogICAgI3ByYWdtYSBvbXAgcGFyYWxsZWwgZm9yCiAgICBmb3IgKGludCBpID0gMDsgaSA8PSBkZWdyZWU7IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSBpOyBqIDw9IGRlZ3JlZTsgaisrKSB7IC8vINCY0YHQv9C+0LvRjNC30YPQtdC8INGB0LjQvNC80LXRgtGA0LjRjgogICAgICAgICAgICBkb3VibGUgdmFsdWUgPSB0cmFwZXpvaWRhbF9pbnRlZ3JhdGlvbihsZWdlbmRyZV9wcm9kdWN0LCBpLCBqLCBhLCBiLCBzdGVwcyk7CiAgICAgICAgICAgIG1hdHJpeFtpICogKGRlZ3JlZSArIDEpICsgal0gPSB2YWx1ZTsKICAgICAgICAgICAgaWYgKGkgIT0gaikgewogICAgICAgICAgICAgICAgbWF0cml4W2ogKiAoZGVncmVlICsgMSkgKyBpXSA9IHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJoc1tpXSA9IHRyYXBlem9pZGFsX2ludGVncmF0aW9uKHRhcmdldF9wcm9kdWN0LCBpLCAwLCBhLCBiLCBzdGVwcyk7CiAgICB9Cn0KCi8vINCc0LXRgtC+0LQg0JPQsNGD0YHRgdCwINGBINCy0YvQsdC+0YDQvtC8INCz0LvQsNCy0L3QvtCz0L4g0Y3Qu9C10LzQtdC90YLQsAp2b2lkIGdhdXNzX2VsaW1pbmF0aW9uKGRvdWJsZSogbWF0cml4LCBkb3VibGUqIHJocywgZG91YmxlKiBzb2x1dGlvbiwgaW50IHNpemUpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CiAgICAgICAgaW50IG1heF9yb3cgPSBpOwogICAgICAgIGZvciAoaW50IGsgPSBpICsgMTsgayA8IHNpemU7IGsrKykgewogICAgICAgICAgICBpZiAoZmFicyhtYXRyaXhbayAqIHNpemUgKyBpXSkgPiBmYWJzKG1hdHJpeFttYXhfcm93ICogc2l6ZSArIGldKSkgewogICAgICAgICAgICAgICAgbWF4X3JvdyA9IGs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgayA9IGk7IGsgPCBzaXplOyBrKyspIHsKICAgICAgICAgICAgZG91YmxlIHRlbXAgPSBtYXRyaXhbaSAqIHNpemUgKyBrXTsKICAgICAgICAgICAgbWF0cml4W2kgKiBzaXplICsga10gPSBtYXRyaXhbbWF4X3JvdyAqIHNpemUgKyBrXTsKICAgICAgICAgICAgbWF0cml4W21heF9yb3cgKiBzaXplICsga10gPSB0ZW1wOwogICAgICAgIH0KICAgICAgICBkb3VibGUgdGVtcCA9IHJoc1tpXTsKICAgICAgICByaHNbaV0gPSByaHNbbWF4X3Jvd107CiAgICAgICAgcmhzW21heF9yb3ddID0gdGVtcDsKCiAgICAgICAgZm9yIChpbnQgayA9IGkgKyAxOyBrIDwgc2l6ZTsgaysrKSB7CiAgICAgICAgICAgIGRvdWJsZSBmYWN0b3IgPSBtYXRyaXhbayAqIHNpemUgKyBpXSAvIG1hdHJpeFtpICogc2l6ZSArIGldOwogICAgICAgICAgICByaHNba10gLT0gZmFjdG9yICogcmhzW2ldOwogICAgICAgICAgICBmb3IgKGludCBqID0gaTsgaiA8IHNpemU7IGorKykgewogICAgICAgICAgICAgICAgbWF0cml4W2sgKiBzaXplICsgal0gLT0gZmFjdG9yICogbWF0cml4W2kgKiBzaXplICsgal07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmb3IgKGludCBpID0gc2l6ZSAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgc29sdXRpb25baV0gPSByaHNbaV0gLyBtYXRyaXhbaSAqIHNpemUgKyBpXTsKICAgICAgICBmb3IgKGludCBrID0gaSAtIDE7IGsgPj0gMDsgay0tKSB7CiAgICAgICAgICAgIHJoc1trXSAtPSBtYXRyaXhbayAqIHNpemUgKyBpXSAqIHNvbHV0aW9uW2ldOwogICAgICAgIH0KICAgIH0KfQoKLy8g0J7RhtC10L3QutCwINGB0YDQtdC00L3QtdC60LLQsNC00YDQsNGC0LjRh9C90L7QuSDQvtGI0LjQsdC60LgKZG91YmxlIGNhbGN1bGF0ZV9lcnJvcihkb3VibGUqIGNvZWZmcywgaW50IGRlZ3JlZSwgZG91YmxlIGEsIGRvdWJsZSBiLCBpbnQgc3RlcHMpIHsKICAgIGRvdWJsZSBlcnJvciA9IDA7CiAgICBkb3VibGUgc3RlcCA9IChiIC0gYSkgLyBzdGVwczsKICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ZXBzOyBpKyspIHsKICAgICAgICBkb3VibGUgeCA9IGEgKyBpICogc3RlcDsKICAgICAgICBkb3VibGUgYXBwcm94ID0gMDsKICAgICAgICBkb3VibGUgcG9seW5vbWlhbHNbNTBdOwogICAgICAgIGNvbXB1dGVfbGVnZW5kcmVfcG9seW5vbWlhbHMocG9seW5vbWlhbHMsIGRlZ3JlZSwgeCk7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gZGVncmVlOyBqKyspIHsKICAgICAgICAgICAgYXBwcm94ICs9IGNvZWZmc1tqXSAqIHBvbHlub21pYWxzW2pdOwogICAgICAgIH0KICAgICAgICBlcnJvciArPSBwb3codGFyZ2V0X2Z1bmN0aW9uKHgpIC0gYXBwcm94LCAyKTsKICAgIH0KICAgIHJldHVybiBzcXJ0KGVycm9yIC8gKHN0ZXBzICsgMSkpOwp9CgovLyDQodC+0YXRgNCw0L3QtdC90LjQtSDQutC+0Y3RhNGE0LjRhtC40LXQvdGC0L7QsiDQsiDRhNCw0LnQuwp2b2lkIHNhdmVfY29lZmZpY2llbnRzX3RvX2ZpbGUoY29uc3QgZG91YmxlKiBjb2VmZnMsIGludCBkZWdyZWUpIHsKICAgIEZJTEUqIGZpbGUgPSBmb3BlbigiY29lZmZpY2llbnRzLnR4dCIsICJ3Iik7CiAgICBpZiAoIWZpbGUpIHsKICAgICAgICBwcmludGYoItCd0LUg0YPQtNCw0LvQvtGB0Ywg0L7RgtC60YDRi9GC0Ywg0YTQsNC50Lsg0LTQu9GPINC30LDQv9C40YHQuCDQutC+0Y3RhNGE0LjRhtC40LXQvdGC0L7Qsi5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZwcmludGYoZmlsZSwgItCa0L7RjdGE0YTQuNGG0LjQtdC90YLRiyDQvNC90L7Qs9C+0YfQu9C10L3QsCDQm9C10LbQsNC90LTRgNCwICjRgdGC0LXQv9C10L3RjCAlZCk6XG4iLCBkZWdyZWUpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gZGVncmVlOyBpKyspIHsKICAgICAgICBmcHJpbnRmKGZpbGUsICJhWyVkXSA9ICVsZlxuIiwgaSwgY29lZmZzW2ldKTsKICAgIH0KICAgIGZjbG9zZShmaWxlKTsKICAgIHByaW50Zigi0JrQvtGN0YTRhNC40YbQuNC10L3RgtGLINGD0YHQv9C10YjQvdC+INGB0L7RhdGA0LDQvdC10L3RiyDQsiDRhNCw0LnQuyBjb2VmZmljaWVudHMudHh0XG4iKTsKfQoKaW50IG1haW4oKSB7CiAgICBpbnQgbWF4X2RlZ3JlZSA9IDQwOwogICAgZG91YmxlIGEgPSAwLCBiID0gNzsKICAgIGludCBzdGVwcyA9IDEwMDA7CiAgICBkb3VibGUgdG9sZXJhbmNlID0gMC4wMTsKCiAgICBmb3IgKGludCBkZWdyZWUgPSAxOyBkZWdyZWUgPD0gbWF4X2RlZ3JlZTsgZGVncmVlKyspIHsKICAgICAgICBkb3VibGUqIG1hdHJpeCA9IChkb3VibGUqKW1hbGxvYygoZGVncmVlICsgMSkgKiAoZGVncmVlICsgMSkgKiBzaXplb2YoZG91YmxlKSk7CiAgICAgICAgZG91YmxlKiByaHMgPSAoZG91YmxlKiltYWxsb2MoKGRlZ3JlZSArIDEpICogc2l6ZW9mKGRvdWJsZSkpOwogICAgICAgIGRvdWJsZSogY29lZmZzID0gKGRvdWJsZSopbWFsbG9jKChkZWdyZWUgKyAxKSAqIHNpemVvZihkb3VibGUpKTsKCiAgICAgICAgYnVpbGRfbm9ybWFsX21hdHJpeChtYXRyaXgsIHJocywgZGVncmVlLCBhLCBiLCBzdGVwcyk7CiAgICAgICAgZ2F1c3NfZWxpbWluYXRpb24obWF0cml4LCByaHMsIGNvZWZmcywgZGVncmVlICsgMSk7CgogICAgICAgIGRvdWJsZSBlcnJvciA9IGNhbGN1bGF0ZV9lcnJvcihjb2VmZnMsIGRlZ3JlZSwgYSwgYiwgc3RlcHMpOwogICAgICAgIHByaW50ZigiRGVncmVlOiAlZCwgRXJyb3I6ICVsZlxuIiwgZGVncmVlLCBlcnJvcik7CgogICAgICAgIGlmIChlcnJvciA8PSB0b2xlcmFuY2UpIHsKICAgICAgICAgICAgcHJpbnRmKCJPcHRpbWFsIGRlZ3JlZTogJWRcbiIsIGRlZ3JlZSk7CiAgICAgICAgICAgIHNhdmVfY29lZmZpY2llbnRzX3RvX2ZpbGUoY29lZmZzLCBkZWdyZWUpOwogICAgICAgICAgICBmcmVlKG1hdHJpeCk7CiAgICAgICAgICAgIGZyZWUocmhzKTsKICAgICAgICAgICAgZnJlZShjb2VmZnMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZnJlZShtYXRyaXgpOwogICAgICAgIGZyZWUocmhzKTsKICAgICAgICBmcmVlKGNvZWZmcyk7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0K
Degree: 1, Error: 14.201725
Degree: 2, Error: 13.406704
Degree: 3, Error: 12.933561
Degree: 4, Error: 12.913922
Degree: 5, Error: 12.066789
Degree: 6, Error: 8.047765
Degree: 7, Error: 5.736353
Degree: 8, Error: 5.127578
Degree: 9, Error: 1.782684
Degree: 10, Error: 1.674198
Degree: 11, Error: 0.563190
Degree: 12, Error: 0.363394
Degree: 13, Error: 0.349523
Degree: 14, Error: 0.245960
Degree: 15, Error: 0.896356
Degree: 16, Error: 0.097016
Degree: 17, Error: 0.115056
Degree: 18, Error: 0.126031
Degree: 19, Error: 0.171374
Degree: 20, Error: 0.068058
Degree: 21, Error: 0.064201
Degree: 22, Error: 0.058142
Degree: 23, Error: 0.069285
Degree: 24, Error: 0.120590
Degree: 25, Error: 0.078761
Degree: 26, Error: 0.136907
Degree: 27, Error: 0.042303
Degree: 28, Error: 0.132902
Degree: 29, Error: 0.082553
Degree: 30, Error: 0.055851
Degree: 31, Error: 0.153969
Degree: 32, Error: 0.045659
Degree: 33, Error: 0.104272
Degree: 34, Error: 0.104347
Degree: 35, Error: 0.050368
Degree: 36, Error: 0.043915
Degree: 37, Error: 0.026945
Degree: 38, Error: 0.048973
Degree: 39, Error: 0.181343
Degree: 40, Error: 0.108479