| Free 60-day Trial |
|
Try it for free with our fully functional
60-day trial version.
Download now!
|
QuickStart Samples
Generic Algorithms QuickStart Sample (VB.NET)
Illustrates how to code algorithms that use generic arithmetic so they can be applied
to multiple operand types using classes and interfaces defined in the
Extreme.Mathematics.Generic namespace in Visual Basic.
C# code Back to QuickStart Samples
Imports System
' Basic generic types live in Extreme.Mathematics.Generics.
Imports Extreme.Mathematics.Generic
' We'll also need the big number types.
Imports Extreme.Mathematics
Namespace Extreme.Numerics.QuickStart.VB
' Illustrates writing generic algorithms that can be
' applied to different operand types using the types in the
' Extreme.Mathematics.Generic namespace.
Module GenericAlgorithms
Sub main()
' We will implement a simple Newton-Raphson solver class.
' The code for the solver is below.
' Here we will call the generic solver with three
' different operand types: BigFloat, BigRational and Double.
' First, let's compute pi to 100 digits
' by solving the equation sin(x) == 0 with
' an initual guess of 3.
Console.WriteLine("Computing pi by solving sin(x) = 0 with x0 = 3 using BigFloat.")
' Create the solver object.
Dim bigFloatSolver As New Solver(Of BigFloat)
' Set the function to solve, and its derivative.
' These functions are defined below.
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 pi As BigFloat = bigFloatSolver.Solve(3, BigFloat.Pow(10, -100))
' Print the results...
Console.WriteLine("Computed value: {0:F100}", pi)
' and verify:
Console.WriteLine("Known value: {0:F100}", _
BigFloat.GetPi(AccuracyGoal.Absolute(100)))
Console.WriteLine()
' Next, we will use rational numbers to compute
' an approximation to the square root of 2.
Console.WriteLine("Computing sqrt(2) by solving x^2 = 2 using BigRational.")
' Create the solver...
Dim bigRationalSolver As New Solver(Of BigRational)()
' Set properties...
bigRationalSolver.TargetFunction = New GenericFunction(Of BigRational)(AddressOf fBigRational)
bigRationalSolver.DerivativeOfTargetFunction = New GenericFunction(Of BigRational)(AddressOf dfBigRational)
' Compute the solution...
Dim sqrt2 As BigRational = bigRationalSolver.Solve(1, BigRational.Pow(10, -100))
' And print the result.
Console.WriteLine("Rational approximation: {0}", sqrt2)
' To verify, we convert the BigRational to a BigFloat:
Console.WriteLine("As real number: {0:F100}", _
New BigFloat(sqrt2, AccuracyGoal.Absolute(100), RoundingMode.TowardsNearest))
Console.WriteLine("Known value: {0:F100}", _
BigFloat.Sqrt(2, AccuracyGoal.Absolute(100), RoundingMode.TowardsNearest))
Console.WriteLine()
' Finally, we compute the Lambert W function at x = 3.
Console.WriteLine("Computing Lambert's W at x = 3 using Double.")
' Create the solver...
Dim doubleSolver As New Solver(Of Double)()
' Set properties...
doubleSolver.TargetFunction = New GenericFunction(Of Double)(AddressOf fDouble)
doubleSolver.DerivativeOfTargetFunction = New GenericFunction(Of Double)(AddressOf dfDouble)
' Compute the solution...
Dim W3 As Double = doubleSolver.Solve(1.0, 0.000000000000001)
' And print the result.
Console.WriteLine("Solution: {0}", W3)
Console.WriteLine("Known value: {0}", ElementaryFunctions.LambertW(3.0))
' Finally, we use generic functions:
Console.WriteLine("To 100 digits (using BigFloat):")
bigFloatSolver.TargetFunction = New GenericFunction(Of BigFloat)(AddressOf fGeneric(Of BigFloat))
bigFloatSolver.DerivativeOfTargetFunction = New GenericFunction(Of BigFloat)(AddressOf dfGeneric(Of BigFloat))
Dim bigW3 As BigFloat = bigFloatSolver.Solve(1, BigFloat.Pow(10, -100))
Console.WriteLine("Solution: {0:F100}", bigW3)
Console.Write("Press Enter key to exit...")
Console.ReadLine()
End Sub
' Functions for solving sin(x) = 0
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
' Functions for solving x^2 - 2 = 0
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
' Functions for solving x*exp(x) = 3 (i.e. W(3))
Function fDouble(ByVal x As Double) As Double
Return x * Math.Exp(x) - 3
End Function
Function dfDouble(ByVal x As Double) As Double
Return Math.Exp(x) * (1 + x)
End Function
' Generic versions of the above
Function fGeneric(Of T)(ByVal x As T) As T
Dim ops As IRealOperations(Of T) = _
CType(TypeAssociationRegistry.GetInstance( _
GetType(T), TypeAssociationRegistry.ArithmeticKey), _
IRealOperations(Of T))
Return ops.Subtract( _
ops.Multiply(x, ops.Exp(x)), _
ops.FromInt32(3))
End Function
Function dfGeneric(Of T)(ByVal x As T) As T
Dim ops As IRealOperations(Of T) = _
CType(TypeAssociationRegistry.GetInstance( _
GetType(T), TypeAssociationRegistry.ArithmeticKey), _
IRealOperations(Of T))
Return ops.Multiply( _
ops.Exp(x), _
ops.Add(x, ops.One))
End Function
End Module
' Class that contains the generic Newton-Raphson algorithm.
Class Solver(Of T)
' Use a variable to hold the arithmetic instance.
' We get the instance from the global TypeAssociationRegistry:
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)
Dim maxIters As Integer = 100
' 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 maximum number of iterations.
Public Property MaxIterations() As Integer
Get
Return maxIters
End Get
Set(ByVal value As Integer)
maxIters = value
End Set
End Property
' The core algorithm.
' Arithmetic operations are replaced by calls to
' methods on the arithmetic object (ops).
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
' Compute the denominator of the correction term.
Dim dfx As T = df(x)
' Relational operators map to the Compare method.
' We also use the value of zero for the operand type.
' if (dfx == 0)
If (ops.Compare(dfx, ops.Zero) = 0) Then
' Change value by 2x tolerance.
' When multiplying by a power of two, it's more efficient
' to use the ScaleByPowerOfTwo method.
dx = ops.ScaleByPowerOfTwo(tolerance, 1)
Else
' dx = f(x) / df(x)
dx = ops.Divide(f(x), dfx)
End If
' x -= dx
x = ops.Subtract(x, dx)
' if |dx|^2<tolerance
' Convergence is quadratic (in most cases), so we should be good here:
If (ops.Compare(ops.Multiply(dx, dx), tolerance) < 0) Then
Return x
End If
Loop While (iterations < MaxIterations)
Return x
End Function
End Class
End Namespace
Copyright © 2003-2010, 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.