The following program calculates the roots of a set of nonlinear equations using Newton's method.
Click here to download a ZIP file containing the project files for this program.
The program prompts you to either use the predefined default input values or to enter the following:
1. The values for the initial set of variables
2. The values for the tolerances for each variable.
3. The function tolerance
4. The maximum number of iterations
In case you choose the default input values, the program displays these values and proceeds to find the roots. In the case you select being prompted, the program displays the name of each input variable along with its default value. You can then either enter a new value or simply press Enter to use the default value. This approach allows you to quickly and efficiently change only a few input values if you so desire.
The program displays the following final results:
1. The coordinates of the minimum value.
2. The number of iterations
The current code finds the roots for the following functions:
F1(X) = X1 * X2 * X3 - 6
F2(X) = (X1 + X2) / X3 - 1
F3(X) = (X1 + 1) * X2 - X3 - 1
Using initial guesses of 3, 2, 1, and 1e-7 for the all variable tolerances, a function tolerance of 1e-7, and a maximum number of 500 iterations. Here is the sample console screen:

Here is the listing for the main module. The module contains several test functions:
Module Module1
Sub Main()
Dim nNumVars As Integer = 3
Dim fX() As Double = {3, 2, 1}
Dim fParam() As Double = {0, 0, 0}
Dim fToler() As Double = {0.00000001, 0.00000001, 0.00000001}
Dim nIter As Integer = 0
Dim nMaxIter As Integer = 500
Dim fEpsFx As Double = 0.0000001
Dim I As Integer
Dim sAnswer As String
Dim oRoot As CRoots_NLE_Newton1
Dim MyFx As MyFxDelegate = AddressOf Fx1
Dim SayFx As SayFxDelegate = AddressOf SayFx1
oRoot = New CRoots_NLE_Newton1
Console.WriteLine("Newton's method for finding the roots of simultaneous nonlinear equations")
Console.WriteLine("Finding the roots of functions:")
Console.WriteLine(SayFx())
Console.Write("Use default input values? (Y/N) ")
sAnswer = Console.ReadLine()
If sAnswer.ToUpper() = "Y" Then
For I = 0 To nNumVars - 1
Console.WriteLine("X({0}) = {1}", I + 1, fX(I))
Console.WriteLine("Tolerance({0}) = {1}", I + 1, fToler(I))
Next
Console.WriteLine("Function tolerance = {0}", fEpsFx)
Console.WriteLine("Maxumum cycles = {0}", nMaxIter)
Else
For I = 0 To nNumVars - 1
fX(I) = GetIndexedDblInput("X", I + 1, fX(I))
fToler(I) = GetIndexedDblInput("Tolerance", I + 1, fToler(I))
Next
fEpsFx = GetIntInput("Function tolerance", fEpsFx)
nMaxIter = GetDblInput("Maxumum cycles", nMaxIter)
End If
Console.WriteLine("******** FINAL RESULTS *************")
oRoot.CalcRoots(nNumVars, fX, fParam, fToler, fEpsFx, nMaxIter, nIter, MyFx)
Console.WriteLine("Optimum at")
For I = 0 To nNumVars - 1
Console.WriteLine("X({0}) = {1}", I + 1, fX(I))
Next
Console.WriteLine("Number of iterations = {0}", nIter)
Console.WriteLine()
Console.Write("Press Enter to end the program ...")
Console.ReadLine()
End Sub
Function GetDblInput(ByVal sPrompt As String, ByVal fDefInput As Double) As Double
Dim sInput As String
Console.Write("{0}? ({1}): ", sPrompt, fDefInput)
sInput = Console.ReadLine()
If sInput.Trim().Length > 0 Then
Return Double.Parse(sInput)
Else
Return fDefInput
End If
End Function
Function GetIntInput(ByVal sPrompt As String, ByVal nDefInput As Integer) As Integer
Dim sInput As String
Console.Write("{0}? ({1}): ", sPrompt, nDefInput)
sInput = Console.ReadLine()
If sInput.Trim().Length > 0 Then
Return Double.Parse(sInput)
Else
Return nDefInput
End If
End Function
Function GetIndexedDblInput(ByVal sPrompt As String, ByVal nIndex As Integer, ByVal fDefInput As Double) As Double
Dim sInput As String
Console.Write("{0}({1})? ({2}): ", sPrompt, nIndex, fDefInput)
sInput = Console.ReadLine()
If sInput.Trim().Length > 0 Then
Return Double.Parse(sInput)
Else
Return fDefInput
End If
End Function
Function GetIndexedIntInput(ByVal sPrompt As String, ByVal nIndex As Integer, ByVal nDefInput As Integer) As Integer
Dim sInput As String
Console.Write("{0}({1})? ({2}): ", sPrompt, nIndex, nDefInput)
sInput = Console.ReadLine()
If sInput.Trim().Length > 0 Then
Return Double.Parse(sInput)
Else
Return nDefInput
End If
End Function
Function SayFx1() As String
Return "F1(X) = X(1) * X(2) * X(3) - 6" & vbCrLf & _
"F2(X) = X(1) + x(2)) / X(3) - 1" & vbCrLf & _
"F3(X) = X(1) + 1) * x(2) - x(3) - 1"
End Function
Function Fx1(ByVal N As Integer, ByRef X() As Double, ByRef fParam() As Double, ByVal nVarIndex As Integer) As Double
Select Case nVarIndex
Case 1
Return X(0) * X(1) * X(2) - 6
Case 2
Return (X(0) + X(1)) / X(2) - 1
Case Else ' case 3
Return (X(0) + 1) * X(1) - X(2) - 1
End Select
End Function
End Module
Notice that the user-defined function has the following:
Please observe the following rules::
The program uses the following class to solve the simultaneous nonlinear functions along with the matrix class library (MatrixLib.vb) which you can download from the VB.Net: Master Page.
Public Delegate Function MyFxDelegate(ByVal nNumVars As Integer, ByRef fX() As Double, ByRef fParam() As Double, ByVal nVarIndex As Integer) As Double
Public Delegate Function SayFxDelegate() As String
Public Class CRoots_NLE_Newton1
Public Sub CalcRoots(ByVal nNumVars As Integer, ByRef fX() As Double, ByRef fParam() As Double, ByRef fToler() As Double, _
ByVal fEpsFx As Double, ByVal nMaxIter As Integer, ByRef nIter As Integer, ByVal MyFx As MyFxDelegate)
Dim g(nNumVars) As Double
Dim Jmat(nNumVars, nNumVars) As Double
Dim H, fXJ, Fp As Double
Dim I, J As Integer
Dim bGoOn As Boolean
nIter = 0
bGoOn = True
Do While bGoOn And nIter < nMaxIter
nIter += 1
If nIter > nMaxIter Then Exit Do
For I = 0 To nNumVars - 1
g(I) = MyFx(nNumVars, fX, fParam, I)
For J = 0 To nNumVars - 1
H = 0.01 * (1 + Math.Abs(fX(J)))
fXJ = fX(J)
fX(J) = fXJ + H
Fp = MyFx(nNumVars, fX, fParam, I)
fX(J) = fXJ
Jmat(I, J) = (Fp - g(I)) / H
Next
Next
' solve for the guess improvements
MatrixLibVb.SolveLU(Jmat, g, nNumVars)
For I = 0 To nNumVars - 1
fX(I) = fX(I) - g(I)
Next
' check refinement convergence
bGoOn = False
For I = 0 To nNumVars - 1
If Math.Abs(g(I)) > fToler(I) Then
bGoOn = True
End If
Next
' check function convergence
If bGoOn Then
bGoOn = False
For I = 0 To nNumVars - 1
If Math.Abs(g(I)) > fEpsFx Then
bGoOn = True
End If
Next
End If
Loop
End Sub
End Class
Copyright (c) Namir Shammas. All rights reserved.