0

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)
10
  • 2
    Which version of Python are you using? Commented Oct 23, 2015 at 19:02
  • 3.5 is the version I am using Commented Oct 23, 2015 at 19:04
  • Ok. I was worried you were using 2.7, in which case 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, x is itself a float so maybe it would still work in 2.7) Commented Oct 23, 2015 at 19:07
  • Presumably your method for estimating the logarithm is wrong. lnx seems to converge to a value, but it's the wrong one, and so the error estimate never reaches that minimum you've set. Commented Oct 23, 2015 at 19:08
  • 1
    Hint: write out the expression from the first iteration (with i=0) manually, substituting to find out the values of ex and the piece that you're adding to lnx. Is that the formula you meant to use? Commented Oct 23, 2015 at 19:25

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

2 Comments

That's exactly the problem; I was hinting broadly in my answer.
Wow thanks, I for some reason thought it would be better to initialize it at 0 instead of 1, but that was the issue I guess. I did have the print outside of the loop originally but nothing was printing, but I guess it was because I initialized wrong. Thanks a lot, your solution helped a lot!
1

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:

4 Comments

Ok, but I have a for loop with the same math and that works fine. I can post that code here to compare it if that would help?
Yes, that might help a lot.
Someone else ended up solving it, I initialized it wrong. Thanks though!
Oh I see Prune yeah, your comment did hint it lol I'm oblivious. I wasn't realizing that the initiation was causing so much problem.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.