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