C# Trust Region Minimization Example

← All NMath Code Examples

 

using System;
using System.Collections.Generic;
using System.Text;

using CenterSpace.NMath.Core;


namespace CenterSpace.NMath.Examples.CSharp
{
  class TrustRegionMinimizationExample
  {
    /// <summary>
    /// A .NET example in C# showing how to minimize a function using the Trust Region 
    /// method.
    /// </summary>
    static void Main( string[] args )
    {
      // Minimization in this context means finding the solution that evaluates to the vector with the smallest
      // two norm (distance from origin).

      // TrustRegionMimizer provides the Minimize() method for minimizing a given function
      // encapsulated as a DoubleMultiVariableFunction, an abstract class for representing a multivariable function.
      // Instances override the Evaluate() method and, optionally, the Jacobian() method. If the Jacobian() method is not
      // overridden, a central differences approximation is used to calculate the Jacobian.
      var f = new MyFunction();

      // Choose a starting point
      var start = new DoubleVector( 50.0, 30.0, -1000.0 );

      // Create a minimizer with default tolerance and maximum iterations.
      var minimizer = new TrustRegionMinimizer();

      Console.WriteLine();

      // Compute the solution and display the results.
      Console.WriteLine( "Minimize by implementing DoubleMultiVariableFunction..." );
      DoubleVector solution = minimizer.Minimize( f, start );
      Print( minimizer, start, solution );

      // You can also wrap a function to minimize in a delegate, rather than extending DoubleMultiVariableFunction
      Func<DoubleVector, DoubleVector> f2 = delegate( DoubleVector x )
      {
        var y = new DoubleVector( 4 );
        y[0] = 5 * x[1] * x[1] + x[2] * x[2];
        y[1] = 4 * x[0] * x[0] - x[2] * x[2] + 45;
        y[2] = x[0] * 3 * x[0] - x[1] * x[1] + 9;
        y[3] = y[0] + y[1] + y[2] * y[2] - 43;
        return y;
      };
      Console.WriteLine( "Minimize using delegate..." );
      int ydim = 4;
      solution = minimizer.Minimize( f2, start, ydim );
      Print( minimizer, start, solution );

      // Now add some constraints. Set a lower bound to (0, 0, 0) and an upper bound to (10, 10, 10)
      Console.WriteLine( "Minimize with bounds..." );
      var lowerBounds = new DoubleVector( 3 );
      var upperBounds = new DoubleVector( 3, 10.0 );
      solution = minimizer.Minimize( f, start, lowerBounds, upperBounds );
      Console.WriteLine( "Lower bounds: {0}", lowerBounds );
      Console.WriteLine( "Upper bounds = {0} ", upperBounds );
      Print( minimizer, start, solution );

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

    }  // Main



    // Encapsulate a function that has three input variables and four output variables
    public class MyFunction : DoubleMultiVariableFunction
    {
      public MyFunction()
        : base( 3, 4 )
      {}

      public override void Evaluate( DoubleVector x, ref DoubleVector y )
      {
        if ( x.Length != 3 || y.Length != 4 )
        {
          throw new InvalidArgumentException( "bad length" );
        }

        y[0] = 5 * x[1] * x[1] + x[2] * x[2];
        y[1] = 4 * x[0] * x[0] - x[2] * x[2] + 45;
        y[2] = x[0] * 3 * x[0] - x[1] * x[1] + 9;
        y[3] = y[0] + y[1] + y[2] * y[2] - 43;
      }
    }

    // Display minimization results
    private static void Print( TrustRegionMinimizer minimizer, DoubleVector start, DoubleVector solution )
    {
      Console.WriteLine( "Start: {0}", start );
      Console.WriteLine( "Initial Residual: {0}", minimizer.InitialResidual.ToString( "G4" ));
      Console.WriteLine( "Solution: {0}", solution.ToString( "G4" ) );
      Console.WriteLine( "Final Residual: {0}", minimizer.FinalResidual.ToString( "G4" ) );
      Console.WriteLine( "Iterations: {0}", minimizer.Iterations );
      Console.WriteLine( "Stopping Criterion: {0}", minimizer.StopCriterion );
      Console.WriteLine();
    }
  }
}

← All NMath Code Examples
Top