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>
/// Find a real root of the nonlinear equation by continued fraction solution
/// Calculate the function f(x) on the left side of the equation double Func(double x)
/// </summary>
/// <param name="Func">Calculate the left end function of the equation</param>
/// <param name="x">Input the initial value of the iteration (guess the solution), return a real root obtained in the interval</param>
// / <param name="eps">precision control parameter</param>
/// <return>bool type, whether the solution is successful</return>
public static bool GetRootPq(delFunction_x Func, ref double x, double eps)
{ int i , j, m, it = 0, r; double z, h, x0, q; double[] a = new double[10]; double[] y = new double[10];
// Solving conditions
r = 10;
q = 1.0e+35;
x0 = x;
h = 0.0;
// 连分式求解
while (r != 0)
{
r = r - 1;
j = 0;
it = r;
while (j <= 7)
{
if (j <= 2)
{
z = x0 + 0.1 * j;
}
else
{
z = h;
}
y[j] = Func(z);
h = z;
if (j == 0)
{
a[0] = z;
}
else
{
m = 0;
i = 0;
while ((m == 0) && (i <= j - 1))
{
if (Math.Abs(h - a[i]) < float.Epsilon)
{
m = 1;
}
else
{
h = (y[j] - y[i]) / (h - a[i]);
}
i = i + 1;
}
a[j] = h;
if (m != 0)
{
a[j] = q;
}
h = 0.0;
for (i = j - 1; i >= 0; i--)
{
if (Math.Abs(a[i + 1] + h) < float.Epsilon)
{
h = q;
}
else
{
h = -y[i] / (a[i + 1] + h);
}
}
h = h + a[0];
}
if (Math.Abs(y[j]) >= eps)
{
j = j + 1;
}
else
{
j = 10;
r = 0;
}
}
x0 = h;
}
x = h;
// Is the real root found in the 10th order continued fraction?
return (10 > it);
}
}
}