This methods solves for the zero of an arbitrary function using the Bisection Method. It works as desired, but I want to know if the code can be improved or made more readable and if I'm properly dealing with the various error conditions that might arise.
/// <summary>
/// Finds the input value of a function such that the output is zero within the range of min and max
/// </summary>
/// <param name="function">The function to zero</param>
/// <param name="min">The lower bound of the "zero search"</param>
/// <param name="max">The upper bound of the "zero search"</param>
/// <param name="counter">The amount of iterations to convergence</param>
/// <param name="eps">Desired precision</param>
/// <returns>An input value such that 'function' returns 0 zero within the desired precision eps</returns>
public static double Zero(this Func<double, double> function, double min, double max, out int counter, double eps = .001) {
double lowerBound = min,
upperBound = max;
counter = 0;
double range = double.MaxValue;
double tryIndex = double.MinValue;
double tryEval = double.MinValue;
while (Math.Abs(tryEval) > eps && counter < 10000) {
counter++;
range = upperBound - lowerBound;
double maxEval = function(upperBound);
double minEval = function(lowerBound);
bool signMax = (maxEval > 0);
bool signMin = (minEval > 0);
if (signMax == signMin) {
throw new Exception("Failed to converge");
}
tryIndex = lowerBound + (range / 2);
tryEval = function(tryIndex);
bool trySign = tryEval > 0;
if (trySign == signMax) {
upperBound = tryIndex;
} else lowerBound = tryIndex;
}
return tryIndex;
}