예제 #1
0
        static (int, double, double[]) PM_Method(double [,] A, double [] y, double [] l, double delta, double eps)
        {
            double ynorm = Math.Sqrt(Enumerable.Range(0, y.Length).Select(i => Math.Pow(y[i], 2)).Sum()); // ||y^(i)||

            double [] x  = Enumerable.Range(0, y.Length).Select(i => y[i] / ynorm).ToArray();             //x^(0) and x^(k)
            int[]     S  = Enumerable.Range(0, x.Length).Where(i => Math.Abs(x[i]) > delta).ToArray();    //S^(0) and S^(k)
            double[]  x_ = new double[x.Length];                                                          //x^(k-1)
            int[]     S_ = new int[S.Length];                                                             //S^(k-1)
            double[]  l_ = new double[l.Length];                                                          //λ^(0) and λ^(k)
            for (int k = 1;; k++)
            {
                Array.Copy(x, x_, x.Length); //x^(k) -> x^(k-1)
                Array.Copy(S, S_, S.Length); //S^(k) -> S^(k-1)
                Array.Copy(l, l_, l.Length); //λ^(k) -> λ^(k-1)
                y     = MatrixTools.MatToVec(MatrixTools.MatrixMult(A, x_));
                l     = Enumerable.Range(0, l.Length).Select(i => S_.Contains(i) ? y[i] / x_[i] : 0).ToArray();
                ynorm = Math.Sqrt(Enumerable.Range(0, y.Length).Select(i => Math.Pow(y[i], 2)).Sum());
                x     = Enumerable.Range(0, x.Length).Select(i => y[i] / ynorm).ToArray();
                S     = Enumerable.Range(0, S.Length).Where(i => Math.Abs(x[i]) > delta).ToArray();
                if (S_.All(i => Math.Abs(l[i] - l_[i]) <= eps) || MatrixTools.SubVecs(x, x_).Max() <= eps)
                {
                    return(k, S_.Select(i => l[i]).Sum() / S_.Length, x);
                }
            }
        }
예제 #2
0
        static void Main(string[] args)
        {
            //Inpute
            Console.Write("n : "); int n = int.Parse(Console.ReadLine());
            Console.Write("Enter n (δ = 10^(-n)) : "); double delta = Math.Pow(10, -double.Parse(Console.ReadLine()));
            //Console.Write("Enter δ : "); double delta = double.Parse(Console.ReadLine());
            Console.Write("Enter n (ε = 10^(-n)) : "); double eps = Math.Pow(10, -double.Parse(Console.ReadLine()));
            //Console.Write("Enter ε : "); double eps = double.Parse(Console.ReadLine());
            double[,] A = IOMatrix.InputSquareMatrix(n, "A");
            double[] y0 = IOMatrix.InputVector(n, "y_0");
            double[] l0 = IOMatrix.InputVector(n, "l_0");

            //Compute
            var res = PM_Method(A, y0, l0, delta, eps);

            //Output
            Console.WriteLine($"k : {res.Item1}");
            Console.WriteLine($"l_1 : {res.Item2}");
            Console.WriteLine("x^(k) : ");
            IOMatrix.OutputVector(res.Item3);

            Console.WriteLine(new string('-', 60));

            Console.WriteLine($"Ax : ");
            IOMatrix.OutputVector(MatrixTools.MatToVec(MatrixTools.MatrixMult(A, res.Item3)));
            Console.WriteLine($"lx : ");
            IOMatrix.OutputVector(res.Item3.Select(e => e * res.Item2).ToArray());

            Console.WriteLine(new string('-', 60));

            Console.WriteLine("A : ");
            IOMatrix.OutputMatrix(A);
            Console.WriteLine("y_0 : ");
            IOMatrix.OutputVector(y0);
            Console.WriteLine("l_0 : ");
            IOMatrix.OutputVector(l0);
            Console.WriteLine($"δ : {eps}");
            Console.WriteLine($"ε : {eps}");
        }
        static (double[], double, int) JacobiMethod(double[,] A, double[] b, double e, int max_k = -1)
        {
            double step = 0;

            double [] x = new double [b.Length], _x = new double[b.Length];
            for (int k = 1;; k++)
            {
                for (int n = 0; n < x.Length; n++)
                {
                    x[n] = _x[n];
                }
                for (int i = 0; i < b.Length; i++)
                {
                    _x[i] = -(Enumerable.Range(0, x.Length).Where(j => j != i).Select(j => A[i, j] * x[j]).Sum() - b[i]) / A[i, i];
                }
                step = MatrixTools.SubVecs(_x, x).Select(x => Math.Abs(x)).Max();
                if (step < e || k == max_k + 1)
                {
                    double r = MatrixTools.SubVecs(MatrixTools.MatToVec(MatrixTools.MatrixMult(A, _x)), b).Select(x => Math.Abs(x)).Max();
                    return(_x, r, k);
                }
            }
        }