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

integral

.js
Скачиваний:
10
Добавлен:
31.03.2021
Размер:
4.62 Кб
Скачать
// Точность вывода на экран
const signs = 5

/**
 * Получить численное значение интеграла при заданном разбиении
 * @param {Object} params 
 * @param {Function} params.f - интегрируемая функция
 * @param {number} params.a - начало отрезка
 * @param {number} params.b - конец отрезка
 * @param {number} n - заданное разбиение
 * @returns {number}
 */
function numIntegral({f, a, b}, n) {
    const h = (b - a) / n

    // заполняем узловые точки
    const x = []
    for (let i = 0; i <= n; i++) {
        x.push(a+i*h)  
    }

    let sum1 = 0;
    for (let i = 1; i < n; i++) {
        sum1 += f(x[i])
    }
    let sum2 = 0;
    for (let i = 0; i < n; i++) {
        sum2 += f(x[i] + h/2)
    }

    // Квадратурная формула Ньютона-Котеса
    // метод парабол
    return (h/6) * (f(a) + f(b) + 2*sum1 + 4*sum2) 
}

/**
 * Получить результаты приближенного счета со всеми значениями, 
 * начиная с n=2, и их погрешность по методу парабол
 * @param {object} params
 * @param {Function} params.f - заданная функция
 * @param {number} params.a - начало отрезка
 * @param {number} params.b - конец отрезка
 * @param {number | undefined} params.exactIntegral - точное значение интеграла
 * @param {number | undefined} params.c - c
 * @param {number} e - заданная точность
 * @returns {object[]}
 */
function process(param, e) {
    const result = []
    let runge = -1
    let integral, integralH2, integralH4

    // Порядок точности метода парабол
    const k = 4 
    
    for (let n = 2; Math.abs(runge) > e; n*=2) {
        integral = numIntegral(param, n)
        integralH2 = numIntegral(param, n*2)
        integralH4 = numIntegral(param, n*4)
        integralDiv2 = numIntegral(param, n/2)
        runge = (integral - integralDiv2) / (2**k - 1) 

        const row = {
            // Разбиение отрезка [a,b] на n узлов
            n: n, 

            // Значение интеграла при разбиении = n
            integral: integral, 

            // Коэффициент уменьшения погрешности 
            deltaK: (integralH2 - integral) / (integralH4 - integralH2), 

            // Оценка по Рунге, (J(h/2) - Jh) / 2^k - 1
            deltaRunge: runge.toExponential(signs) 
        }
        if (param.exactIntegral) {
            row.deltaExact = Math.abs(param.exactIntegral - integral).toExponential(signs)
        }
        if (param.c) {
            const h = (param.b - param.a) / n
            row.deltaTheory = (Math.abs(param.c * (h**k))).toExponential(signs)
        }
        result.push(row)
    }
    return result
}

function main() {
    // заданная точность
    const e = 1e-7

    // отладочный пример
    const test = {
        f: (x) => {
            return 6*(x**5)
        },
        a: 0,
        b: 1,
        exactIntegral: 1,//32/3, // Точное значение определенного интеграла x^5 на [0,2]
        c: 720/2880
    }

    const resultTest = process(test, e)
    const integralTest = resultTest[resultTest.length - 1].integral
    
    console.table(resultTest)
    console.log(`Значение интеграла 6x^5 на отрезке [0, 1]  = ${integralTest}`)

    // x^(1/15) * sqrt(1+x^2) на отрезке [0, 1.5] 
    const task1 = {
        f: (x) => {
            return x**(1./15) * Math.sqrt(1+x**2)
        },
        a: 0,
        b: 1.5,
    }

    const result1 = process(task1, e)
    const integral1 = result1[result1.length - 1].integral
    
    console.table(result1)
    console.log(`Значение интеграла x^(1/15) * sqrt(1+x^2) на отрезке [0, 1.5] = ${integral1}`)

    // x^(1/5) * sqrt(1+x^2) на отрезке [0.001, 1.5] 
    const task2 = {
        ...task1,
        a: 0.001,
    }

    const result2 = process(task2, e)
    const integral2 = result2[result2.length - 1].integral
    
    console.table(result2)
    console.log(`Значение интеграла x^(1/15) * sqrt(1+x^2) на отрезке [0.001, 1.5] = ${integral2}`)
}

main()
Соседние файлы в предмете Методы вычислений