Поиск значения второй производной функции в точке(Интерполирование куб.сплайнами)
Моя задача - найти значение второй производной функции в заданной точке. На вход я имею количество точек,точку в которой ищется производная,граничные условия,аргументы и значения функции в точках. Не могли бы вы подсказать, где я допустил ошибку в коде,ведь для функции-константы программы выдаёт неверный результат.
#include <iostream>
#include <fstream>
using namespace std;
struct dot {
double x, y;
};
//проверка упорядоченности агрументов функции
bool check_order(dot* X, int N) {
for (int i = 0; i < N - 1; i++)
if (X[i].x > X[i + 1].x)
return false;
return true;
}
int main()
{
setlocale(LC_ALL, "rus");
ifstream input("input.txt");
ofstream output("output.txt");
if (input && output) {
int N,IER = 0; //N - количество точек
double XX; //ХХ - точка в которой мы ищем значение второй производной
double A, B; //Граничные условия
double YY; //значение второй производной функции в т. ХХ
try {
//
// Ввод информации
//
input >> N >> XX;
input >> A >> B;
if (N < 3) throw - 1;
dot* X = new dot[N];
for (int i = 0; i < N; i++) //аргументы функции
input >> X[i].x;
if (!check_order(X, N)) throw true;
for (int i = 0; i < N; i++) //значение функции в заданных точках
input >> X[i].y;
//
//Получение данных для метода трехточечной прогонки
//
double* a = new double[N+1];
double* b = new double[N-2];
double* C = new double[N-2];
double* F = new double[N-2];
for (int i = 1; i < N-1; i++)
a[i] = X[i+1].x - X[i].x;
for (int i = 0; i < N - 2; i++)
F[i] = 6 * ((X[i + 2].y - X[i+1].y) / a[i + 1] - (X[i+1].y - X[i].y) / a[i]);
for (int i = 0; i < N - 2; i++) {
C[i] = -2 * (a[i] + a[i + 1]);
}
for (int i = 0; i < N-2; i++)
b[i] = a[i + 1];
double* alpha = new double[N+1];
double* v = new double[N+1];
double* z = new double[N+1];
alpha[0] = -0.5; alpha[N] = 0;
v[0] = 3 * ((X[1].y - X[0].y - A * a[0]) / a[0]) / a[0];
v[N] = B;
for (int k = 1; k <= N - 1; k++)
{
double temp = C[k] - a[k] * alpha[k - 1];
alpha[k] = b[k] / temp;
v[k] = (a[k] * v[k - 1] - F[k]) / temp;
}
z[N] = (alpha[N] * v[N - 1] + v[N]) / (1 - alpha[N] * alpha[N - 1]);
for (int k = N - 1; k > -1; k--)
z[k] = alpha[k] * z[k + 1] - v[k];
int number_otr = -1;
for (int i = 0; i < N; i++)
{
if (XX < X[i].x) {
number_otr = i - 1;
break;
}
}
if (number_otr < 0) throw 5.6;
YY = z[number_otr+1] + ((z[number_otr+1] - z[number_otr]) / a[number_otr+1]) * (XX - X[number_otr].x);
cout << YY;
}
catch (int) {
IER = 1;
cout << "IER = " << IER << "\nКубический сплайн не может быть построен ( N < 3)";
}
catch(bool){
IER = 2;
cout << "IER = " << IER << "\nНарушен порядок возрастания аргумента в входном векторе X";
}
catch (double)
{
IER = 3;
cout << "IER = " << IER << "\nТочка XX не принадлежит отрезку [x(1) ; x(N)]";
}
}
else
cout << "Ошибка";
}
Ответы (1 шт):
Автор решения: Миша Попов
→ Ссылка
#include <iostream>
#include <fstream>
#include <clocale>
using namespace std;
struct dot {
double x, y;
};
//проверка упорядоченности агрументов функции
bool check_order(dot* X, int N) {
for (int i = 0; i < N; i++)
if (X[i].x > X[i + 1].x)
return false;
return true;
}
int main()
{
setlocale(LC_ALL, "rus");
ifstream input("input.txt");
ofstream output("output.txt");
if (input && output) {
int m, IER = 0; //N - количество точек
double XX; //ХХ - точка в которой мы ищем значение второй производной
double A, B; //Граничные условия
double YY; //значение второй производной функции в т. ХХ
try {
//
// Ввод информации
//
input >> m >> XX;
input >> A >> B;
if (m < 3) throw - 1;
dot* X = new dot[m];
for (int i = 0; i < m; i++) //аргументы функции
input >> X[i].x;
if (!check_order(X, m - 1)) throw true;
for (int i = 0; i < m; i++) //значение функции в заданных точках
input >> X[i].y;
//
//Получение данных для метода трехточечной прогонки
//
double* a = new double[m];
double* b = new double[m-1];
double* c = new double[m-1];
double* F = new double[m-1];
for (int i = 1; i <= m - 1; i++)
a[i] = X[i].x - X[i - 1].x;
for (int i = 1; i <= m - 2; i++)
F[i] = 6 * ((X[i + 1].y - X[i].y) / a[i + 1] - (X[i].y - X[i - 1].y) / a[i]);
for (int i = 1; i <= m - 2; i++) {
c[i] = -2 * (a[i] + a[i + 1]);
}
for (int i = 1; i <= m - 2; i++)
b[i] = a[i + 1];
double* alpha = new double[m];
double* beta = new double[m];
double* z = new double[m];
alpha[0] = -0.5; alpha[N] = 0;
beta[0] = 33 * ((X[1].y - X[0].y - A * a[0]) / a[0]) / a[0];
beta[m - 1] = B;
for (int k = 1; k <= m - 2; k++)
{
double temp = 1 / (c[k] - a[k] * alpha[k - 1]);
alpha[k] = b[k] * temp;
beta[k] = (a[k] * beta[k - 1] - F[k]) * temp;
}
z[m - 1] = (beta[m - 1] + alpha[m - 1] * beta[m - 2]) / (1 - alpha[m - 1] * alpha[m - 2]);
for (int k = m - 2; k > -1; k--)
z[k] = alpha[k] * z[k + 1] + beta[k];
int number_otr = -1;
for (int i = 0; i <= m-1; i++)
{
if (XX < X[i].x) {
number_otr = i - 1;
break;
}
}
if (number_otr < 0 || number_otr > m-1) throw 5.6;
YY = z[number_otr + 1] + ((z[number_otr + 1] - z[number_otr]) / a[number_otr + 1]) * (XX - X[number_otr + 1].x);
output << "Значение второй производной функции YY = " << YY << "\nИндикатор ошибки IER = " << IER;
}
catch (int) {
IER = 1;
cout << "IER = " << IER << "\nКубический сплайн не может быть построен ( N < 3)";
}
catch (bool) {
IER = 2;
cout << "IER = " << IER << "\nНарушен порядок возрастания аргумента в входном векторе X";
}
catch (double)
{
IER = 3;
cout << "IER = " << IER << "\nТочка XX не принадлежит отрезку [x(1) ; x(N)]";
}
}
else
cout << "Ошибка";
}