Data Analysis Mathematics Linear Algebra Statistics
New Version 8.1!

Supports .NET 6.0. Try it for free with our fully functional 60-day trial version.

QuickStart Samples

# Numerical Differentiation QuickStart Sample (C#)

Illustrates how to approximate the derivative of a function in C#.

```using System;

namespace Extreme.Numerics.QuickStart.CSharp
{
// The numerical differentiation classes reside in the
// Extreme.Mathematics.Calculus namespace.
using Extreme.Mathematics.Calculus;
// Function delegates reside in the Extreme.Mathematics
// namespace.
using Extreme.Mathematics;

/// <summary>
/// Illustrates numerical differentiation using the
/// FunctionMath class in the Extreme.Mathematics
/// namespace of the Extreme Optimization Mathematics
/// Library for .NET.
/// </summary>
class NumericalDifferentiationSample
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
// Numerical differentiation is a fairly simple
// procedure. Its accuracy is inherently limited
// because of unavoidable round-off error.
//
// All calculations are performed by static methods
// of the FunctionMath class. All methods are extension
// methods, so they can be applied to the delegates
// directly.

double result;
double estimatedError;

//
// Standard numerical differentiation.
//

// Central differences are the standard way of
// approximating the result of a function.
// For this to work, it must be possible to
// evaluate the target function on both sides of
// the point where the numerical result is
// requested.

// The function must be provided as a
// this delegate, see the FunctionDelegates
// QuickStart Sample.
Func<double, double> fCentral = Math.Cos;

Console.WriteLine("Central differences:");
// The actual calculation is performed by the
// CentralDerivative method.
result = fCentral.CentralDerivative(1.0);
Console.WriteLine("  Result = {0}", result);
Console.WriteLine("  Actual = {0}", -Math.Sin(1.0));
// This method is overloaded. It has an optional
// out parameter that returns an estimate for the
// error in the result.
result = fCentral.CentralDerivative(1.0, out estimatedError);
Console.WriteLine("Estimated error = {0}",
estimatedError);

//
// Forward and backward differences.
//

// Some functions are not defined everywhere.
// If the result is required on a boundary
// of the domain where it is defined, the central
// differences method breaks down. This also happens
// if the function has a discontinuity close to the
// differentiation point.
//
// In these cases, either forward or backward
// differences may be used instead.
//
// Here is an example of a function that may require
// forward differences. It is undefined for
// x < -2:
Func<double, double> fForward = x => (x+2) * (x+2) * Math.Sqrt(x+2);

// Calculating the derivative using central
// differences returns NaN (Not a Number):
result = fForward.CentralDerivative(-2.0, out estimatedError);
Console.WriteLine("Using central differences may not work:");
Console.WriteLine("  Derivative = {0}", result);
Console.WriteLine("  Estimated error = {0}", estimatedError);

// Using the ForwardDerivative method does work:
result = fForward.ForwardDerivative(-2.0, out estimatedError);
Console.WriteLine("  Derivative = {0}", result);
Console.WriteLine("  Estimated error = {0}", estimatedError);

// The FBackward function at the end of this file
// is an example of a function that requires
// backward differences for differentiation at
// x = 0.
Func<double, double> fBackward = x => x > 0.0 ? 1.0 : Math.Sin(x);
Console.WriteLine("Using backward differences:");
result = fBackward.BackwardDerivative(0.0, out estimatedError);
Console.WriteLine("  Derivative = {0}", result);
Console.WriteLine("  Estimated error = {0}", estimatedError);

//
// Derivative function
//

// In some cases, it may be useful to have the
// derivative of a function in the form of a
// Func<double, double>, so it can be passed as
// an argument to other methods. This is very
// easy to do.
Console.WriteLine("Using delegates:");

// For central differences:
Func<double, double> dfCentral = fCentral.GetNumericalDifferentiator();
Console.WriteLine("Central: f'(1) = {0}", dfCentral(1));

// For forward differences:
Func<double, double> dfForward = fForward.GetForwardDifferentiator();
Console.WriteLine("Forward: f'(-2) = {0}", dfForward(-2));

// For backward differences:
Func<double, double> dfBackward = fBackward.GetBackwardDifferentiator();
Console.WriteLine("Backward: f'(0) = {0}", dfBackward(0));

Console.Write("Press Enter key to exit...");