CodePlexProject Hosting for Open Source Software

The FindZero method finds the zeros of user-supplied functions. The following C# code snippet illustrates its use.

Note that there is no guarantee that any arbitrary function must have a root anywhere. The function y = x^2 + 1, for example, does not cross the real axis anywhere. If FindZero cannot locate a zero within its evaluation budget, it throws a NonConvergence exception.

There is also a multi-dimensional overload of FindZero that operates on vector-to-vector functions. The following C# code snippet illustrates its use.

// Find the point where the psi function crosses the axis. // I remember there is just one crossing at some value // not too far from one, so I start with one as a guess. double x0 = FunctionMath.FindZero(AdvancedMath.Psi, 1.0); // Okay, it's at 1.46... // You can also define the function as an anonymous delegate. // Find a Bessel function zero near pi. double x1 = FunctionMath.FindZero(x => AdvancedMath.BesselJ(0, x), Math.PI); // Ah, there's one at 2.40... // You can also specify an interval in which to search. // Find the point where sin(x) and cos(x) are equal in the interval (0,pi/2). double x2 = FunctionMath.FindZero(x => Math.Sin(x) - Math.Cos(x), Interval.FromEndpoints(0.0, Math.PI / 2.0)); // Hey, that's exactly pi/4!

Note that there is no guarantee that any arbitrary function must have a root anywhere. The function y = x^2 + 1, for example, does not cross the real axis anywhere. If FindZero cannot locate a zero within its evaluation budget, it throws a NonConvergence exception.

There is also a multi-dimensional overload of FindZero that operates on vector-to-vector functions. The following C# code snippet illustrates its use.

// Any complex function is a map R^2 -> R^2, so we can use FindZero // to finds its complex roots. // For example, let's map z^3 - 1 into a vector-to-vector function. Func<double[], double[]> f1 = delegate (double[] x) { Complex z = new Complex(x[0], x[1]); Complex y = z * z * z - 1.0; return (new double[] { y.Re, y.Im }); }; // Then we can use FindZero to zero this function. double[] u1 = FunctionMath.FindZero(f1, new double[] { 1.0, 1.0 }); // The answer, of course, is e^{i pi / 3} = (1/2, sqrt(3)/2) // But if you write y = AdvanceComplexMath.Erf(z), you will solve the // much harder problem of finding zeros of the complex error function. // Complex functions provide a nice 2-D play-space, but our multi-dimensional // zero finder can do problems in any dimension. // Find a three-dimensional vector with length 5, a projection into // the x-y plane of length 4, and that is 30 degrees from the x-axis. Func<double[], double[]> f2 = (double[] x) => new double[] { Math.Sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]) - 5.0, Math.Sqrt(x[0] * x[0] + x[1] * x[1]) - 4.0, x[0] / Math.Sqrt(x[0] * x[0] + x[1] * x[1]) - Math.PI / 6.0 }; double[] u2 = FunctionMath.FindZero(f2, new double[] { 3.0, 2.0, 1.0 });

Last edited Sep 28, 2012 at 8:21 PM by ichbin, version 1