Добавил:
shaaydar
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:boundary
.jsfunction p(x) {
return 1 / (x**2 - 1)
}
function q(x) {
return 1 / Math.sqrt(1 - x**2)
}
/**
*
* @param {*} x
*/
function f(x) {
return -Math.sin(x) + p(x) * Math.cos(x) + q(x) * Math.sin(x)
}
/**
* Метод конечных разностей
* @param {number[]} X - список точек разбиения (n+1)
* @param {number} n - количество частичных отрезков
* @param {number} h - длина шага разбиения
*/
function process(X, n, h) {
// заданные c1, c2, d1, d2
const c1 = c2 = d1 = d2 = 1
//Конечные разности
const y0 = Math.sin(X[0])
const y1 = Math.sin(X[1])
const yn = Math.sin(X[n])
const yn1 = Math.sin(X[n-1])
// Краевые условия
const c = c1*y0 + c2*(y1 - y0)/ h
const d = d1*yn + d2*(yn - yn1)/ h
// разностные коэффициэнты
const beta = []
const gamma = []
const phi = []
const alpha = []
beta[0] = c1 * h - c2
gamma[0] = c2
phi[0] = h * c
for (let i = 1; i < n; i++) {
alpha[i] = 1 - (p(X[i]) * h / 2)
beta[i] = -2 + q(X[i])*(h**2)
gamma[i] = 1 + (p(X[i]) * h / 2)
phi[i] = h**2 * f(X[i])
}
alpha[n] = -d2
beta[n] = h*d1 + d2
phi[n] = h*d
// Прогоночные коэффициенты
const l = []
const u = []
l[0] = -gamma[0] / beta[0]
u[0] = phi[0] / beta[0]
// заполняем согласно рекуррентным формулам
for (let i = 1; i <= n; i++) {
l[i] = -gamma[i] / (beta[i] + alpha[i] * l[i-1])
u[i] = (phi[i] - alpha[i] * u[i-1]) / (beta[i] + alpha[i] * l[i-1])
}
const Y = []
Y[n] = u[n]
// Yi = li * Yi+1 + ui
for (let i = n-1; i >= 0; i--) {
Y[i] = l[i] * Y[i+1] + u[i]
}
return Y;
}
/**
* Краевая задача (ЛОДУ второго порядка, метод конечных разностей)
* тестовая задача
* y = sin x
* a = 0
* b = П/4
*/
function main() {
const a = 0
const b = Math.PI / 4
const result = []
for (let n = 2; Math.log2(n) < 20; n*=2) {
// длина шага
h = (b - a) / n
// разбиваем на частичные отрезки
const X = [a]
for (let i = 1; i < n; i++) {
X.push(a + i*h)
}
X.push(b)
// получаем значения y
const Y = process(X, n, h)
const deltaA = Math.abs(Math.sin(X[0]) - Y[0])
const deltaN2 = Math.abs(Math.sin(X[n/2]) - Y[n/2])
const deltaB = Math.abs(Math.sin(X[n]) - Y[n])
// Абсолютные погрешности в точках начало, середина и конец отрезка
result.push({
n,
"delta sin(0)": deltaA.toExponential(3),
"delta sin(π/8)": deltaN2.toExponential(3),
"delta sin(π/4)": deltaB.toExponential(3),
})
}
console.table(result)
}
main()
Соседние файлы в предмете Методы вычислений