N.T.C
N.T.C

Reputation: 658

Recursion in VB.NET with stop condition

I have written a function in VB.NET that uses the Bisect Method to find a root of an arbitrary function.

[Given a continuous function f(x), if f(x1) and f(x2) have different signs then it guarantees that there is at least one root between x1 and x2. The Bisect Method narrows the range [x1, x2] until it finds a root.]

I've written the function in 2 different ways: one using a while loop and the other using recursion.

In the while loop method, I could easily keep track of the number of iterations so that, for example, after 1000 loops, if no root has been found, the function stops and exits.

My question here is: How can I insert such a stop condition with the recursion method while still being able to keep tail call optimization? Thank you in advance.

Method 1: While Loop

Public Function FindOneRoot(lowerBound As Double, upperBound As Double, _
                             tolerance As Double, ByRef Root As Double, _
                             theFunction As Func(Of Double, Double)) As Boolean
  Dim flower As Double = theFunction(lowerBound)
  Dim fupper As Double = theFunction(upperBound)
  Root = (lowerBound + upperBound) / 2
  Dim froot As Double = theFunction(Root)
  Dim count As Integer = 0
  While Math.Abs(froot) > tolerance
     If froot * flower > 0 Then
        lowerBound = Root
     Else
        upperBound = Root
     End If
     Root = (lowerBound + upperBound) / 2
     froot = theFunction(Root)
     count += 1 'keep track of the loops

     If count >= 1000 Then 'stop looping after 1000 iterations
        Exit While
     End If
  End While

  If count < 1000 Then
     Return True
  Else
     Return False
  End If

End Function

Method 2: Recursion

 Public Function FindOneRoot(x1 As Double, x2 As Double, tolerance As Double, _
                                    theFunction As Func(Of Double, Double)) As Double
  Dim x As Double = (x1 + x2) / 2
  If Math.Abs(theFunction(x)) < tolerance Then
     Return x 'found a root
  ElseIf theFunction(x1) * theFunction(x) < 0 Then
     Return FindOneRoot(x1, x, tolerance, Root, theFunction)
  Else
     Return FindOneRoot(x, x2, tolerance, Root, theFunction)
  End If
End Function

Upvotes: 1

Views: 1106

Answers (1)

Sathish
Sathish

Reputation: 4487

Use Same Condition In Recursive. But declare count outside the function

Add Another Parameter as Count pass the count and check inside the function

 Public Function FindOneRoot(x1 As Double, x2 As Double, tolerance As Double, 
 ByRef Root As Double,theFunction As Func(Of Double, Double),
 Count as integer) As Boolean

    If count >= 1000 Then 'stop looping after 1000 iterations
       Return False: Exit Function
    End If

   Dim x As Double = (x1 + x2) / 2
   If Math.Abs(theFunction(x)) < tolerance Then
      Return x 'found a root
   ElseIf theFunction(x1) * theFunction(x) < 0 Then
     Return FindOneRoot(x1, x, tolerance, Root, theFunction,count +1)
  Else
  Return FindOneRoot(x, x2, tolerance, Root, theFunction,count +1)
  End If
  End Function

Upvotes: 1

Related Questions