Optimization In One Dimension in F# QuickStart Sample
Illustrates the use of the Brent and Golden Section optimizer classes in the Numerics.NET.Optimization namespace for one-dimensional optimization in F#.
View this sample in: C# Visual Basic IronPython
// Illustrates the use of the Brent and Golden Section optimizers
// in the Numerics.NET.Optimization namespace of Numerics.NET.
#light
open System
open Numerics.NET
// The optimization classes resides in the
// Numerics.NET.EquationSolvers namespace.
open Numerics.NET.Optimization
// The license is verified at runtime. We're using a 30 day trial key here.
// For more information, see:
// https://numerics.net/trial-key
let licensed = Numerics.NET.License.Verify("64542-18980-57619-62268")
// Several algorithms exist for optimizing functions
// in one variable. The most common one is
// Brent's algorithm.
// The function we are trying to minimize is called the
// objective function and must be provided as a Func<double, double>.
//
// Brent's algorithm
//
// Now let's create the BrentOptimizer object.
let optimizer = BrentOptimizer()
// Set the objective function:
optimizer.ObjectiveFunction <- Func<_,_> (fun x -> x * x * x - 2.0 * x - 5.0)
// 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.0, 3.0)
// You can verify that an interval was found from the
// IsBracketValid property:
if (not optimizer.IsBracketValid) then
raise (Exception("An interval containing a minimum was not found."))
// Finally, we can run the optimizer by calling the FindExtremum method:
let extremum = optimizer.FindExtremum()
printfn "Function 1: x^3 - 2x - 5"
// The Status property indicates
// the result of running the algorithm.
printfn " Status: %A" optimizer.Status
// The result is available through the
// Result property.
printfn " Minimum: %A" optimizer.Result
let exactResult = sqrt(2.0/3.0)
let result = optimizer.Extremum
printfn " Exact minimum: %A" exactResult
// You can find out the estimated error of the result
// through the EstimatedError property:
printfn " Estimated error: %A" optimizer.EstimatedError
printfn " Actual error: %A" (abs(result - exactResult))
printfn " # iterations: %d" optimizer.IterationsNeeded
printfn "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.
let f2 = Func<_,_> (fun x -> 1.0 / exp(x*x - 0.7*x + 0.2))
let result2 = optimizer.FindMaximum(f2, 0.0)
printfn " Maximum: %A" result2
printfn " Actual maximum: %A" 0.35
printfn " Estimated error: %A" optimizer.EstimatedError
printfn " Actual error: %A" (result - 0.35)
printfn " # iterations: %d" 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:
let optimizer2 = GoldenSectionOptimizer()
printfn "Using Golden Section optimizer:"
let result3 = optimizer2.FindMaximum(f2, 0.0)
printfn " Maximum: %A" result3
printfn " Actual maximum: %A" 0.35
printfn " Estimated error: %A" optimizer2.EstimatedError
printfn " Actual error: %A" (result - 0.35)
printfn " # iterations: %d" optimizer2.IterationsNeeded
printf "Press Enter key to exit..."
Console.ReadLine() |> ignore