Extreme Optimization™: Complexity made simple.

Math and Statistics
Libraries for .NET

  • Home
  • Features
    • Math Library
    • Vector and Matrix Library
    • Statistics Library
    • Performance
    • Usability
  • Documentation
    • Introduction
    • Math Library User's Guide
    • Vector and Matrix Library User's Guide
    • Data Analysis Library User's Guide
    • Statistics Library User's Guide
    • Reference
  • Resources
    • Downloads
    • QuickStart Samples
    • Sample Applications
    • Frequently Asked Questions
    • Technical Support
  • Blog
  • Order
  • Company
    • About us
    • Testimonials
    • Customers
    • Press Releases
    • Careers
    • Partners
    • Contact us
Introduction
Deployment Guide
Nuget packages
Configuration
Using Parallelism
Expand Mathematics Library User's GuideMathematics Library User's Guide
Expand Vector and Matrix Library User's GuideVector and Matrix Library User's Guide
Expand Data Analysis Library User's GuideData Analysis Library User's Guide
Expand Statistics Library User's GuideStatistics Library User's Guide
Expand Data Access Library User's GuideData Access Library User's Guide
Expand ReferenceReference
  • Extreme Optimization
    • Features
    • Solutions
    • Documentation
    • QuickStart Samples
    • Sample Applications
    • Downloads
    • Technical Support
    • Download trial
    • How to buy
    • Blog
    • Company
    • Resources
  • Documentation
    • Introduction
    • Deployment Guide
    • Nuget packages
    • Configuration
    • Using Parallelism
    • Mathematics Library User's Guide
    • Vector and Matrix Library User's Guide
    • Data Analysis Library User's Guide
    • Statistics Library User's Guide
    • Data Access Library User's Guide
    • Reference
  • Mathematics Library User's Guide
    • General Classes
    • Mathematical Functions
    • Complex Numbers
    • Arbitrary Precision Arithmetic
    • Automatic Differentiation
    • Curves and Interpolation
    • Curve Fitting
    • Solving Equations
    • Optimization
    • Calculus
    • Fast Fourier Transforms
    • Random Numbers
    • Generic Arithmetic
    • Appendices
  • Generic Arithmetic
    • Using Generic Arithmetic
    • Interfaces for Generic Operations
    • Generic Linear Algebra
  • Using Generic Arithmetic

Using Generic Arithmetic

Extreme Optimization Numerical Libraries for .NET Professional

Writing generic algorithms that involve arithmetic is fairly straightforward. Unfortunately, the convenience of using generic arithmetic is limited by lack of support in programming languages.

Generic Operations

The OperationsT type contains fields and methods that perform arithmetic operations and compute elementary functions for arbitrary types. The types that are supported out-of-the-box are: Double, Single, Quad, Decimal, SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, UInt64, Boolean, BigInteger, BigRational, BigFloat. The details of how to implement these operations for your own types are discussed later.

Using the OperationsT class is very straightforward. The following operations are available:

  • Constants: Zero, One, MinusOne, Epsilon, PositiveInfinity, NegativeInfinity, NaN.

  • Arithmetic operations: Add, Subtract, Negate, Abs, Multiply, Divide, Pow, Reciprocal.

  • Relational operations: Compare, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, EqualTo, NoEqualTo, IsZero, IsOne.

  • Elementary functions: Sqrt, Log, Log1PlusX, Exp, Hypot, Sin, Cos, Tan, Asin, Acos, Atan, Atan2, Sinh, Cosh, Tanh, Asinh, Acosh, Atanh.

  • Misc. operations: IsNaN, IsInfinity, FromInt32, FromDouble, Floor, Ceiling, IsReal.

To illustrate how to use these methods, we will implement the Newton-Raphson method for solving equations in generic arithmetic. The code below implements the algorithm:

