C# Multi Variable Minimization Example

← All NMath Code Examples

 

using System;
using System.Diagnostics;

using CenterSpace.NMath.Core;


namespace CenterSpace.NMath.Examples.CSharp
{
  class MultiVariableMinimizationExample
  {
    /// <summary>
    /// A .NET example in C# showing how to find a minimum of a multivariate function
    /// using the downhill simplex method and Powells method.
    /// </summary>
    static void Main( string[] args )
    {
      // Create a multivariable function.
      var function = new MultiVariableFunction( new Func<DoubleVector, double>( f ) );

      // Start at ( 0, 0, 0, 0 ).
      var startPoint = new DoubleVector( 0.0, 0.0, 0.0, 0.0 );

      // Create a DownhillSimplexMinimizer with the default error tolerance and maximum
      // iterations.
      var simplex = new DownhillSimplexMinimizer();

      // Minimize the function.
      DoubleVector min = simplex.Minimize( function, startPoint );

      Console.WriteLine();

      Console.WriteLine( "DownhillSimplexMinimizer found a minimum of " + function.Evaluate( min ) );
      Console.WriteLine( "at " + min.ToString( "G7" ) + "." );

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

      // Increase the maximum number of iterations from the default of 100 to 1000.
      simplex.MaxIterations = 1000;

      // Minimize the function.
      min = simplex.Minimize( function, startPoint );

      Console.WriteLine( "DownhillSimplexMinimizer found a minimum of " + function.Evaluate( min ) );
      Console.WriteLine( "at " + min.ToString( "G7" ) + "." );

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

      // Now try using Powells Method.

      // Create the minimizer with default error tolerance and default maximum iterations.
      var powell = new PowellMinimizer();

      // Perform the minimization.
      min = powell.Minimize( function, startPoint );

      Console.WriteLine( "PowellMinimizer found a minimum of " + function.Evaluate( min ) );
      Console.WriteLine( "at " + min.ToString( "G7" ) + "." );

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

      // If the derivatives are known, then use one of the IMultiVariableDMinimizer
      // classes such as ConjugateGradientMinimizer.

      // Create an array of partial derivatives
      var partials = new MultiVariableFunction[4];
      partials[0] = new MultiVariableFunction( new Func<DoubleVector, double>( df0 ) );
      partials[1] = new MultiVariableFunction( new Func<DoubleVector, double>( df1 ) );
      partials[2] = new MultiVariableFunction( new Func<DoubleVector, double>( df2 ) );
      partials[3] = new MultiVariableFunction( new Func<DoubleVector, double>( df3 ) );

      // Create the minimizer with default tolerance and default maximum iterations.
      var cg = new ConjugateGradientMinimizer();

      // Perform the minimization.
      startPoint = new DoubleVector( 1.0, 2.0, 3.0, 4.0 );
      min = cg.Minimize( function, partials, startPoint );

      Console.WriteLine( "ConjugateGradientMinimizer found a minimum of " + function.Evaluate( min ) );
      Console.WriteLine( "at " + min.ToString( "G7" ) + "." );

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

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

    private static double df0( DoubleVector x )
    {
      return 1.6 * Math.Pow( x[0], 3 );
    }

    private static double df1( DoubleVector x )
    {
      return 0.1 * Math.Cos( x[1] );
    }

    private static double df2( DoubleVector x )
    {
      return 10 * x[2];
    }

    private static double df3( DoubleVector x )
    {
      return 16 * Math.Pow( x[3], 3 );
    }

    private static double f( DoubleVector x )
    {
      return 0.4 * Math.Pow( x[0], 4 ) + 0.1 * Math.Sin( x[1] ) + 5 * x[2] * x[2] + 4 * Math.Pow( x[3], 4 );
    }

  } // class

} // namespace


← All NMath Code Examples
Top