Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

boundary

.js
Скачиваний:
11
Добавлен:
31.03.2021
Размер:
3.23 Кб
Скачать
function 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()
Соседние файлы в предмете Методы вычислений