C#
VB
C++
F#
Copy
public static double Solve(Func<double, double> function,
    Func<double, double> derivative, double initialGuess, double tolerance)
{
    int maxIterations = 20;
    double x = initialGuess;
    for (int i = 0; i < maxIterations; i++)
    {
        var y = function(x);
        var dy = derivative(x);
        var dx = y / dy;
        var x1 = x - dx;
        var activeTolerance = tolerance * Math.Abs(x1);
        if (Math.Abs(dx) < activeTolerance)
            return x1;
        x = x1;
    }
    throw new Exception("Max. number of iterations exceeded.");
}
Public Shared Function Solve(f As Func(Of Double, Double),
    df As Func(Of Double, Double), initialGuess As Double, tolerance As Double)

    Dim maxIterations As Integer = 20
    Dim x As Double = initialGuess
    For i = 1 To maxIterations
        Dim y = f(x)
        Dim dy = df(x)
        Dim dx = y / dy
        Dim x1 = x - dx
        Dim activeTolerance = tolerance * Math.Abs(x1)
        If (Math.Abs(dx) < activeTolerance) Then
            Return x1
        End If
        x = x1
    Next
    Throw New Exception("Max. number of iterations exceeded.")
End Function

No code example is currently available or this language may not be supported.

let SolveDouble f df initialGuess tolerance =

    let maxIterations = 20
    let rec iterate x i =
        match i with
        | _ when i < maxIterations -> 
            let y = f x
            let dy = df x
            let dx = y / dy
            let x1 = x - dx
            let activeTolerance = tolerance * abs(x1)
            if (abs(dx) < activeTolerance) then x1 else iterate x1 (i+1)
        | _ -> failwith "Max. number of iterations exceeded."
    iterate initialGuess 0

To make this code generic, we add a generic type parameter to the method and replace all references to Double with this type parameter. We then replace all operators and method calls with the equivalent member of the OperationsT class. This gives us:

C#
VB
C++
F#
Copy
public static T Solve<T>(Func<T, T> function, Func<T,T> derivative,
    T initialGuess, T tolerance) {

    int maxIterations = 20;
    T x = initialGuess;
    for (int i = 0; i < maxIterations; i++)
    {
        var y = function(x);
        var dy = derivative(x);
        var dx = Operations<T>.Divide(y, dy);
        var x1 = Operations<T>.Subtract(x, dx);
        var activeTolerance = Operations<T>.Multiply(tolerance,
            Operations<T>.Abs(x1));
        if (Operations<T>.LessThan(Operations<T>.Abs(dx), activeTolerance))
            return x1;
        x = x1;
    }
    throw new Exception("Max. number of iterations exceeded.");
}
Public Shared Function Solve(Of T)(f As Func(Of T, T), df As Func(Of T, T),
    initialGuess As T, tolerance As T) As T

    Dim maxIterations As Integer = 20
    Dim x As T = initialGuess
    For i = 1 To maxIterations

        Dim y = f(x)
        Dim dy = df(x)
        Dim dx = Operations(Of T).Divide(y, dy)
        Dim x1 = Operations(Of T).Subtract(x, dx)
        Dim activeTolerance = Operations(Of T).Multiply(tolerance,
            Operations(Of T).Abs(x1))
        If (Operations(Of T).LessThan(Operations(Of T).Abs(dx), activeTolerance)) Then
            Return x1
        End If
        x = x1
    Next
    Throw New Exception("Max. number of iterations exceeded.")
End Function

No code example is currently available or this language may not be supported.

