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); } } }
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); } } }