C#でLU分解（教育目的）

# 目的
LU分解の教育用にコードを書いたので共有します。
教育目的のため、下三角行列と上三角行列をそれぞれ別の配列にしています。
特に4行4列以上の計算のフローを確認するためのものです。

# ソースコード
```cs
            // 正方行列の行・列数
            int n;

            // 行列のサイズ
            while (true)
            {
                Console.WriteLine("正方行列の行・列数を入力");
                string linebuf = Console.ReadLine();
                if (int.TryParse(linebuf, out n)) break;
                Console.WriteLine("整数以外の値が入力されました。");
            }

            // 行列を定義
            double[,] Matrix_A = new double[n, n];
            double[,] Matrix_b = new double[n, 1];
            double[,] Matrix_L = new double[n, n];
            double[,] Matrix_U = new double[n, n];

            Console.WriteLine("行列Aの値を入力");
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("{0}行目をを入力", i + 1);
                for (int j = 0; j < n; j++)
                {
                    while (true)
                    {
                        string linebuf = Console.ReadLine();
                        if (double.TryParse(linebuf, out Matrix_A[i, j])) break;
                        Console.WriteLine("整数以外の値が入力されました。");
                    }
                }
            }

            Console.WriteLine("行列bの値を入力");
            for (int j = 0; j < n; j++)
            {
                while (true)
                {
                    string linebuf = Console.ReadLine();
                    if (double.TryParse(linebuf, out Matrix_b[j, 0])) break;
                    Console.WriteLine("整数以外の値が入力されました。");
                }
            }

            Console.WriteLine("入力値の確認");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write("{0} ", Matrix_A[i, j].ToString().PadLeft(4, ' '));
                    
                }
                Console.Write(" x{0}  ", i + 1);
                Console.Write("{0} ", Matrix_b[i, 0].ToString().PadLeft(4, ' '));
                Console.WriteLine();
            }

            Console.WriteLine("=====================");
            Console.WriteLine("行列Aを行列LとUに分解");
            Console.WriteLine("---------------------");

            for (int j = 0; j < n; j++)
            {
                //Lを求める
                for (int i = j; i < n; i++)
                {
                    Console.Write("L[{0}][{1}] = A[{0}][{1}]", i ,j);
                    double sum = 0;
                    if(j <= i)
                    {
                        for (int m = 0; m <= j - 1; m++)
                        {
                            sum -= Matrix_L[i, m] * Matrix_U[m, j];
                            Console.Write(" - L[{0}][{1}] * U[{1}][{2}]", i, m, j);
                        }
                    }

                    Matrix_L[i, j] = Matrix_A[i, j] + sum;
                    Console.Write(" = {0}", Matrix_L[i, j]);
                    Console.WriteLine();

                }

                Console.WriteLine("---------------------");

                //Uを求める
                for (int i = j; i < n; i++)
                {
                    if (i == j)
                    {
                        Matrix_U[j, i] = 1;
                        Console.WriteLine("U[{0}][{1}] = 1", j, i);
                        continue;
                    }

                    Console.Write("U[{0}][{1}] = (A[{0}][{1}]", j, i);

                    double sum = 0;
                    if (j < i)
                    {
                        for (int m = 0; m <= j - 1; m++)
                        {
                            sum -= Matrix_L[j, m] * Matrix_U[m, i];
                            Console.Write(" - L[{0}][{1}] * U[{1}][{2}]", j, m, i);
                        }
                    }
                    Matrix_U[j, i] = (Matrix_A[j, i] + sum) / Matrix_L[j, j];
                    Console.WriteLine(") / L[{0}][{0}] = {1}", j, Matrix_U[j, i]);
                }
                Console.WriteLine("---------------------");
            }

            Console.WriteLine("行列LとUに分解した結果");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write(Matrix_L[i, j].ToString().PadLeft(4, ' '));
                }

                Console.Write(" ");
                for (int j = 0; j < n; j++)
                {
                    Console.Write(Matrix_U[i, j].ToString().PadLeft(4, ' '));
                }
                Console.WriteLine();
            }

            Console.WriteLine("");
            Console.WriteLine("前進消去で行列yを求める");
            double[,] Matrix_y = new double[n, 1];

            for (int i = 0; i < n; i++)
            {
                double sum = 0;
                if (i != 0)
                {
                    for (int j = 0; j < i; j++)
                    {
                        sum -= Matrix_L[i, j] * Matrix_y[j, 0];

                    }
                }

                Matrix_y[i, 0] = (Matrix_b[i, 0] + sum) / Matrix_L[i, i];
            }

            Console.WriteLine("");
            Console.WriteLine("後退代入で行列xを求める");
            double[,] Matrix_x = new double[n, 1];

            for (int i = n - 1; i >= 0; i--)
            {
                double sum = 0;
                if (i != n - 1)
                {
                    for (int j = i + 1; j < n; j++)
                    {
                        sum -= Matrix_U[i, j] * Matrix_x[j, 0];
                    }
                }
                Matrix_x[i, 0] = Matrix_y[i, 0] + sum;
            }

            Console.WriteLine("連立方程式の解 行列x");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write("{0} ", Matrix_A[i, j].ToString().PadLeft(4, ' '));
                }
                Console.Write("     {0}     ", Matrix_x[i, 0].ToString().PadLeft(4, ' '));
                Console.Write("{0} ", Matrix_b[i, 0].ToString().PadLeft(4, ' '));
                Console.WriteLine();
            }

            Console.ReadLine();

```