[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]