public static double locateMonotonic(ObjectiveFunction.ObjectiveFunction objectivefunction, double min, double max, double value_target, double tolerance, int max_iterations)
        {
            double value_min = objectivefunction.evaluate(min);
            double value_max = objectivefunction.evaluate(max);

            for (int i = 0; i < max_iterations; ++i)
            {
                double mid       = 0.5 * (min + max);
                double value_mid = objectivefunction.evaluate(mid);

                if ((value_min <= value_target && value_mid >= value_target) || (value_min >= value_target && value_mid <= value_target))
                {
                    max       = mid;
                    value_max = value_mid;
                }
                else
                {
                    min       = mid;
                    value_min = value_mid;
                }

                if (Math.Abs(max - min) < tolerance)
                {
                    return(mid);
                }
            }

            throw new GenericException("Reached the maximum number of iterations before converging.");
        }
        public static double integrate(double from, double to, ObjectiveFunction.ObjectiveFunction f, int NUM_STEPS)
        {
            double total = 0.0;

            total += 0.5 * f.evaluate(from);
            for (int i = 1; i < NUM_STEPS; ++i)
            {
                total += f.evaluate(i * (to - from) / NUM_STEPS);
            }
            total += 0.5 * f.evaluate(from);

            total *= (to - from);
            total /= NUM_STEPS;

            return(total);
        }