So this code is meant to return the final error and the final logarithm of a number inputted by a user. Now my issue is that it doesn't run the loop, it just keeps going over the same number and it never ends. I am not sure if I have my print statements in the wrong area, or if I am doing the loop wrong but I want the loop to end when the error is less then 1x10^-9. It's possible my iterations are set up wrong too, not really sure what I messed up on here.
import math
import sys
#Computing natural log of x
#x value is input here
x = float(input("Please input a positive number: "))
#If x is not positive then program will not work, so it will exit
if x<=0:
print("Your number is not positive. System Shutdown.")
sys.exit()
#Retrieving ln(x) using the math command
lnx0 = math.log(x)
#Formula for approximate ln
xfrac = (x - 1)/(x + 1)
lnx = 0 #Initializing the approximating
i=0
#This is the code to make it go until it hits the error we want
while True:
ex = 2*i - 1
lnx += 2.0* (xfrac**ex / ex)
#Counter adding 1 to it
i+=1
#This is the error
err = math.fabs(lnx0 - lnx)
if err<0.0000000001:
break
#Priting approximate ln at end of loop
print ("ln(x) at " ,x,"is: " ,lnx)
#Final Error
print ("Final error is:" ,err)
#Number of itterations
#Printing accurate version of ln(x) just to see what it should be
print ("Your accurate value of ln(x) is: " ,lnx0)
2 Answers 2
I'm assuming you're using the fourth formula on this page to approximate the log function. If so, your i is starting at the wrong value; you've initialized it to 0 here, but it needs to start at 1.
Also, if you only want output after the answer has been found, rather than once per iteration, your print functions should be de-indented so they are outside the loop. Try:
import math
import sys
#Computing natural log of x
#x value is input here
x = float(input("Please input a positive number: "))
#If x is not positive then program will not work, so it will exit
if x<=0:
print("Your number is not positive. System Shutdown.")
sys.exit()
#Retrieving ln(x) using the math command
lnx0 = math.log(x)
#Formula for approximate ln
xfrac = (x - 1)/(x + 1)
lnx = 0 #Initializing the approximating
i=1
#This is the code to make it go until it hits the error we want
while True:
ex = 2*i - 1
lnx += 2.0* (xfrac**ex / ex)
#Counter adding 1 to it
i+=1
#This is the error
err = math.fabs(lnx0 - lnx)
if err<0.0000000001:
break
#Priting approximate ln at end of loop
print ("ln(x) at " ,x,"is: " ,lnx)
#Final Error
print ("Final error is:" ,err)
#Number of itterations
#Printing accurate version of ln(x) just to see what it should be
print ("Your accurate value of ln(x) is: " ,lnx0)
Result:
Please input a positive number: 5
ln(x) at 5.0 is: 1.6094379123624052
Final error is: 7.169509430582366e-11
Your accurate value of ln(x) is: 1.6094379124341003
Thanks to DSM for identifying the formula and possible fix
2 Comments
There are several problems with this. The first is that your computations are incorrect. I tried entering 'e' to 9 places. Your estimate, lnx, quickly degenerates to -3.3279+ and sticks there. This dooms you to an infinite loop, because the estimate will never get near the true value.
Others have already pointed out that you haven't traced your computations with print statements. I'll add another hint from my days in numerical analysis: use a restricted "for" loop until you've debugged the computations. Then trade it in for a "while err> tolerance" loop.
To address your most recent comment, you're not getting the same numbers. The first few terms are significant, but the infinite sequence quickly drops close to 0, so the additions don't show up after about 15-20 iterations.
Also print out ex and lnx values within the loop. Especially check the first one, where your exponent is -1; I believe that you've started the loop in the wrong place.
Finally, you might find this loop form a little easier to read. Get rid of your if...break statement and use this instead:
i = 1
err = 1
tolerance = 1e-10
# This is the code to make it go until it hits the error we want
while err >= tolerance:
xfrac = (x - 1)/(x + 1)would cause xfrac to be equal to zero, since truncated integer division is the default behavior. But it should work OK in 3.x. (although on second look,xis itself a float so maybe it would still work in 2.7)lnxseems to converge to a value, but it's the wrong one, and so the error estimate never reaches that minimum you've set.exand the piece that you're adding tolnx. Is that the formula you meant to use?