C# One Variable Minimization Example

[TOC]

using System;

using CenterSpace.NMath.Core;
using CenterSpace.NMath.Analysis;

namespace CenterSpace.NMath.Analysis.Examples.CSharp
{
  class OneVariableMinimizationExample
  {
    /// <summary>
    /// A .NET example in C# showing how to find a minimum of a univariate function
    /// using a golden minimizer and Brent's method.
    /// </summary>
    static void Main(string[] args)
    {
      Console.WriteLine();

      // Create a one-variable function.
      OneVariableFunction function = (new NMathFunctions.DoubleUnaryFunction(f));

      // Use golden section search to find the minimum of the function
      // in the interval -10000 to 10000.
      int lower = -10000;
      int upper = 10000;

      // Create the minimizer with default tolerance and default maximum iterations.
      GoldenMinimizer golden = new GoldenMinimizer();

      // Perform the minimization.
      double min = golden.Minimize(function, lower, upper);

      Console.WriteLine("GoldenMinimizer found a minimum of " + function.Evaluate(min));
      Console.WriteLine("at " + min + " in " + golden.Iterations + " iterations.");

      if (golden.ToleranceMet)
      {
        // Error is less than desired tolerance
        Console.Write("Error of " + golden.Error + " is within tolerance of ");
        Console.WriteLine(golden.Tolerance + ".");
      }
      else
      {
        // Minimization ended because maximum iterations was reached
        Console.WriteLine("Ended with maximum iterations.");
      }
      Console.WriteLine();

      // Try Brent's Method for better efficiency.
      BrentMinimizer brent = new BrentMinimizer();
      min = brent.Minimize(function, lower, upper);

      Console.WriteLine("BrentMinimizer found a minimum of " + function.Evaluate(min));
      Console.WriteLine("at " + min + " in " + brent.Iterations + " iterations.");
      if (brent.ToleranceMet)
      {
        // Error is less than desired tolerance
        Console.Write("Error of " + brent.Error + " is within tolerance of ");
        Console.WriteLine(brent.Tolerance + ".");
      }
      else
      {
        // Minimization ended because maximum iterations was reached
        Console.WriteLine("Ended with maximum iterations.");
      }
      Console.WriteLine();

      // If the derivative is known, we can utilize a better Brent's
      // algorithm.

      // Create the derivative function.
      OneVariableFunction derivative = (new NMathFunctions.DoubleUnaryFunction(df));

      // Instantiate a DBrentMinimizer.
      DBrentMinimizer dbrent = new DBrentMinimizer();
      min = dbrent.Minimize(function, derivative, lower, upper);

      Console.WriteLine("DBrentMinimizer found a minimum of " + function.Evaluate(min));
      Console.WriteLine("at " + min + " in " + dbrent.Iterations + " iterations.");
      if (dbrent.ToleranceMet)
      {
        // Error is less than desired tolerance
        Console.Write("Error of " + dbrent.Error + " is within tolerance of ");
        Console.WriteLine(dbrent.Tolerance + ".");
      }
      else
      {
        // Minimization ended because maximum iterations was reached
        Console.WriteLine("Ended with maximum iterations.");
      }
      Console.WriteLine();

      // Increase the tolerance to 0.1
      dbrent.Tolerance = 0.1;
      min = dbrent.Minimize(function, derivative, lower, upper);

      Console.WriteLine("DBrentMinimizer found a minimum of " + function.Evaluate(min));
      Console.WriteLine("at " + min + " in " + dbrent.Iterations + " iterations.");
      if (dbrent.ToleranceMet)
      {
        // Error is less than desired tolerance
        Console.Write("Error of " + dbrent.Error + " is within tolerance of ");
        Console.WriteLine(dbrent.Tolerance + ".");
      }
      else
      {
        // Minimization ended because maximum iterations was reached
        Console.WriteLine("Ended with maximum iterations.");
      }
      Console.WriteLine();

      // Decrease tolerance to 1e-13 and increase the interval.
      dbrent.Tolerance = 1e-13;
      min = dbrent.Minimize(function, derivative, lower * 100, upper * 100);

      Console.WriteLine("DBrentMinimizer found a minimum of " + function.Evaluate(min));
      Console.WriteLine("at " + min + " in " + dbrent.Iterations + " iterations.");
      if (dbrent.ToleranceMet)
      {
        Console.Write("Error of " + dbrent.Error + " is within tolerance of ");
        Console.WriteLine(dbrent.Tolerance + ".");
      }
      else
      {
        Console.WriteLine("Ended with maximum iterations.");
      }
      Console.WriteLine();

      Console.WriteLine();
      Console.WriteLine("Press Enter Key");
      Console.Read();
    }

    private static double df(double x)
    {
      return 8 * Math.Cos(x) + 6 * x - 5;
    }

    private static double f(double x)
    {
      return 8 * Math.Sin(x) + 3 * x * x - 5 * x;
    }

  } // class

} // namepace
[TOC]