Post Reply 
Variant of the Secant Method
12-10-2020, 02:56 PM (This post was last modified: 12-11-2020 01:18 PM by Namir.)
Post: #6
RE: Variant of the Secant Method
I was able to implement in Excel VBA a version of the Generalized Secant algorithm using divided differences for the first, second and third derivatives.

Here is the VBA listing for the version that uses two initial guesses and divided differences for the first and second derivatives.
Code:



Cell Mapping
===========
A1 : "X0"
A2 : value for X0
A3 : "X1"
A4 : value for X1
A5 : "Tolerance"
A6 : value for tolerance
A7 : "F(x)"
A8: String containing expression for f(x)=0, such as exp(x)-3*x^2.
B1 : "X"
C1 : "F(X)"  (for Generalized Secant method)
D1 : "X"
E1 : "F(X)"  (for Newton's method, used for comparison)

VBA Listing
===========

Function Fx(ByVal sFx As String, ByVal X As Double) As Double
  sFx = Replace(sFx, "EXP", "!")
  sFx = Replace(sFx, "X", "(" & CStr(X) & ")")
  sFx = Replace(sFx, "!", "EXP")
  Fx = Evaluate(sFx)
End Function

Sub genSecant2()
  Dim sFx As String, X0 As Double, X1 As Double, X2 As Double, X3 As Double
  Dim Toler As Double, Df1 As Double, Df2 As Double
  Dim Row As Integer, h As Double
  Dim Fx0 As Double, Fx1 As Double, Fx2 As Double, Diff As Double
  
  Range("B2:X1000").Clear
  
  X0 = [A2].Value
  X1 = [A4].Value
  Toler = [A6].Value
  sFx = [A8].Value
  sFx = Replace(sFx, " ", "")
  sFx = UCase(sFx)
  
  Fx0 = Fx(sFx, X0)
  Fx1 = Fx(sFx, X1)
  Df1 = Fx0 / (X0 - X1) + Fx1 / (X1 - X0)
  X2 = X1 - Fx1 / Df1
  Fx2 = Fx(sFx, X2)
  Diff = X2 - X1
  
  Row = 2
  Cells(Row, 2) = X2
  Cells(Row, 3) = Fx(sFx, X2)
  Row = Row + 1
  Do Until Abs(Diff) < Toler
    Df1 = Fx2 / (X2 - X1) + Fx1 / (X1 - X2)
    Df2 = Fx2 / (X2 - X1) / (X2 - X0) + Fx1 / (X1 - X2) / (X1 - X0) + Fx0 / (X0 - X2) / (X0 - X1)
    Diff = Fx2 / (Df1 + Df2 * (X2 - X1))
    X3 = X2 - Diff
    X0 = X1
    Fx0 = Fx1
    X1 = X2
    Fx1 = Fx2
    X2 = X3
    Fx2 = Fx(sFx, X3)
    Cells(Row, 2) = X3
    Cells(Row, 3) = Fx2
    Row = Row + 1
  Loop
  
  ' Newton's method
  X1 = [A4].Value
  Fx1 = Fx(sFx, X1)
  Row = 2
  Diff = 2 * Toler
  Do Until Abs(Diff) < Toler
    h = 0.01 * (1 + Abs(X1))
    Diff = h * Fx1 / (Fx(sFx, X1 + h) - Fx1)
    X1 = X1 - Diff
    Fx1 = Fx(sFx, X1)
    Cells(Row, 4) = X1
    Cells(Row, 5) = Fx1
    Row = Row + 1
  Loop
  
End Sub

Output
======

Columns B and C show the refined guesses and their function values for the Generalized Secant Algorithm.
Columns D and E show the refined guesses and their function values for Newton's method.

Here is the version of the VBA code that uses three initial guesses and the divided differences for the first three derivatives:

Code:

Cell Mapping
===========
A1 : "X0"
A2 : value for X0
A3 : "X1"
A4 : value for X1
A5 : "X2"
A6 : value for X2
A7 : "Tolerance"
A8 : value for tolerance
A9 : "F(x)"
A10: String containing expression for f(x)=0
B1 : "X"
C1 : "F(X)"  (for Generalized Secant method)
D1 : "X"
E1 : "F(X)"  (for Newton's method, used for comparison)

VBA Listing
===========

Function Fx(ByVal sFx As String, ByVal X As Double) As Double
  sFx = Replace(sFx, "EXP", "!")
  sFx = Replace(sFx, "X", "(" & CStr(X) & ")")
  sFx = Replace(sFx, "!", "EXP")
  Fx = Evaluate(sFx)
End Function

Sub genSecant3()
  Dim sFx As String, X0 As Double, X1 As Double, X2 As Double, X3 As Double, X4 As Double
  Dim Toler As Double, Df1 As Double, Df2 As Double, Df3 As Double
  Dim Row As Integer, h As Double
  Dim Fx0 As Double, Fx1 As Double, Fx2 As Double, Fx3 As Double, Diff As Double
  
  Range("B2:X1000").Clear
  
  X0 = [A2].Value
  X1 = [A4].Value
  X2 = [A6].Value
  Toler = [A8].Value
  sFx = [A10].Value
  sFx = Replace(sFx, " ", "")
  sFx = UCase(sFx)
  
  Fx0 = Fx(sFx, X0)
  Fx1 = Fx(sFx, X1)
  Fx2 = Fx(sFx, X2)
  Df1 = Fx0 / (X0 - X1) + Fx1 / (X1 - X0)
  Df2 = Fx2 / (X2 - X1) / (X2 - X0) + Fx1 / (X1 - X2) / (X1 - X0) + Fx0 / (X0 - X2) / (X0 - X1)
  X3 = X2 - Fx2 / (Df1 + Df2 * (X2 - X1))
  Fx3 = Fx(sFx, X3)
  Diff = X3 - X2
  
  Row = 2
  Cells(Row, 2) = X3
  Cells(Row, 3) = Fx3
  Row = Row + 1
  Do Until Abs(Diff) < Toler Or Row > 100
    Df1 = Fx3 / (X3 - X2) + Fx2 / (X2 - X3)
    Df2 = Fx3 / (X3 - X1) / (X3 - X2) + Fx2 / (X2 - X1) / (X2 - X3) + Fx1 / (X1 - X2) / (X1 - X3)
    Df3 = Fx3 / (X3 - X2) / (X3 - X1) / (X3 - X0) + _
          Fx2 / (X2 - X3) / (X2 - X1) / (X2 - X0) + _
          Fx1 / (X1 - X3) / (X1 - X2) / (X1 - X0) + _
          Fx0 / (X0 - X3) / (X0 - X2) / (X0 - X1)
    Diff = Fx3 / (Df1 + Df2 * (X3 - X2) + Df3 * (X3 - X2) * (X3 - X1))
    X4 = X3 - Diff
    X0 = X1
    Fx0 = Fx1
    X1 = X2
    Fx1 = Fx2
    X2 = X3
    Fx2 = Fx3
    X3 = X4
    Fx3 = Fx(sFx, X4)
    Cells(Row, 2) = X4
    Cells(Row, 3) = Fx3
    Row = Row + 1
  Loop
  
  ' Newton's method
  X1 = [A4].Value
  Fx1 = Fx(sFx, X1)
  Row = 2
  Diff = 2 * Toler
  Do Until Abs(Diff) < Toler
    h = 0.01 * (1 + Abs(X1))
    Diff = h * Fx1 / (Fx(sFx, X1 + h) - Fx1)
    X1 = X1 - Diff
    Fx1 = Fx(sFx, X1)
    Cells(Row, 4) = X1
    Cells(Row, 5) = Fx1
    Row = Row + 1
  Loop
  
End Sub

Output
======

Columns B and C show the refined guesses and their function values for the Generalized Secant Algorithm.
Columns D and E show the refined guesses and their function values for Newton's method.

Use different worksheets for each of the above methods as the input values in column A are not the same.

I wrote the above code to make it easy to ready. A programmer can optimize the above code by using arrays, matrices, and loops.
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
Variant of the Secant Method - ttw - 12-09-2020, 04:33 AM
RE: Variant of the Secant Method - Namir - 12-10-2020, 01:54 PM
RE: Variant of the Secant Method - Namir - 12-10-2020 02:56 PM
RE: Variant of the Secant Method - Namir - 12-12-2020, 04:22 AM
RE: Variant of the Secant Method - ttw - 12-12-2020, 02:41 PM



User(s) browsing this thread: 2 Guest(s)