Forum Statistics
- Forum Members:
- Total Threads:
- Total Posts: 7
There are 1 users currently browsing forums.
|
 |

03-24-2008, 10:45 PM
|
|
Valued Forum Contributor
|
|
Join Date: 03 Mar 2005
Posts: 303
|
|
|
LOOPING: Faster rate of convergence required
Please Register to Remove these Ads
I am developing a UDF which requires some looping to arrive at the result. To keep it simple, part of the routine is akin to solving the following Amount equation for i.
Find i such that A=1.72846 given A=(1+i)^10
The following code resolves to the correct answer of i = 5.6248%
Code:
Sub nn()
Time1 = Timer
i = 0.01
k = 1
Do
A = (1 + i) ^ 10
i = i + 0.0000001
k = k + 1
'Debug.Print k & "........" & i
Loop Until Application.Round(A, 4) = 1.7285
MsgBox i & " ... " & Timer - Time1
End Sub
But it does so using 462,477 iterations and taking a whooping 90 seconds! (One would expect under 100 iterations to be ideal).
While Solver can easily tackle this problem, the Solver tool cannot be deployed in my exercise. Solver requires a WorkSheet interface and is hence inappropriate for incorporation in the UDF.
Can someone kindly come up with a non-linear algorithm that will speed up the rate of convergence? I would be happy with a solution that takes under 5 seconds.
Last edited by davidm; 03-24-2008 at 10:47 PM.
|

03-25-2008, 12:05 AM
|
|
Registered User
|
|
Join Date: 17 Nov 2005
Location: Georgia
Posts: 64
|
|
|
18 Loops
Timer does not register ---- 18 loops to solve. Set a Min and Max i for limits and let it go...
18 Loops was based on Starting i with a min value of 0% and a Max value of 100%
Code:
Sub nn()
Dim i As Double
Dim A As Double
Dim B As Double
Dim Min_i As Double
Dim Max_i As Double
Dim Step As Double
Dim Iterations As Long
Iterations = 0
Min_i = 0
Max_i = 1
Step = Max_i - Min_i
i = Min_i
Do
A = (1 + i) ^ 10
B = Application.Round(A, 4)
If B < 1.7285 Then
i = i + Step
Step = Step / 2
ElseIf B > 1.7285 Then
i = i - Step
Step = Step / 2
Else
MsgBox i & " ... " & Iterations
Exit Sub
End If
Iterations = Iterations + 1
Loop Until B = 1.7285
MsgBox i & " ... " & Iterations
End Sub
|

03-25-2008, 12:21 AM
|
|
Forum Moderator
|
|
Join Date: 30 Mar 2007
Location: Davis CA
MS Office Version:Excel 2004
Posts: 2,323
|
|
If A = (i +1)^10
then LN(A)=10*LN(i+1)
i+1 = e ^ (LN(A)/10)
i = (e ^ (LN(A)/10)) -1
Code:
Dim a as Double
Dim i as Double
a = 1.72846
i = Exp(Log(a) / 10) - 1
returns 0.0562480820384001 with no loops.
The spreadsheet function =EXP(LN(A1)/10)-1 gives the same result.
Last edited by mikerickson; 03-25-2008 at 12:27 AM.
|

03-25-2008, 12:50 AM
|
|
Registered User
|
|
Join Date: 17 Nov 2005
Location: Georgia
Posts: 64
|
|
|
Much Better
I was not even thinking about logs....
-Lee
|

03-25-2008, 01:04 AM
|
|
Forum Moderator
|
|
Join Date: 30 Mar 2007
Location: Davis CA
MS Office Version:Excel 2004
Posts: 2,323
|
|
Your binary search is nice.
I adapted it to find roots of any function. It needs some more error checking (are the intial boundries appropriate?, etc.).
The Sub test solves both the problem in the OP and finds the cube root of 3.
Code:
Sub test()
MsgBox binarySolver("Ftn", 1.72846, 0, 3, 10 ^ -4) & " is the solution to the OPs problem."
MsgBox binarySolver("Cube", 3, 0, 5, 10 ^ -7) & " is the cube root of 3."
End Sub
Function binarySolver(thisFunction As String, Goal As Double, Low As Double, High As Double, Accuracy As Double) As Double
Rem to solve thisFunction(x) = Goal within accuracy
Rem Low and High are estimates that bracket the solution
Dim Mid As Double
Dim FtnLow As Double, FtnMid As Double, FtnHigh As Double
Dim loopCount As Long
FtnLow = Run(thisFunction, Low)
FtnHigh = Run(thisFunction, High)
loopCount = 0
Do
loopCount = loopCount + 1
Mid = (Low + High) / 2
FtnMid = Run(thisFunction, Mid)
If Sgn(FtnLow - Goal) = Sgn(FtnMid - Goal) Then
Low = Mid: FtnLow = FtnMid
Else
High = Mid: FtnHigh = FtnMid
End If
Loop Until Abs(Goal - FtnMid) < Accuracy
binarySolver = Mid
'MsgBox loopCount
End Function
Function Ftn(a As Double) As Double
Ftn = (1 + a) ^ 10
End Function
Function Cube(a As Double) As Double
Cube = a ^ 3
End Function
Last edited by mikerickson; 03-25-2008 at 01:10 AM.
|

03-25-2008, 09:21 AM
|
|
Registered User
|
|
Join Date: 17 Nov 2005
Location: Georgia
Posts: 64
|
|
|
Thanks
Thanks for the compliment
I think I will archive your adaptation for future use
- Lee
|

03-26-2008, 12:37 AM
|
|
Valued Forum Contributor
|
|
Join Date: 03 Mar 2005
Posts: 303
|
|
|
Thanks Tek and Mik.
The binary search technique does the trick. My example appeared to be too simplistic to allow for making the RequiredToFind the subject of the equation. In my original, transformation, log or otherwise, is not possible as in "Find x if y = .10 in
y = x - x*(2/(1+x)^15 ).
Once again, thanks.
|
 |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|