Solving for the zero of an arbitrary function
Wall of declarations


double lowerBound = min,
    upperBound = max;
counter = 0;
double range = double.MaxValue;
double tryIndex = double.MinValue;
double tryEval = double.MinValue;



Nobody likes being greeted by a wall of declarations like that.  Let's see what can be done to reduce them.

lowerBound and upperBound merely rename the parameters.  You could just use min and max directly everywhere.

counter is strongly related to the loop.  You could write the loop as

for (counter = 0; Math.Abs(tryEval) &gt; eps &amp;&amp; counter &lt; 10000; counter++)
{
    …
}


range is also local to the loop, and should be declared inside the loop.  It's also annoying that it's initialized on the 4th line of the function, redefined on the 9th line, and used 17th line. In fact, I wouldn't bother making a variable for it at all:

tryIndex = lowerBound + (min - max) / 2;


In general, you have a lot of expressions that don't need to be assigned to variables.

Loop structure

Initializing tryIndex and tryEval to double.MinValue is a code smell.  First of all, you should probably prefer double.NaN.  Secondly, it raises the question, under what circumstances might double.MinValue "leak" out as a result?  It's worth restructuring the program to avoid having those special values at all.

Restructuring the program will also reveal that there are two possible error conditions: failure to converge because the two endpoints evaluate to the same sign, and failure to converge because it took too many iterations.

public static double Zero(this Func&lt;double, double&gt; function, double min, double max, out int counter, double eps = .001)
{
    for (counter = 0; counter &lt; 10000; counter++)
    {
        bool signMax = (function(max) &gt; 0);
        if ((function(min) &gt; 0) == signMax)
        {
            // Same sign
            throw new Exception("Failed to converge (same sign)");
        }

        double tryIndex = min + (max - min) / 2;
        double tryEval = function(tryIndex);
        if (Math.Abs(tryEval) &lt;= eps)
        {
            return tryIndex;
        }
        else if ((tryEval &gt; 0) == signMax)
        {
            max = tryIndex;
        }
        else
        {
            min = tryIndex;
        }
    }
    throw new Exception("Failed to converge (too many iterations)");
}