edirol
asked on
how to calculate Exponential function by using vba
In inputbox input x and n
exponential function : e^x=1+ x/1! + x^2/2! +.....x^n/n! ; n!=1*2*3...*n
inside the function we can use t(n)=x^n/n! and for recurrence formula t(n)=t(n-1)*x/n
The partial sum to the n-th clause is expressed with s(n) which is ; s(n)=s(n-1)+t(n)
then e=1+s(n)
the calculation will repeat until i=n and |t(n)|<0.001
the problem is when i run the program the answer is no same with the exponential function above.
Sub e2()
Dim n As Double
Dim x As Double
Dim i As Double
Dim tn As Double
Dim sn As Double
Dim t1 As Double
Dim e As Double
x = CInt(InputBox("x?"))
n = CInt(InputBox("n?"))
Do
For i = 1 To n
t1 = x / (n - 1)
tn = (x / (n - 1)) * (x / n)
sn = tn + t1
e = 1 + sn
If x = 0 Then Exit For
Next i
Loop Until tn < 0.001 Or -tn < 0.001
MsgBox "e^" & CStr(x) & "=" & CStr(e)
End Sub
exponential function : e^x=1+ x/1! + x^2/2! +.....x^n/n! ; n!=1*2*3...*n
inside the function we can use t(n)=x^n/n! and for recurrence formula t(n)=t(n-1)*x/n
The partial sum to the n-th clause is expressed with s(n) which is ; s(n)=s(n-1)+t(n)
then e=1+s(n)
the calculation will repeat until i=n and |t(n)|<0.001
the problem is when i run the program the answer is no same with the exponential function above.
Sub e2()
Dim n As Double
Dim x As Double
Dim i As Double
Dim tn As Double
Dim sn As Double
Dim t1 As Double
Dim e As Double
x = CInt(InputBox("x?"))
n = CInt(InputBox("n?"))
Do
For i = 1 To n
t1 = x / (n - 1)
tn = (x / (n - 1)) * (x / n)
sn = tn + t1
e = 1 + sn
If x = 0 Then Exit For
Next i
Loop Until tn < 0.001 Or -tn < 0.001
MsgBox "e^" & CStr(x) & "=" & CStr(e)
End Sub
ASKER
thanks WaterStreet
i`d tried CDbl but the answer is still wrong.
for example x=2,n=3 the answer should be e^2=6.3333
i think there are something wrong with the formulas for t1,tn
i`d tried CDbl but the answer is still wrong.
for example x=2,n=3 the answer should be e^2=6.3333
i think there are something wrong with the formulas for t1,tn
Sub e2()
Dim n As Double
Dim x As Double
Dim e As Double
Dim Laste As Double
x = CInt(InputBox("x?"))
e = 1
x = 3
n = 1
Do
Laste = e
e = e + x ^ n / Factorial(n)
n = n + 1
Loop While Abs(e - Laste) > 0.0000001
MsgBox "e^" & x & "=" & e
End Sub
Public Function Factorial(ByRef Value As Double) As Double
If Value = 1 Then
Factorial = 1
Exit Function
Else
Factorial = Value * Factorial(Value - 1)
End If
End Function
Kevin
Dim n As Double
Dim x As Double
Dim e As Double
Dim Laste As Double
x = CInt(InputBox("x?"))
e = 1
x = 3
n = 1
Do
Laste = e
e = e + x ^ n / Factorial(n)
n = n + 1
Loop While Abs(e - Laste) > 0.0000001
MsgBox "e^" & x & "=" & e
End Sub
Public Function Factorial(ByRef Value As Double) As Double
If Value = 1 Then
Factorial = 1
Exit Function
Else
Factorial = Value * Factorial(Value - 1)
End If
End Function
Kevin
here's a solution that avoids using the ^ operator, there's not much point in doing that, cos you could hard code e as a constant and do e^n in code.
Anyway, your keeping of a running total for the value seemed to be in error.
Dim n As Double
Dim x As Double
Dim i As Double
Dim tn As Double
Dim sn As Double
Dim t1 As Double
Dim e As Double
x = CInt(InputBox("x?"))
n = CInt(InputBox("n?"))
e = 0
tn = 1
e = e + tn
'now e is the first term in the taylor expansion (call this term 0)
Do
'add on term 1, 2, 3
i = i + 1
tn = tn * x / i 'this gets the next term from the last
e = e + tn
'If x = 0 Then Exit For - not needed, gives tn=0 when x = 0, so it ends below
'the end ing condition wasn't true
Loop Until tn < 0.001 And tn >= 0 Or -tn < 0.001 And tn <= 0
msgbox ("e^" & CStr(x) & "=" & CStr(e))
Anyway, your keeping of a running total for the value seemed to be in error.
Dim n As Double
Dim x As Double
Dim i As Double
Dim tn As Double
Dim sn As Double
Dim t1 As Double
Dim e As Double
x = CInt(InputBox("x?"))
n = CInt(InputBox("n?"))
e = 0
tn = 1
e = e + tn
'now e is the first term in the taylor expansion (call this term 0)
Do
'add on term 1, 2, 3
i = i + 1
tn = tn * x / i 'this gets the next term from the last
e = e + tn
'If x = 0 Then Exit For - not needed, gives tn=0 when x = 0, so it ends below
'the end ing condition wasn't true
Loop Until tn < 0.001 And tn >= 0 Or -tn < 0.001 And tn <= 0
msgbox ("e^" & CStr(x) & "=" & CStr(e))
ASKER
thanks Kevin.
i`d tried your solution and it is working!!!however i have to make the program by using the
functions in the question.
Actually i found that i misunderstood the question.This is the question again ;
Exponential function : e^x=1+ x/1! + x^2/2! +.....x^n/n! ; n!=1*2*3...*n
Inside the function we can use t(n)=x^n/n! and for recurrence formula t(n)=t(n-1)*x/n
The partial sum to the n-th clause is expressed with s(n) which is ; s(n)=s(n-1)+t(n)
Then e=1+s(n)
The calculation will repeat until n=100 and |t(n)|<0.001
Sub e21()
Dim x As Double
Dim n As Double
Dim i As Double
Dim t1 As Double
Dim tn As Double
Dim sn As Double
Dim e As Double
x = CDbl(InputBox("x?"))
Do
For n = 1 To 100
t1 = x / (n - 1)
tn = (x / (n - 1)) * (x / n)
sn = tn + t1
e = 1 + sn
If x = 0 Then Exit For
Next n
Loop Until tn < 0.001 Or -tn < 0.001
MsgBox "e^" & CStr(x) & "=" & CStr(e)
End Sub
I`d tried to run the program but it comes into debug.
For example if x=3
e^3=20.0855....
i`d tried your solution and it is working!!!however i have to make the program by using the
functions in the question.
Actually i found that i misunderstood the question.This is the question again ;
Exponential function : e^x=1+ x/1! + x^2/2! +.....x^n/n! ; n!=1*2*3...*n
Inside the function we can use t(n)=x^n/n! and for recurrence formula t(n)=t(n-1)*x/n
The partial sum to the n-th clause is expressed with s(n) which is ; s(n)=s(n-1)+t(n)
Then e=1+s(n)
The calculation will repeat until n=100 and |t(n)|<0.001
Sub e21()
Dim x As Double
Dim n As Double
Dim i As Double
Dim t1 As Double
Dim tn As Double
Dim sn As Double
Dim e As Double
x = CDbl(InputBox("x?"))
Do
For n = 1 To 100
t1 = x / (n - 1)
tn = (x / (n - 1)) * (x / n)
sn = tn + t1
e = 1 + sn
If x = 0 Then Exit For
Next n
Loop Until tn < 0.001 Or -tn < 0.001
MsgBox "e^" & CStr(x) & "=" & CStr(e)
End Sub
I`d tried to run the program but it comes into debug.
For example if x=3
e^3=20.0855....
for one thing, you've got looping Until tn < 0.001 Or -tn < 0.001
, but if say tn=3, then -tn < .001 and the loop ends
, but if say tn=3, then -tn < .001 and the loop ends
also if you look at
For n = 1 To 100
t1 = x / (n - 1)
then where n=1, you have an immediate division by zero in the second line
For n = 1 To 100
t1 = x / (n - 1)
then where n=1, you have an immediate division by zero in the second line
ASKER
already tried to change the functions.but still wrong
your calculation of the terms in the series is not right. The first term has to be calculated before you go into the loop, but that's always 1.
t0 = 1
t1 = t0 * x / 1
t2 = t1 * x / 2
t3 = t2 * x / 3
t(n) = t(n-1) * x / n
but you don't want to store all those values, you want to calculate the next term from the previous and throw away the old one - so lets call the nth term variable 'tn'
first consider this
-------------------------- ---------- ---------- ---------- ---------- ---
dim tn as double
x=2
tn = 1
for n = 1 to 10
tn = tn * x/n
msgbox("term " + cstr(n) + " = " + cstr(tn))
next
-------------------------- ---------- ---------- ---------- ---------- ---
so looking at the code above, I calculate each of the first 10 term in the series. But I want to add them all up, including t0, so then I need running_total
-------------------------- ---------- ---------- ---------- ---------- ---
x=2
tn = 1
running_total = tn
for n = 1 to 100
tn = tn * x/n
running_total = running_total + tn
next
-------------------------- ---------- ---------- ---------- ---------- ---
'at the end of this, the value is in running total
do you see what this bit does
tn = tn * x/n
it takes the last term and works out the latest term from it.
t0 = 1
t1 = t0 * x / 1
t2 = t1 * x / 2
t3 = t2 * x / 3
t(n) = t(n-1) * x / n
but you don't want to store all those values, you want to calculate the next term from the previous and throw away the old one - so lets call the nth term variable 'tn'
first consider this
--------------------------
dim tn as double
x=2
tn = 1
for n = 1 to 10
tn = tn * x/n
msgbox("term " + cstr(n) + " = " + cstr(tn))
next
--------------------------
so looking at the code above, I calculate each of the first 10 term in the series. But I want to add them all up, including t0, so then I need running_total
--------------------------
x=2
tn = 1
running_total = tn
for n = 1 to 100
tn = tn * x/n
running_total = running_total + tn
next
--------------------------
'at the end of this, the value is in running total
do you see what this bit does
tn = tn * x/n
it takes the last term and works out the latest term from it.
ASKER
Thanks deighton ;
I`d changed my program by referring your functions and it works.
But how can i make that program to calculate until abs(tn)<0.0001?
I did `Step Into ` and in `Locals Window` when Abs(tn)<0.0001 it should
stop running,but it still run until n=100.
Sub ee()
Dim x As Double
Dim n As Double
Dim tn As Double
Dim running_total As Double
x = CDbl(InputBox("x"))
tn = 1
running_total = tn
Do
For n = 1 To 100
tn = tn * x / n
running_total = running_total + tn
Next n
Loop Until Abs(tn) < 0.00001
MsgBox CStr(running_total)
End Sub
I`d changed my program by referring your functions and it works.
But how can i make that program to calculate until abs(tn)<0.0001?
I did `Step Into ` and in `Locals Window` when Abs(tn)<0.0001 it should
stop running,but it still run until n=100.
Sub ee()
Dim x As Double
Dim n As Double
Dim tn As Double
Dim running_total As Double
x = CDbl(InputBox("x"))
tn = 1
running_total = tn
Do
For n = 1 To 100
tn = tn * x / n
running_total = running_total + tn
Next n
Loop Until Abs(tn) < 0.00001
MsgBox CStr(running_total)
End Sub
if you look at that, you have a for loop 'nested' in the Do loop, so you will always do 100 iterations, then you will break out of the second loop only if abs(tn) < .00001,
if you get rid of the do loop and have
For n = 1 To 100
tn = tn * x / n
running_total = running_total + tn
if Abs(tn) < 0.00001 then exit for
Next n
you will iterate for a maximum of 100 times, but leaving the loop if tn < .00001
is one way of doing that
you could also use a do loop with a counter and the loop until n>100 or abs(tn)<.000001
if you get rid of the do loop and have
For n = 1 To 100
tn = tn * x / n
running_total = running_total + tn
if Abs(tn) < 0.00001 then exit for
Next n
you will iterate for a maximum of 100 times, but leaving the loop if tn < .00001
is one way of doing that
you could also use a do loop with a counter and the loop until n>100 or abs(tn)<.000001
ASKER
At last !!!Thanks deighton.
Anyway can u explain why does tn = 1& sn = tn
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
x = CInt(InputBox("x?"))
n = CInt(InputBox("n?"))
try
x = CDbl(InputBox("x?"))
n = CDbl(InputBox("n?"))