Метод Ланцоша для симметричных СЛАУ. C#

Пытаюсь реализовать данный метод http://window.edu.ru/resource/183/41183/files/nstu144.pdf, стр 52. Вроде бы сделал все как в алгоритме, но результат выдает неверный. Не могу найти ошибку, нужна помощь!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SymmetricMatrix
{
    public partial class Form1 : Form
    {
        int n;
        List<List<double>> matrix;
        List<double> b;
        public Form1()
        {
            InitializeComponent();
            matrix = new List<List<double>>();
            b = new List<double>();
            n = 3;
            Init();
            LanczosMethod();

        }

        private void Init()
        {
            Random rnd = new Random();
            for (int i = 0; i < n; i++)
            {
                matrix.Add(new List<double>());
                for (int j = 0; j < n; j++)
                    matrix[i].Add(0);
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (i == j)
                        matrix[i][j] = rnd.Next(-10, 10)/* + rnd.NextDouble()*/;
                    else if (i < j)
                    {
                        double randomValue = rnd.Next(-10, 10)/* + rnd.NextDouble()*/;
                        matrix[i][j] = randomValue;
                        matrix[j][i] = randomValue;
                    }
                }
            }

            for (int i = 0; i < n; i++)
                b.Add(rnd.Next(-10, 10));
        }

        private List<double> MatrToVec(List<List<double>> matr, List<double> vec)
        {
            List<double> result = new List<double>();
            for (int i = 0; i < n; i++)
                result.Add(0);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                    result[i] += matr[i][j] * vec[j];
            }
            return result;
        }

        private double Norma(List<double> vec)
        {
            double res = 0;
            for (int i = 0; i < n; i++)
                res += vec[i] * vec[i];
            return Math.Sqrt(res);
        }

        private List<double> Division(List<double> vec, double x)
        {
            List<double> result = new List<double>();
            for (int i = 0; i < n; i++)
                result.Add(0);
            for (int i = 0; i < n; i++)
                result[i] = vec[i] / x;
            return result;
        }

        private double ScalarMult(List<double> vec1, List<double> vec2)
        {
            double res = 0;
            for (int i = 0; i < n; i++)
                res += vec1[i] * vec2[i];
            return res;
        }

        private List<double> Sub(List<double> vec1, List<double> vec2)
        {
            List<double> result = new List<double>();
            for (int i = 0; i < n; i++)
                result.Add(0);
            for (int i = 0; i < n; i++)
                result[i] = vec1[i] - vec2[i];
            return result;
        }

        private List<double> Sum(List<double> vec1, List<double> vec2)
        {
            List<double> result = new List<double>();
            for (int i = 0; i < n; i++)
                result.Add(0);
            for (int i = 0; i < n; i++)
                result[i] = vec1[i] + vec2[i];
            return result;
        }

        private List<double> Mult(List<double> vec, double x)
        {
            List<double> result = new List<double>();
            for (int i = 0; i < n; i++)
                result.Add(0);
            for (int i = 0; i < n; i++)
               result[i] = vec[i] * x;
            return result;
        }

        private List<double> fill(List<double> vec, double x)
        {
            for (int i = 0; i < n; i++)
                vec.Add(x);
            return vec;
        }

        private void LanczosMethod()
        {
            int m = n;
            List<double> x0 = new List<double>();
            List<double> r0 = new List<double>();
            List<double> alpha = new List<double>();
            List<double> beta = new List<double>();
            List<List<double>> v = new List<List<double>>();
            List<List<double>> w = new List<List<double>>();
            for (int i = 0; i < m + 2; i++)
            {
                v.Add(new List<double>());
                w.Add(new List<double>());
            }
            for (int i = 0; i < m; i++)
                x0.Add(1);
            r0 = Sub(b, MatrToVec(matrix, x0));
            fill(v[0], 0);
            beta.Add(Norma(r0));
            beta.Add(0);
            alpha.Add(0);
            v[1] = Division(r0, beta[0]);
            for (int j = 1; j <=m; j++)
            {
                w[j] = Sub(MatrToVec(matrix, v[j]), Mult(v[j - 1], beta[j]));
                alpha.Add(ScalarMult(w[j], v[j]));
                beta.Add(Norma(w[j]));
                if (beta[j + 1] == 0)
                {
                    m = j;
                    break;
                }
                v[j + 1] = Division(w[j], beta[j + 1]);
            }

            List<double> y = new List<double>();
            for (int i = 0; i < m; i++)
                y.Add(0);
            List<double> f = new List<double>();
            f.Add(beta[0]);
            for (int i = 1; i <m; i++)
                f.Add(0);

            List<double> a1 = new List<double>();
            List<double> b1 = new List<double>();
            List<double> c1 = new List<double>();

            for (int i = 1; i <= m; i++)  //создание трехдиагональной матрицы
            {
                b1.Add(beta[i + 1]);
                a1.Add(beta[i]);
                c1.Add(alpha[i]);
            }
            b1[m - 1] = 0;

            double tmp;                // метод прогонки
            for (int i = 1; i < m; i++)
            {
                tmp = a1[i] / c1[i - 1];
                c1[i] = c1[i] - tmp * b1[i - 1];
                f[i] = f[i] - tmp * f[i - 1];
            }

            y[n - 1] = f[n - 1] / c1[n - 1];

            for (int i = m - 2; i >= 0; i--)
                y[i] = (f[i] - b1[i] * y[i + 1]) / c1[i];


            List<double> x = new List<double>();
            for (int i = 0; i < m; i++)
                x.Add(0);

            for (int i = 1; i <= m; i++)        //результат
                x = Sum(x, Mult(v[i],y[i-1]));
            x = Sum(x, x0);

        }
    }
}

Матрица:

5 - 1  -7 |  9
-1  5  9  | -6
-7  9  -8 |  2

Ожидаемый результат:

 0,8533
 0,2527
-0,7122

Результат:

 0.9670
-0.5740
-2.1193

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