Calculate the minimum and maximum for a function

I am looking for a way to calculate the minimum and maximum values ​​for a function in Java. The program I'm going to create will see all the local minimums and maxima for a function that oscillates around the x-axis (this is not a school assignment, although I mentioned cos (x) in the diagram below). Methods I've seen all over the internet calculate the min / max value for an array. I am looking into a method that will directly compute this value for a function that goes from x = 0 to x = infinity.

For example cos (x) from x = 0 to x = 5000. There are tons of local lows and highs,

In addition, sin (x) is from x = 0 to x = 5000. A large number of local highs and lows must be found.

The function is also continuous from x = 0 to x = infinity.

Is there a preferred numerical method for doing this?

public class Test {
    public static void main(String [] args) {
         Function testFunction = new Function()
         {
             public double f(double x) {
             return something;
         }

       }

         findMax(testFunction, 1, 40000, 0.001);
         findMin(testFunction, 1, 40000, 0.001);

    }

    public static interface Function {
        public double f(double x);
    }

    public static double function(double x) {
        return Math.cos(x);
    }

    public static void findMax(Function f, double lowerBound, double upperBound, double step) {

    }

    public static void findMin(Function f, double lowerBound, double upperBound, double step) {

    }

}

      

It is a similar program that finds the roots -

// Finds the roots of the specified function passed in with a lower bound,
    // upper bound, and step size.
    public static void findRoots(Function f, double lowerBound,
                  double upperBound, double step) {
    double x = lowerBound, next_x = x;
    double y = f.f(x), next_y = y;
    int s = sign(y), next_s = s;

    for (x = lowerBound; x <= upperBound ; x += step) {
        s = sign(y = f.f(x));
        if (s == 0) {
        System.out.println(x);
        } else if (s != next_s) {
        double dx = x - next_x;
        double dy = y - next_y;
        double cx = x - dx * (y / dy);
        System.out.println(cx);
        }
        next_x = x; next_y = y; next_s = s;
    }
    }

      

+3


source to share


2 answers


Here is the most naive implementation of your function findMax()

:

public static void findMax(Function f, double lowerBound, double upperBound, double step) {
    double maxValue = f.f(lowerBound);

    for (double i=lowerBound; i <= upperBound; i+=step) {
        double currEval = f.f(i);
        if (currEval > maxValue) {
            maxValue = currEval;
        }
    }

    return maxValue;
}

      



You can play with the step size until you converge at the maximum value. The smaller the step size, the more accurate the resolution you will need to find the maximum.

The next step on this implementation would be to consider the immersion of a mesh containing lowerBound

and upperBound

non-uniformly. For example, in case cos(x)

you don't have to try very close to the lows and highs, because the function doesn't change the value very much. On the other hand, near the point where it crosses zero, the function changes its value very quickly. So an improvement on what I wrote here would be to make your grid more dynamic (and therefore requiring fewer evaluations).

+4


source


I'm not sure if this helps, but could this be what you are looking for. https://en.wikibooks.org/wiki/The_Science_of_Programming/Peaks_and_Valleys



0


source







All Articles