Inheritance: BaseMatrix
        public override BaseMatrix LUsq()
        {
            var newau = new double[au.Length][];

            for (int i = 0; i < au.Length; i++)
            {
                newau[i] = au[i].Clone() as double[];
            }
            var newal = new double[al.Length][];

            for (int i = 0; i < al.Length; i++)
            {
                newal[i] = al[i].Clone() as double[];
            }
            var matrPrec = new DiagonalMatrix(di.Clone() as double[], newal, newau, shift_l, shift_u);

            // Здесь нужно разделить и верхний и нижные треугольники
            for (int l_diags = 0; l_diags < shift_l.Length; l_diags++)
            {
                for (int j = 0, indl = shift_l[l_diags]; indl < al.Length; j++, indl++)
                {
                    matrPrec.al[indl][l_diags] /= matrPrec.di[j];
                }
            }

            for (int u_diags = 0; u_diags < shift_u.Length; u_diags++)
            {
                for (int inddi = 0, indu = shift_u[u_diags]; indu < au.Length; inddi++, indu++)
                {
                    matrPrec.au[indu][u_diags] /= matrPrec.di[inddi];
                }
            }
            HashSet <int> shift = new HashSet <int>(shift_l); // одинаковые смещения

            shift.IntersectWith(shift_u);
            if (shift.Count != 0)
            {
                for (int i = 1; i < di.Length; i++)
                {
                    double sum = 0;
                    for (int k = 0; k < shift_l.Length; k++)
                    {
                        sum += matrPrec.al[i][k] * matrPrec.au[i][k];
                    }
                    double newdi = matrPrec.di[i] - sum;
                    matrPrec.di[i] = Math.Sqrt(newdi);
                }
            }
            return(matrPrec);
        }
        // !
        // Есть очень простые формулы для LU-разложения
        // для случия, если shift_l = {1} и shift_u = {1}
        // введу для них частный случай, в котором сложность n
        // см. "Методы решения СЛАУ большой размерности" М.Ю.Баландин Э.П.Шурина 1 августа 2000 г.

        // Подробные комментарии только для LU разложения
        public override BaseMatrix LU()
        {
            var newal = new double[al.Length][];

            for (int i = 0; i < al.Length; i++)
            {
                newal[i] = al[i].Clone() as double[];
            }

            var matrPrec = new DiagonalMatrix(di.Clone() as double[], newal, au, shift_l, shift_u);

            // Деление всего нижнего треугольника на элементы главной диагонали, причём
            // элементы j-го столбца деляться на di[j]

            for (int l_diags = 0; l_diags < shift_l.Length; l_diags++)
            {
                for (int j = 0, indl = shift_l[l_diags]; indl < al.Length; j++, indl++)
                {
                    matrPrec.al[indl][l_diags] /= matrPrec.di[j];
                }
            }



            // Для расчёта новых di, необходимы произведения симметричных элементов
            // для этого нахожим одинаковые смещения
            HashSet <int> shift = new HashSet <int>(shift_l); // одинаковые смещения

            shift.IntersectWith(shift_u);

            if (shift.Count != 0)
            {
                for (int i = 1; i < di.Length; i++)
                {
                    double sum = 0;
                    for (int k = 0; k < shift_l.Length; k++)
                    {
                        sum += matrPrec.al[i][k] * matrPrec.au[i][k];
                    }
                    matrPrec.di[i] -= sum;
                }
            }
            return(matrPrec);
        }
 public override BaseMatrix LLt()
 {
     var newal = new double[al.Length][];
     for (int i = 0; i < al.Length; i++)
         newal[i] = al[i].Clone() as double[];
     var matrPrec = new DiagonalMatrix(di.Clone() as double[], newal, newal, shift_l, shift_u);
     for (int l_diags = 0; l_diags < shift_l.Length; l_diags++)
         for (int j = 0, indl = shift_l[l_diags]; indl < al.Length; j++, indl++)
             matrPrec.al[indl][l_diags] /= matrPrec.di[j];
     for (int i = 1; i < di.Length; i++)
     {
         double sum = 0;
         for (int k = 0; k < shift_l.Length; k++)
             sum += matrPrec.al[i][k] * matrPrec.al[i][k];
         double newdi = matrPrec.di[i] - sum;
         matrPrec.di[i] = Math.Sqrt(newdi);
     }
     return matrPrec;
 }
        public override BaseMatrix LUsq()
        {
            var newau = new double[au.Length][];
            for (int i = 0; i < au.Length; i++)
                newau[i] = au[i].Clone() as double[];
            var newal = new double[al.Length][];
            for (int i = 0; i < al.Length; i++)
                newal[i] = al[i].Clone() as double[];
            var matrPrec = new DiagonalMatrix(di.Clone() as double[], newal, newau, shift_l, shift_u);
            // Здесь нужно разделить и верхний и нижные треугольники
            for (int l_diags = 0; l_diags < shift_l.Length; l_diags++)
                for (int j = 0, indl = shift_l[l_diags]; indl < al.Length; j++, indl++)
                    matrPrec.al[indl][l_diags] /= matrPrec.di[j];

            for (int u_diags = 0; u_diags < shift_u.Length; u_diags++)
                for (int inddi = 0, indu = shift_u[u_diags]; indu < au.Length; inddi++, indu++)
                    matrPrec.au[indu][u_diags] /= matrPrec.di[inddi];
            HashSet<int> shift = new HashSet<int>(shift_l); // одинаковые смещения
            shift.IntersectWith(shift_u);
            if (shift.Count != 0)
                for (int i = 1; i < di.Length; i++)
                {
                    double sum = 0;
                    for (int k = 0; k < shift_l.Length; k++)
                        sum += matrPrec.al[i][k] * matrPrec.au[i][k];
                    double newdi = matrPrec.di[i] - sum;
                    matrPrec.di[i] = Math.Sqrt(newdi);
                }
            return matrPrec;
        }
        // !
        // Есть очень простые формулы для LU-разложения
        // для случия, если shift_l = {1} и shift_u = {1}
        // введу для них частный случай, в котором сложность n
        // см. "Методы решения СЛАУ большой размерности" М.Ю.Баландин Э.П.Шурина 1 августа 2000 г.
        // Подробные комментарии только для LU разложения
        public override BaseMatrix LU()
        {
            var newal = new double[al.Length][];
            for (int i = 0; i < al.Length; i++)
                newal[i] = al[i].Clone() as double[];

            var matrPrec = new DiagonalMatrix(di.Clone() as double[], newal, au, shift_l, shift_u);
            // Деление всего нижнего треугольника на элементы главной диагонали, причём
            // элементы j-го столбца деляться на di[j]

            for (int l_diags = 0; l_diags < shift_l.Length; l_diags++)
                for (int j = 0, indl = shift_l[l_diags]; indl < al.Length; j++, indl++)
                    matrPrec.al[indl][l_diags] /= matrPrec.di[j];

            // Для расчёта новых di, необходимы произведения симметричных элементов
            // для этого нахожим одинаковые смещения
            HashSet<int> shift = new HashSet<int>(shift_l); // одинаковые смещения
            shift.IntersectWith(shift_u);

            if (shift.Count != 0)
                for (int i = 1; i < di.Length; i++)
                {
                    double sum = 0;
                    for (int k = 0; k < shift_l.Length; k++)
                        sum += matrPrec.al[i][k] * matrPrec.au[i][k];
                    matrPrec.di[i] -= sum;
                }
            return matrPrec;
        }