using System;
namespace Zhou.CSharp.Algorithm
{
public delegate double delFunction_x(double x);
public delegate double delFunction_xa(double[] x);
public delegate double delFunction_x_y(double x, double y);
public delegate double delFunction_x_ya(double x, double[] y);
public delegate double delFunction_xa_ya(double[] x, double[] y);
/// <summary>
/// Class NLEquations for solving nonlinear equations
/// Zhou Changfa
/// Adapted to deep confusion
/// </summary>
public static partial class NLEquations
{
/// <summary>
/// Gradient method to find a set of real roots of nonlinear equations
/// Calculation of the function f(x) at the left end of the equation and its partial derivative values
/// double Func(double x[], double [] y)
/// </summary>
/// <param name="Func">Calculate the left end function of the equation</param>
/// <param name="n">The number of equations is also the number of unknowns Number</param>
/// <param name="x">A one-dimensional array with a length of n, storing a set of initial values x0, x1, …, xn-1, and storing a set of real roots of the equation when returning< /param>
/// <param name="nMaxIt">Number of iterations</param>
/// <param name="eps">Control precision</param>
/// <return>bool type, whether the solution is successful< /return>
public static bool GetRootsetGrad(delFunction_xa_ya Func, int n, double[] x, int nMaxIt,double eps)
{ int i, j; double f, d, s;
double[] y = new double[n];
i = nMaxIt;
f = Func(x, y);
// Control precision, solve iteratively
while (f >= eps)
{ i = i - 1; if (i == 0) { return true; }
d = 0.0;
for (j = 0; j <= n - 1; j++)
{
d = d + y[j] * y[j];
}
if (Math.Abs(d) < float.Epsilon)
{
return false;
}
s = f / d;
for (j = 0; j <= n - 1; j++)
{
x[j] = x[j] - s * y[j];
}
f = Func(x, y);
}
// Whether the accuracy is reached within the effective number of iterations
return (nMaxIt > i);
}
}
}