Root Bracketing Solvers in C# QuickStart Sample
Illustrates the use of the root bracketing solvers for solving equations in one variable in C#.
View this sample in: Visual Basic F# IronPython
using System;
// The RootBracketingSolver and derived classes reside in the
// Extreme.Mathematics.EquationSolvers namespace.
using Extreme.Mathematics.EquationSolvers;
// Function delegates reside in the Extreme.Mathematics
// namespace.
using Extreme.Mathematics;
using Extreme.Mathematics.Algorithms;
namespace Extreme.Numerics.QuickStart.CSharp
{
/// <summary>
/// Illustrates the use of the root bracketing solvers
/// in the Extreme.Mathematics.EquationSolvers namespace of Extreme Numerics.NET.
/// </summary>
class RootBracketingSolvers
{
static void Main(string[] args)
{
// The license is verified at runtime. We're using
// a demo license here. For more information, see
// https://numerics.net/trial-key
Extreme.License.Verify("Demo license");
if
// Root bracketing solvers are used to solve
// non-linear equations in one variable.
//
// Root bracketing solvers start with an interval
// which is known to contain a root. This interval
// is made smaller and smaller in successive
// iterations until a certain tolerance is reached,
// or the maximum number of iterations has been
// exceeded.
//
// The properties and methods that give you control
// over the iteration are shared by all classes
// that implement iterative algorithms.
//
// Target function
//
// The function we are trying to solve must be
// provided as a Func<double, double>. For more
// information about this delegate, see the
// FunctionDelegates QuickStart sample.
Func<double, double> f = Math.Cos;
// All root bracketing solvers inherit from
// RootBracketingSolver, an abstract base class.
RootBracketingSolver solver;
//
// Bisection method
//
// The bisection method halves the interval during
// each iteration. It is implemented by the
// BisectionSolver class.
Console.WriteLine("BisectionSolver: cos(x) = 0 over [1,2]");
solver = new BisectionSolver();
solver.LowerBound = 1;
solver.UpperBound = 2;
// The target function is a Func<double, double>.
// See above.
solver.TargetFunction = f;
double result = solver.Solve();
// The Status property indicates
// the result of running the algorithm.
Console.WriteLine(" Result: {0}", solver.Status);
// The result is also available through the
// Result property.
Console.WriteLine(" Solution: {0}", solver.Result);
// You can find out the estimated error of the result
// through the EstimatedError property:
Console.WriteLine(" Estimated error: {0}", solver.EstimatedError);
Console.WriteLine(" # iterations: {0}", solver.IterationsNeeded);
//
// Regula Falsi method
//
// The Regula Falsi method optimizes the selection
// of the next interval. Unfortunately, the
// optimization breaks down in some cases.
// Here is an example:
Console.WriteLine("RegulaFalsiSolver: cos(x) = 0 over [1,2]");
solver = new RegulaFalsiSolver();
solver.LowerBound = 1;
solver.UpperBound = 2;
solver.MaxIterations = 1000;
solver.TargetFunction = f;
result = solver.Solve();
Console.WriteLine(" Result: {0}", solver.Status);
Console.WriteLine(" Solution: {0}", solver.Result);
Console.WriteLine(" Estimated error: {0}", solver.EstimatedError);
Console.WriteLine(" # iterations: {0}", solver.IterationsNeeded);
// However, for sin(x) = 0, everything is fine:
Console.WriteLine("RegulaFalsiSolver: sin(x) = 0 over [-0.5,1]");
solver = new RegulaFalsiSolver();
solver.LowerBound = -0.5;
solver.UpperBound = 1;
solver.TargetFunction = Math.Sin;
result = solver.Solve();
Console.WriteLine(" Result: {0}", solver.Status);
Console.WriteLine(" Solution: {0}", solver.Result);
Console.WriteLine(" Estimated error: {0}", solver.EstimatedError);
Console.WriteLine(" # iterations: {0}", solver.IterationsNeeded);
//
// Dekker-Brent method
//
// The Dekker-Brent method combines the best of
// both worlds. It is the most robust and, on average,
// the fastest method.
Console.WriteLine("DekkerBrentSolver: cos(x) = 0 over [1,2]");
solver = new DekkerBrentSolver();
solver.LowerBound = 1;
solver.UpperBound = 2;
solver.TargetFunction = f;
result = solver.Solve();
Console.WriteLine(" Result: {0}", solver.Status);
Console.WriteLine(" Solution: {0}", solver.Result);
Console.WriteLine(" Estimated error: {0}", solver.EstimatedError);
Console.WriteLine(" # iterations: {0}", solver.IterationsNeeded);
//
// Controlling the process
//
Console.WriteLine("Same with modified parameters:");
// You can set the maximum # of iterations:
// If the solution cannot be found in time, the
// Status will return a value of
// IterationStatus.IterationLimitExceeded
solver.MaxIterations = 20;
// You can specify how convergence is to be tested
// through the ConvergenceCriterion property:
solver.ConvergenceCriterion =
ConvergenceCriterion.WithinRelativeTolerance;
// And, of course, you can set the absolute or
// relative tolerance.
solver.RelativeTolerance = 1e-6;
// In this example, the absolute tolerance will be
// ignored.
solver.AbsoluteTolerance = 1e-24;
solver.LowerBound = 157081;
solver.UpperBound = 157082;
solver.TargetFunction = f;
result = solver.Solve();
Console.WriteLine(" Result: {0}", solver.Status);
Console.WriteLine(" Solution: {0}", solver.Result);
// The estimated error will be less than 0.157
Console.WriteLine(" Estimated error: {0}", solver.EstimatedError);
Console.WriteLine(" # iterations: {0}", solver.IterationsNeeded);
Console.Write("Press Enter key to exit...");
Console.ReadLine();
}
}
}