Добавил:
shaaydar
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:interpolation
.js// Заданная функция
function f(x) {
return Math.sin(x)
}
// Вторая производная заданной функции
function fDerivative2(x) {
return -Math.sin(x);
}
/**
* Кубический сплайн
* @param {number} x - текущий аргумент
* @param {number} i - номер точки
* @param {number[]} M - массив вторых производных кубического сплайна, M[i] = S3''[i]
* @param {number[]} X - массив аргументов
*/
function S3(x, i, h, M, X) {
return M[i-1] * ((X[i]-x)**3 - h**2 * (X[i] - x)) / (6*h)
+ M[i] * ((x - X[i-1])**3 - h**2 * (x - X[i-1])) / (6*h)
+ f(X[i-1]) * (X[i] - x) / h
+ f(X[i]) * (x - X[i-1]) / h
}
/**
* Метод прогонки
* краевые условия S3''(a)=f''(a), S3''(b)=f''(b)
* @param {Function} f - заданная функция
* @param {Function} der2 - 2 производная заданной функции
* @param {number} f0 - начало отрезка
* @param {number} fn - конец отрезка
* @param {number} h - длина шага
* @param {number} n - кол-во частичных отрезков
* @param {number[]} X - массив аргументов
* @returns {number[]} M - массив вторых производных кубического сплайна
*/
function TMA(f, der2, f0, fn, h, n, X) {
// согласно краевым условиям
ai = 2 * h / 3
bi = h / 6
ci = h / 6
a0 = 1
b0 = 0
an = 1
cn = 0
// правая часть СЛУ
const d = []
d[0] = der2(f0) // f''(0) = -sin(0)
d[n] = der2(fn) // f''(Pi) = -sin(Pi)
// Yi = (Yi+1 - Yi)/h - (Yi - Yi-1)/h
for (let i = 1; i < n; i++) {
d[i] = (f(X[i+1]) - f(X[i]))/h - (f(X[i]) - f(X[i-1]))/h
}
// Прогоночные коэффициенты
const l = []
const u = []
l[0] = -b0 / a0 // 0
u[0] = d[0] / a0 // 0
// заполняем согласно рекуррентным формулам
for (let i = 1; i < n; i++) {
l[i] = -bi / (ai + ci * l[i-1])
u[i] = (d[i] - ci * u[i-1]) / (ai + ci * l[i-1])
}
// и крайнюю точку
l[n] = -bi / (an + cn * l[n-1])
u[n] = (d[n] - cn * u[n-1]) / (an + cn * l[n-1])
const M = []
M[n] = u[n] // т.к. bn=0
// Mi = li * Mi+1 + ui
for (let i = n-1; i >= 0; i--) {
M[i] = l[i] * M[i+1] + u[i]
}
return M;
}
function main() {
const a = 0
const b = Math.PI
const result = []
let prevMax = 0
let h
for (let n = 5; n <= 5120; n *= 2) {
// длина шага
h = (b - a) / n
// разбиваем на частичные отрезки
const X = [a]
for (let i = 1; i < n; i++) {
X.push(a + i*h)
}
X.push(b)
// получаем вторые производные кубического сплайна методом прогонки
const M = TMA(f, fDerivative2, a, b, h, n, X)
let deltaMax = 0
let ocenka = 0
for (let i = 1; i < n+1; i++) {
// |S3(x) - f(x)| в серединах частичных отрезков
const s3 = S3(X[i-1] + h/2, i, h, M, X)
ocenka = Math.abs(s3 - f(X[i-1] + h/2))
deltaMax = Math.max(deltaMax, ocenka)
}
result.push({
// кол-во частичных отрезков
n,
// максимальная погрешность
deltaMax,
// оценка погрешности (четвертый порядок точности)
deltaOc: prevMax / (2**4),
// отношение погрешности пред. строки к текущей
K: prevMax / deltaMax,
})
prevMax = deltaMax
}
console.table(result)
}
main()
Соседние файлы в предмете Методы вычислений