Optimization In One Dimension in Visual Basic QuickStart Sample
Illustrates the use of the Brent and Golden Section optimizer classes in the Numerics.NET.Optimization namespace for one-dimensional optimization in Visual Basic.
This sample is also available in: C#, F#, IronPython.
Overview
This QuickStart sample demonstrates how to find the minimum or maximum of a function in one dimension using Numerics.NET’s optimization capabilities.
The sample shows two different optimization algorithms:
- Brent’s algorithm - A sophisticated and efficient method that combines golden section search with
parabolic interpolation. It is the recommended method for most one-dimensional optimization problems.
The sample demonstrates how to:
- Create and configure a BrentOptimizer
- Find an interval containing an extremum using FindBracket
- Locate the precise minimum or maximum
- Access results and error estimates
- Golden Section Search - A simpler but slower algorithm based on the golden ratio. The sample shows how to use the GoldenSectionOptimizer class to find extrema.
Both methods are demonstrated on two test functions:
- A cubic polynomial f(x) = x� - 2x - 5
- An exponential function f(x) = 1/exp(x� - 0.7x + 0.2)
The sample illustrates proper error handling, accessing optimization results, and comparing estimated versus actual errors. It also shows how to use lambda expressions for defining objective functions in C# 3.0 and later.
The code
Option Infer On
' The optimization classes resides in the
' Numerics.NET.EquationSolvers namespace.
Imports Numerics.NET.Optimization
' Function delegates reside in the Numerics.NET
' namespace.
Imports Numerics.NET
' Illustrates the use of the Brent and Golden Section optimizers
' in the Numerics.NET.Optimization namespace of Numerics.NET.
Module OptimizationIn1D
Sub Main()
' The license is verified at runtime. We're using
' a 30 day trial key here. For more information, see
' https://numerics.net/trial-key
Numerics.NET.License.Verify("your-trial-key-here")
' Several algorithms exist for optimizing functions
' in one variable. The most common one is
' Brent's algorithm.
'
' Brent's algorithm
'
' Now let's create the BrentOptimizer object.
Dim optimizer As BrentOptimizer = New BrentOptimizer
' Set the objective function:
optimizer.ObjectiveFunction = AddressOf TestFunction1
' Optimizers can find either a minimum or a maximum.
' Which of the two is specified by the ExtremumType
' property
optimizer.ExtremumType = ExtremumType.Minimum
' The first phase is to find an interval that contains
' a local minimum. This is done by the FindBracket method.
optimizer.FindBracket(0, 6)
' You can verify that an interval was found from the
' IsBracketValid property:
If (Not optimizer.IsBracketValid) Then
Throw New Exception("An interval containing a minimum was not found.")
End If
' Finally, we can run the optimizer by calling the FindExtremum method:
optimizer.FindExtremum()
Console.WriteLine("Function 1: x^3 - 2x - 5")
' The Status property indicates
' the result of running the algorithm.
Console.WriteLine($" Result: {optimizer.Status}")
' The result is available through the
' Extremum property.
Console.WriteLine($" Minimum: {optimizer.Extremum}")
Dim exactResult = Math.Sqrt(2 / 3.0)
Dim result = optimizer.Extremum
Console.WriteLine($" Exact minimum: {exactResult}")
' You can find out the estimated error of the result
' through the EstimatedError property:
Console.WriteLine($" Estimated error: {optimizer.EstimatedError}")
Console.WriteLine($" Actual error: {Math.Abs(result - exactResult)}")
Console.WriteLine($" # iterations: {optimizer.IterationsNeeded}")
Console.WriteLine("Function 2: 1/Exp(x*x - 0.7*x +0.2)")
' You can also perform these calculations more directly
' using the FindMinimum or FindMaximum methods. This implicitly
' calls the FindBracket method.
result = optimizer.FindMaximum(AddressOf TestFunction2, 0)
Console.WriteLine($" Maximum: {result}")
Console.WriteLine($" Actual maximum: {0.35}")
Console.WriteLine($" Estimated error: {optimizer.EstimatedError}")
Console.WriteLine($" Actual error: {result - 0.35}")
Console.WriteLine($" # iterations: {optimizer.IterationsNeeded}")
'
' Golden section search
'
' A slower but simpler algorithm for finding an extremum
' is the golden section search. It is implemented by the
' GoldenSectionMinimizer class:
Dim optimizer2 As New GoldenSectionOptimizer
Console.WriteLine("Using Golden Section optimizer:")
result = optimizer2.FindMaximum(AddressOf TestFunction2, 0)
Console.WriteLine($" Maximum: {result}")
Console.WriteLine($" Actual maximum: {0.35}")
Console.WriteLine($" Estimated error: {optimizer2.EstimatedError}")
Console.WriteLine($" Actual error: {result - 0.35}")
Console.WriteLine($" # iterations: {optimizer2.IterationsNeeded}")
Console.Write("Press Enter key to exit...")
Console.ReadLine()
End Sub
' Minimum at x = Sqrt(2/3) = 0.816496580927726
Function TestFunction1(x As Double) As Double
Return x * x * x - 2 * x - 5
End Function
' Maximum at x = 0.35
Function TestFunction2(x As Double) As Double
Return 1 / Math.Exp(x * x - 0.7 * x + 0.2)
End Function
End Module