public Tuple <Matrix, double> SpeedestDescentMethod(Matrix x0, double epsilon, double a = 1, int steps = 100) { int n = function.Variables.Count, accuracy = 10;// Regex.Match(epsilon.ToString(), @"(?<=[,])\d+").Value.Count(); //заполняем градиент FunctionParser[] gradFunctional = new FunctionParser[n]; for (int i = 0; i < n; ++i) { gradFunctional[i] = function.DifferentiateBy(function.Variables[i]).Optimize(); } //вычисляем градиент в точке x_0 Matrix x = (Matrix)x0.Clone(), grad = CountGrad(x, gradFunctional); int step = steps; //пока ||grad f(x_0)|| >= e while (Norm(grad) >= epsilon && step-- > 0) { string func = function.ToString(); //заменяем цифры в скобках просто цифрами func = Regex.Replace(func, @"[(](\d+)[)]", "$1"); //заменяем переменные x_i на x_i - x * grad_i, чтобы получить функцию одной переменной x for (int i = 0; i < function.Variables.Count; ++i) { string replacedVariable = function.Variables[i], //replacement = grad[i] > 0 ? $"{Math.Round(x[i], accuracy)}-{Math.Round(grad[i], accuracy)}a" : $"{Math.Round(x[i], accuracy)}+{Math.Abs(Math.Round(grad[i], accuracy))}a"; replacement = grad[i] > 0 ? $"{x[i]:f10}-{grad[i]:f10}a" : $"{x[i]:f10}+{Math.Abs(grad[i]):f10}a"; func = Regex.Replace(func, $@"(?<=[(]){replacedVariable}(?=[)])", replacement); func = Regex.Replace(func, replacedVariable, $"({replacement})"); } FunctionParser Ф = new FunctionParser(func); Matrix A = new Matrix(1); A[0] = a; Optimizer support = new Optimizer(Ф); var min = support.NewtonsMethod(A, epsilon); x = x - min.Item1[0] * grad; grad = CountGrad(x, gradFunctional); } if (step < 0) { throw new MethodDivergencyException($"Методу не удалось найти решение за {steps} шагов."); } return(new Tuple <Matrix, double>(x, f(x.ToVector()))); }