let Solve f df (initialGuess : 'a) tolerance =

    let maxIterations = 20
    let rec iterate x i =
        match i with
        | _ when i < maxIterations ->
            let y = f(x)
            let dy = df(x)
            let dx = Operations<_>.Divide(y, dy)
            let x1 = Operations<_>.Subtract(x, dx)
            let activeTolerance = 
                Operations<_>.Multiply(tolerance, 
                    Operations<_>.Abs(x1))
            if (Operations<_>.LessThan(Operations<_>.Abs(dx), activeTolerance)) 
                then x1
            else
                iterate x1 (i+1)
        | _ -> failwith "Max. number of iterations exceeded."
    iterate initialGuess 0

We can now call this method with different types. We will keep it really simple here, and calculate the square root of 3 by solving the equation x2-3=0:

C#
VB
C++
F#
Copy
var xSingle = Solve(x => x * x - 3.0f, x => 2.0f * x, 1.0f, 1e-5f);
var xDouble = Solve(x => x * x - 3.0, x => 2.0 * x, 1.0, 1e-15);
var xQuad = Solve(x => x * x - 3, x => 2 * x, Quad.One, 10 * Quad.Epsilon);
var xRational = Solve(x => x * x - 3, x => 2 * x, BigRational.One, 
    new BigRational(1, 1000000000));
Console.WriteLine("Single precision result: {0}", xSingle);
Console.WriteLine("Double precision result: {0}", xDouble);
Console.WriteLine("Quad precision result: {0}", xQuad);
Console.WriteLine("Rational result: {0} ({1})", xRational, (double)xRational);
Dim xSingle = Solve(Function(x) x * x - 3.0F, Function(x) 2.0F * x, 1.0F, 0.00001F)
Dim xDouble = Solve(Function(x) x * x - 3.0, Function(x) 2.0 * x, 1.0, 0.000000000000001)
Dim xQuad = Solve(Function(x) x * x - 3, Function(x) 2 * x, Quad.One, 10 * Quad.Epsilon)
Dim xRational = Solve(Function(x) x * x - 3, Function(x) 2 * x, BigRational.One,
    New BigRational(1, 1000000000))
Console.WriteLine("Single precision result: {0}", xSingle)
Console.WriteLine("Double precision result: {0}", xDouble)
Console.WriteLine("Quad precision result: {0}", xQuad)
Console.WriteLine("Rational result: 0 (1)", xRational, CType(xRational, Double))

No code example is currently available or this language may not be supported.

let xSingle = Solve (fun x -> x * x - 3.0f) (fun x -> 2.0f * x) 1.0f 1e-5f
let xDouble = Solve (fun x -> x * x - 3.0) (fun x -> 2.0 * x) 1.0 1e-15
let xQuad = Solve (fun x -> x * x - Quad(3)) (fun x -> Quad(2) * x) Quad.One (Quad(10) * Quad.Epsilon)
let xRational = Solve(fun x -> x * x - 3) (fun x -> 2 * x) BigRational.One (BigRational(1, 1000000000))
printfn "Single precision result: %f" xSingle
printfn "Double precision result: %f" xDouble
printfn "Quad precision result: %A" xQuad
printfn "Rational result: %A (%f)" xRational ((double)xRational)
Generic linear algebra

All types that represent vectors, matrices, or matrix decompositions are generic over the element type. This means that the same code can be used for different element types.

Not all methods are available for all operand types. For example, in order to solve a system of equations, you need at least full division. Integer division is not enough. Calling a method for which the operand type doesn't support the necessary operations will result in a GenericArithmeticException.

The example below constructs a 20x20 Hilbert matrix and computes its inverse. Hilbert matrices are infamous for the numerical difficulties involved in performing calculations with them. The condition number of a 20x20 Hilbert matrix is about 1030, which means that about 30 digits of precision are lost in the calculation. So, we use the BigRational type for the matrix elements.

C#
VB
C++
F#
Copy
int n = 20;
Matrix<BigRational> h = Matrix.Create(n, n,
        (i, j) => new BigRational(1, i + j + 1));
Matrix<BigRational> hInv = h.GetInverse();
Dim n As Integer = 20
Dim h As Matrix(Of BigRational) = Matrix.Create(n, n,
        Function(i, j) New BigRational(1, i + j + 1))
Dim hInv = h.GetInverse()

No code example is currently available or this language may not be supported.

let n = 20
let h = Matrix.Create(n, n, 
            fun i j -> BigRational(1, i + j + 1))
let hInv = h.GetInverse()
Operand Types and Arithmetic Types

Generic arithmetic is implemented by associating with each operand type a class (the arithmetic type) that implements the operations on that operand type. The association between an operand type and its arithmetic type is declared using a TypeAssociationAttribute.

To perform generic operations, you need to first acquire an instance of the arithmetic type. This is done with a call to the GetInstance method of the TypeAssociationRegistry class. This is a static method, and takes two arguments. The first argument is the operand type. The second argument is a key that identifies the association. The key is a string. The key that identifies the arithmetic type is ArithmeticKey.

The return value is an instance of the arithmetic type. It implements one or more of the generic interfaces defined in the next section. The example below illustrates how to obtain the arithmetic for a generic type. The arithmetic implements IRingOperationsT, which means it supports addition, multiplication and related operations, but not division.

C#
VB
C++
F#
Copy
IRingOperations<T> R = TypeAssociationRegistry.GetInstance(typeof(T), 
    TypeAssociationRegistry.ArithmeticKey) as IRingOperations<T>;
Dim R As IRingOperations(Of T) = CType(TypeAssociationRegistry.GetInstance(GetType(T), 
    TypeAssociationRegistry.ArithmeticKey), IRingOperations(Of T));

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Obtaining the arithmetic is a relatively expensive operation, especially compared to the work done by individual operations. It is usually a good idea to cache the arithmetic in a static variable that is available to all instances of the containing type.

Generic calculations

Once you have an instance of the arithmetic type, you can use it to perform calculations with the operand type. Not all operand types support the same set of operations. Which operations they support is determined by the interfaces that the arithmetic type implements. A thorough overview of the different interfaces for generic arithmetic is given in the next section.

To illustrate how generic algorithms can be coded, we will implement a generic algorithm for the solution of an equation using Newton's method. Newton's method finds the solution of an equation f(x)=0 using the following iteration formula:

We start out with the non-generic version using doubles.

C#
VB
C++
F#
Copy
class Solver
{
    // Member fields:
    RealFunction f, df;

    // The function to solve:
    public RealFunction TargetFunction
    {
        get { return f; }
        set { f = value; }
    }
    // The derivative of the function to solve.
    public RealFunction DerivativeOfTargetFunction
    {
        get { return df; }
        set { df = value; }
    }

    // The core algorithm.
    public double Solve(double initialGuess, double tolerance)
    {
        int iterations = 0;
        double x = initialGuess;
        double dx = 0.0;
        do
        {
            iterations++;
            // Compute the denominator of the correction term.
            double dfx = df(x);
            if (dfx == 0.0)
            {
                // Change value by 2x tolerance.
                dx = 2 * tolerance;
            }
            else
            {
                dx = f(x) / dfx;
            }
            x -= dx;

            if (Math.Abs(dx) < tolerance)
                return x;
        }
        while (iterations < 100);
        return x;
    }
}
Class Solver

    ' Member fields:
    Dim f, df As RealFunction

    ' The function to solve:
    Public Property TargetFunction() As RealFunction
        Get
            Return f
        End Get
        Set(ByVal value As RealFunction)
            f = value
        End Set
    End Property

    ' The derivative of the function to solve.
    Public Property DerivativeOfTargetFunction() As RealFunction
        Get
            Return df
        End Get
        Set(ByVal value As RealFunction)
            df = value
        End Set
    End Property

    ' The core algorithm.
    Public Function Solve(ByVal initialGuess As Double, ByVal tolerance As Double) As Double

        Dim iterations As Integer = 0
        Dim x As Double = initialGuess
        Dim dx As Double = 0.0
        Do
            iterations = iterations + 1
            ' Compute the denominator of the correction term.
            Dim dfx As Double = df(x)
            If (dfx = 0) Then
                ' Change value by 2x tolerance.
                dx = 2 * tolerance
            Else
                dx = f(x) / dfx
            End If
            x = x - dx

            If Math.Abs(dx) < tolerance Then
                Return x
            End If
        Loop While (iterations < MaxIterations)
        Return x
    End Function
End Class

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

The first step is to add a generic type parameter to the class definition, and replace all occurrences of the operand type with the generic parameter type. We also want to replace all related types, like delegates and lists, with the corresponding generic type. In this case, we replace all occurrences of Double with T. We also replace FuncT, TResult with its generic equivalent, FuncT, TResult. This gives us the following:

C#
VB
C++
F#
Copy
class Solver<T>
{
    // Member fields:
    GenericFunction<T> f, df;

    // The function to solve:
    public GenericFunction<T> TargetFunction
    {
        get { return f; }
        set { f = value; }
    }
    // The derivative of the function to solve.
    public GenericFunction<T> DerivativeOfTargetFunction
    {
        get { return df; }
        set { df = value; }
    }

    // The core algorithm.
    public T Solve(T initialGuess, T tolerance)
    {
        int iterations = 0;
        T x = initialGuess;
        T dx = 0.0;
        do
        {
            iterations++;
            // Compute the denominator of the correction term.
            T dfx = df(x);
            if (dfx == 0.0)
            {
                // Change value by 2x tolerance.
                dx = 2 * tolerance;
            }
            else
            {
                dx = f(x) / dfx;
            }
            x -= dx;

            if (Math.Abs(dx) < tolerance)
                return x;
        }
        while (iterations < 100);
        return x;
    }
}
Class Solver(Of T)

    ' Member fields:
    Dim f, df As GenericFunction(Of T)

    ' The function to solve:
    Public Property TargetFunction() As GenericFunction(Of T)
        Get
            Return f
        End Get
        Set(ByVal value As GenericFunction(Of T))
            f = value
        End Set
    End Property

    ' The derivative of the function to solve.
    Public Property DerivativeOfTargetFunction() As GenericFunction(Of T)
        Get
            Return df
        End Get
        Set(ByVal value As GenericFunction(Of T))
            df = value
        End Set
    End Property

    ' The core algorithm.
    Public Function Solve(ByVal initialGuess As T, ByVal tolerance As T) As T

        Dim iterations As Integer = 0
        Dim x As T = initialGuess
        Dim dx As T = 0.0
        Do
            iterations = iterations + 1
            Dim dfx As T = df(x)
            If (dfx = 0) Then
                dx = 2 * tolerance
            Else
                dx = f(x) / dfx
            End If
            x = x - dx

            If Math.Abs(dx) < tolerance Then
                Return x
            End If
        Loop While (iterations < MaxIterations)
        Return x
    End Function
End Class

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

The last step is to create a static (Shared in Visual Basic) variable in the class to hold an instance of the arithmetic type, and to replace all arithmetic operations with calls to methods of this instance. For Newton's algorithm, we need division, so the type of the arithmetic should be IFieldOperationsT. The different generic arithmetic interfaces are covered in the next section. This gives us the following final result:

C#
VB
C++
F#
Copy
class Solver<T>
{
    static IFieldOperations<T> ops = 
        (IFieldOperations<T>)TypeAssociationRegistry.GetInstance(
            typeof(T), TypeAssociationRegistry.ArithmeticKey);

    // Member fields:
    GenericFunction<T> f, df;

    // The function to solve:
    public GenericFunction<T> TargetFunction
    {
        get { return f; }
        set { f = value; }
    }
    // The derivative of the function to solve.
    public GenericFunction<T> DerivativeOfTargetFunction
    {
        get { return df; }
        set { df = value; }
    }

    // The core algorithm.
    public T Solve(T initialGuess, T tolerance)
    {
        int iterations = 0;
        T x = initialGuess;
        T dx = ops.Zero;
        do
        {
            iterations++;
            T dfx = df(x);
            if (ops.Compare(dfx, ops.Zero) == 0)
            {
                // Change value by 2x tolerance.
                dx = ops.ScaleByPowerOfTwo(tolerance, 1);
            }
            else
            {
                dx = ops.Divide(f(x), dfx);
            }
            x = ops.Subtract(x, dx);

            if (ops.Compare(ops.Abs(dx), tolerance) < 0)
                return x;
        }
        while (iterations < 100);
        return x;
    }
}
Class Solver(Of T)

    Dim ops As IFieldOperations(Of T) = _
        CType(TypeAssociationRegistry.GetInstance( _
            GetType(T), TypeAssociationRegistry.ArithmeticKey), _
            IFieldOperations(Of T))

    ' Member fields:
    Dim f, df As GenericFunction(Of T)

    ' The function to solve:
    Public Property TargetFunction() As GenericFunction(Of T)
        Get
            Return f
        End Get
        Set(ByVal value As GenericFunction(Of T))
            f = value
        End Set
    End Property

    ' The derivative of the function to solve.
    Public Property DerivativeOfTargetFunction() As GenericFunction(Of T)
        Get
            Return df
        End Get
        Set(ByVal value As GenericFunction(Of T))
            df = value
        End Set
    End Property

    ' The core algorithm.
    Public Function Solve(ByVal initialGuess As T, ByVal tolerance As T) As T

        Dim iterations As Integer = 0
        Dim x As T = initialGuess
        Dim dx As T = ops.Zero
        Do
            iterations = iterations + 1
            Dim dfx As T = df(x)
            If (ops.Compare(dfx, ops.Zero) = 0) Then
                dx = ops.ScaleByPowerOfTwo(tolerance, 1)
            Else
                dx = ops.Divide(f(x), dfx)
            End If
            x = ops.Subtract(x, dx)

            If ops.Compare(ops.Abs(dx), tolerance) < 0 Then
                Return x
            End If
        Loop While (iterations < MaxIterations)
        Return x
    End Function
End Class

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Values of 0 were replaced with calls to the Zero property. Relational operators were replaced with calls to the Compare method.

We are now ready to use this class with any operand type that has an associated arithmetic with a full division operator. As a first example, we'll compute the number π to 100 digits by solving sin x = 0 using the BigFloat with a starting value of 3:

C#
VB
C++
F#
Copy
Solver<BigFloat> bigFloatSolver = new Solver<BigFloat>();
// Set the function to solve, and its derivative.
bigFloatSolver.TargetFunction = delegate(BigFloat x) { return BigFloat.Sin(x); };
bigFloatSolver.DerivativeOfTargetFunction = delegate(BigFloat x) { return BigFloat.Cos(x); };
// Now solve to within a tolerance of 10^-100.
BigFloat pi = bigFloatSolver.Solve(3, BigFloat.Pow(10, -100));
Function fBigFloat(ByVal x As BigFloat) As BigFloat
    Return BigFloat.Sin(x)
End Function
Function dfBigFloat(ByVal x As BigFloat) As BigFloat
    Return BigFloat.Cos(x)
End Function

Dim bigFloatSolver As New Solver(Of BigFloat)
' Set the function to solve, and its derivative.
bigFloatSolver.TargetFunction = New GenericFunction(Of BigFloat)(AddressOf fBigFloat)
bigFloatSolver.DerivativeOfTargetFunction = New GenericFunction(Of BigFloat)(AddressOf dfBigFloat)
' Now solve to within a tolerance of 10^-100.
Dim sqrt2 As BigFloat = bigFloatSolver.Solve(1, BigFloat.Pow(10, -100))

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Next, we compute a rational approximation to the square root of 2:

C#
VB
C++
F#
Copy
Solver<BigRational> bigRationalSolver = new Solver<BigRational>();
// Set the function to solve, and its derivative.
bigRationalSolver.TargetFunction = delegate(BigRational x) { return x*x - 2; };
bigRationalSolver.DerivativeOfTargetFunction = delegate(BigRational x) { return 2*x; };
// Now solve to within a tolerance of 10^-100.
BigRational pi = bigRationalSolver.Solve(3, BigRational.Pow(10, -100));
Function fBigRational(ByVal x As BigRational) As BigRational
    Return x * x - 2
End Function
Function dfBigRational(ByVal x As BigRational) As BigRational
    Return 2 * x
End Function

Dim bigRationalSolver As New Solver(Of BigRational)()
' Set the function to solve, and its derivative.
bigRationalSolver.TargetFunction = New GenericFunction(Of BigRational)(AddressOf fBigRational)
bigRationalSolver.DerivativeOfTargetFunction = New GenericFunction(Of BigRational)(AddressOf dfBigRational)
' Now solve to within a tolerance of 10^-100.
Dim sqrt2 As BigRational = bigRationalSolver.Solve(1, BigRational.Pow(10, -100))

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Finally, we show that our solver class works just as well for the built-in types, including Double. We use the exact same code as above, and simply replace all references to BigRational with references to Double.

C#
VB
C++
F#
Copy
Solver<double> doubleSolver = new Solver<double>();
// Set the function to solve, and its derivative.
doubleSolver.TargetFunction = delegate(double x) { return x*x - 2; };
doubleSolver.DerivativeOfTargetFunction = delegate(double x) { return 2*x; };
// Now solve to within a tolerance of 10^-100.
double pi = doubleSolver.Solve(3.0, 1e-10);
Function fDouble(ByVal x As double) As double
    Return x * x - 2
End Function
Function dfDouble(ByVal x As double) As double
    Return 2 * x
End Function

Dim doubleSolver As New Solver(Of Double)()
' Set the function to solve, and its derivative.
doubleSolver.TargetFunction = New GenericFunction(Of Double)(AddressOf fDouble)
doubleSolver.DerivativeOfTargetFunction = New GenericFunction(Of Double)(AddressOf dfDouble)
' Now solve to within a tolerance of 10^-10.
Dim sqrt2 As Double = doubleSolver.Solve(1.0, 0.0000000001)

No code example is currently available or this language may not be supported.

No code example is currently available or this language may not be supported.

Copyright (c) 2004-2021 ExoAnalytics Inc.

Send comments on this topic to support@extremeoptimization.com

Copyright © 2004-2021, Extreme Optimization. All rights reserved.
Extreme Optimization, Complexity made simple, M#, and M Sharp are trademarks of ExoAnalytics Inc.
Microsoft, Visual C#, Visual Basic, Visual Studio, Visual Studio.NET, and the Optimized for Visual Studio logo
are registered trademarks of Microsoft Corporation.