# Пример расчета суммы ряда

Рассмотрим как можно посчитать предел суммы ряда на lyng. Для наивной реализации
представим что у нас есть функция рассчитывающая n-й член ряда. Тогда мы можем 
считать сумму до тех пор, пока отклонение при расчете следующего члена не станет
меньше чем заданная погрешность:

    fun сумма_ряда(x, погрешность=0.0001, f) {
        var сумма = 0
        for( n in 1..100000) {
            val следующая_сумма = сумма + f(x, n)
            if( n > 1 && abs(следующая_сумма - сумма) < погрешность )
                break следующая_сумма
            сумма = следующая_сумма
        }
        else null
    }

Для проверки можно посчитать на хорошо известном ряду Меркатора

$$ \ln(1+x)=x-{\dfrac {x^{2}}{2}}+{\dfrac {x^{3}}{3}}-\cdots =\sum \limits _{n=0}^{\infty }{\dfrac {(-1)^{n}x^{n+1}}{(n+1)}}=\sum \limits _{n=1}^{\infty }{\dfrac {(-1)^{n-1}x^{n}}{n}} $$

Который в нашем случае для точки $ x = 1 $ можно записать так:

    val x = сумма_ряда(1) { x, n -> 
        val sign = if( n % 2 == 1 ) 1 else -1
        sign * pow(x, n) / n
    }

Проверим:
    
    assert( x - ln(2) < 0.001 )

В нашем примере есть изъян - погрешность вычисляется примитивно: `abs(следующая_сумма - сумма) < погрешность`, что совершенно неверно, если значения малы. Значительно более корректно вычислять погрешность, нормированную на диапазон сравниваемых величин:


    fun погрешность(x0, x1) {
        abs( x1 - x0 ) / (abs( x1 + x0 ) / 2.0)
    }
    // относительная погрешность одинакова и в разных диапазонах
    assertEquals( погрешность(5,6), погрешность(0.005,0.006))

Теперь мы могли бы написать более корректное сравнение для вещественных

    // расхождение не больше 1% или сколько укажете:
    fun почти_равны(a,b,epsilon=0.01) { 
        погрешность(a,b) <= epsilon 
    }
    assert( почти_равны( 0.0005, 0.000501 ) )

Во многих случаях вычисление $n+1$ члена значительно проще cчитается от предыдущего члена, в нашем случае это можно было бы записать через итератор, см [Iterable] и `flow` в [parallelism].

[Iterable]: ../Iterable.md
[parallelism]: ../parallelism.md
