Решение уравнения f(x)=0 методом простых итераций (последовательных приближений)

/ Просмотров: 417

Метод простых итераций решения уравнения f(x)=0 состоит в замене исходного уравнения эквивалентным ему уравнением x=φ(x) и построении последовательности xn+1=φ(xn), сходящейся при n→∞.

Достаточным условием сходимости является наличие числа q такого, что | φ’(x)|≤q<1 на отрезке [a, b], причём чем оно меньше, тем быстрее сходится алгоритм. В качестве начального приближения можно выбрать любое число, лежащее на этом промежутке. Принцип работы алгоритма наглядно продемонстрирован на рисунке. Синим цветом обозначена функция φ(x), красным y=x. Стрелка выходит из точки, которая выбрана в качестве начального приближения, после чего она через несколько итераций приходит к корню уравнения. Тогда класс, решающий уравнение методом последовательных приближений, будет выглядеть следующим образом:

/uploads/_pages/23/siter.png

public class Siter
{
    public double Function(double x)
    {
        return Math.Exp(-0.1 * x);
    }

    public double X0;
    public double Epsilon;
    public IEquation Equation;

    public double Resolve(double x0, double epsilon)
    {
        X0 = x0;
        Epsilon = epsilon;
        return Calc(Equation.F);
    }

    public double Resolve(Func<double, double> Function)
    {
        return Calc(Function);
    }

    private double Calc(Func<double, double> Function)
    {
        double k = 0;
        double y = 0;
        do
        {
            if (k > 0) X0 = y;
            y = Function(X0);
            k++;
        } while ((Math.Abs(y - X0) > Epsilon));
        return X0;
    }
}

Теперь создадим модульный тест, выполняющий проверку работоспособности алгоритма. В качестве примера возьмём два уравнения: x – e-0.1x=0 и cos x2 – 10x=0. Заменим их на эквивалентные уравнения вида x=φ(x): x=e-0.1x и x=0.1cos x2. Для первого уравнения, судя по рисунку, начальным приближением удобно выбрать 0, а построив такой же рисунок для второго уравнения, можно увидеть, что удобным начальным приближением является число 0,5.

class SiterEquat : IEquation
{
    public double F(double x)
    {
        return Math.Exp(-0.1 * x);
    }
}
    [TestMethod]
    public void TestSiter()
    {
        Siter s = new Siter();
        s.Equation = new SiterEquat();
        Assert.AreEqual(s.Resolve(0, 0.1e-3), 0.91277, 0.1e-3);
        s.X0 = 0.5;
        Assert.AreEqual(s.Resolve(x => {return 0.1 * Math.Cos(x * x); }), 0.1, 0.1e-3);
    }

Как видно в тестовом методе, решение осуществляется двумя способами: с помощью создания класса, содержащего функцию φ(x), а также с помощью явного указания лямбда-функции.

Если вы незнакомы с модульным тестированием, то я поясню. При запуске модульного тестирования запускаются все методы, помеченные как [TestMethod]. Тест считается проваленным, если в нём произошло хотя бы одно исключение, в противном случае тест считается выполненным. Класс Assert содержит набор методов, предназначенных для сравнения некоторых данных с эталонными. Таким образом, проверяемым значением у нас является решение уравнения, полученное программно, эталонным – точное решение уравнения. В качестве третьего параметра можно указать допустимое отличие проверяемого параметра от эталонного. Поскольку программа решает уравнение с точностью до четвертого знака после запятой, эту же точность мы и указали в качестве третьего параметра.

Оставьте комментарий!

Комментарий будет опубликован после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)