Вычислить на ЭВМ длину кривой на заданном интервале [a, b] с заданной точностью

#include <iostream>
#define _USE_MATH_DEFINES // for C++
#include <math.h>
using namespace std;

int main()
{

    double a = 1.0, b = M_E, h, s = 0., s1 = s, len = 0., len1 = len, eps = 0.01;
    double n = 10.;
    do {
        h = (b - a) / n;
        s1 = s; s = 0.;
        for (double i = 1.; i <= n; i++)
            s += h * (1 + log(a + h * (i - 0.5)) / (a + h * (i - 0.5)));
        n *= 2.;
    } while (fabs(s - s1) > eps);

    cout << "s = " << s << endl;

    n = 10.;

    do {
        h = (b - a) / n;
        len1 = len; len = 0.;
        for (double i = 1.; i < n; i++)
            len += sqrt((a + h * i) - (a + h * (i - 1.))) * ((a + h * i) - (a + h * (i - 1.))) + (1. + log((a + h * (i - 1.))) / (a + h * (i - 1.))) - (1. + log((a + i * h)) / (a + i * h)) * (1. + log((a + h * (i - 1.))) / (a + h * (i - 1.))) - (1 + log((a + i * h)) / (a + i * h));
        n *= 2.;
    } while (fabs(len - len1) > eps);

    cout << "dlina = " << len;

}

введите сюда описание изображения

В условии [1,e] - интервал, 0,01 - заданная точность, уравнение - функция. Работает вывод значения интеграла(s), но не работает вывод длины кривой с заданной точностью(len).


Ответы (1 шт):

Автор решения: Harry

Подарок в честь рождества :)

В этом вопросе есть вполне работающий код интегрирования методом трапеций с заданной точностью. У вас такое сложное выражение при расчете, что прокопаться через него очень сложно, а потому просто возьмем готовый код и применим его к функции

введите сюда описание изображения

double trapez(double(*f)(double), double a, double b, double eps)
{
    double old_i = 0, new_i = old_i+2*eps;
    for(unsigned int n = 1; abs(new_i-old_i) > eps; n *= 2)
    {
        old_i = new_i;
        double h = (b-a)/n, s = -(f(a) + f(b))/2;
        for(int i = 0; i <= n; ++i)
            s += f(a + i*h);
        new_i = s*h;
    }
    return new_i;
}

double y(double x) 
{ 
    x = log(x)/x/x;
    return sqrt(1+x*x); 
}

int main()
{
    cout << trapez(y,1,2.718281828459045,1e-5) << endl;
}

Точность я немного увеличил. Вычисления — здесь. Вам остается приспособить приведенный код в свою программу.

В скобках замечу, что требуемая в задании точность достигается путем замены кривой линии на прямолинейный отрезок без какого-либо интегрирования:

введите сюда описание изображения

Update

Идя навстречу пожеланиям зрителей :), вот вычисление длины через набор отрезков:

double length(double(*f)(double), double a, double b, double eps)
{
    double old_l = 0, new_l = old_l+2*eps;
    for(unsigned int n = 1; abs(new_l-old_l) > eps; n *= 2)
    {
        old_l = new_l;
        new_l = 0;
        double h = (b-a)/n, y0 = f(a), x0 = a;
        for(int i = 1; i <= n; ++i)
        {
            double x1 = x0+h;
            double y1 = f(x1);
            new_l += hypot(x1-x0,y1-y0);
            x0 = x1; y0 = y1;
        }
    }
    return new_l;
}

double y(double x) 
{ 
    return (1 + log(x))/x;
}

int main()
{
    cout << length(y,1,2.718281828459045,1e-5) << endl;
}
→ Ссылка