Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
approximation
#1
I am writing a function that approximates the natural logarithm function by using the following formula
under iteration:
a sub 0= (1+x)/2 b sub 0= sqrt(x)
a sub (i+1)= (a sub i + b sub i)/2
b sub (i+1) = sqrt(a sub (i+1) + b sub i)

and the approximation to ln(x) is equal to ((x-1)/a sub i)

this is the code I came up with but I am not sure I am getting the right results,
since when I increase n, the approximation does not get closer to ln(x) (shouldn't it? I'm not sure, if you know,
please share), and the graphs I am getting are empty.

def applog(n,x):
    a0=(1+x)/2
    b0=sqrt(x)
    for i in range(n):
        a0=(a0+b0)/2
        b0=sqrt((a0+b0/2)*b0)
    return (x-1)/a0
 

print("the log approximation is: " , ((applog(1,4)))) 
print("log value-------------------:" , (math.log(4)) )
                       #of n and get strange result
error=(abs( applog(4,4)- (math.log(4))   ))                    
print("the error is : ", error)   
    
        

plt.plot((applog(1,4)) )
plt.plot((math.log(4)))
plt.show()          #should plot both funtctions in the same graph
plt.plot(error )
plt.show()         # should plot the difference of both functions
Reply
#2
As far as I understood, sub stands for sub-index; If so, sqrt((a0+b0/2)*b0) doesn't equal to sqrt(a sub (i+1) + b sub i) in the formula. So, you have coded another formula than that written above.

from math import sqrt, log
 
def applog(n,x):
    a0=(1+x)/2
    b0=sqrt(x)
    for i in range(n):
        a0=(a0+b0)/2
        b0 = sqrt(a0 + b0)  # This line was changed... 
    return (x-1)/a0
  
for j in range(2, 45):
    error=(abs( applog(j,4)- (log(4))))
    print(f"{j}:{error}")
Output:
2:0.0053156365995163934 3:0.039090279331435385 4:0.061621145018602386 5:0.07728516949056563 6:0.08826319537752325 7:0.09595463102864743 8:0.10133370381925122 9:0.10508932614514 10:0.10770813826749515 11:0.10953258138230271 12:0.11080279652612712 13:0.11168674981804516 14:0.1123017079623232 15:0.11272943559557191 16:0.11302689201201455 17:0.11323373160573724 18:0.11337754927182253 19:0.11347754206638672 20:0.11354706207495191 21:0.11359539468519486 ....
So, iterative process doesn't converge to the expected solution... The iterative formula seems to be wrong...
Reply
#3
Thanks,
I understand what you are saying,
I came up with a correction to my code, however
my graphs are still empty.
I'd like to know why so and what I should do in order
to solve this issue.

def applog(n,x):
    a0=(1+x)/2
    b0=sqrt(x)
    for i in range(n):
        a0=(a0+b0)/2
        b0=sqrt((a0)*b0)
    return (x-1)/a0
 



print("the log approximation is: " , ((applog(100,4)))) 
print("log value-------------------:" , (np.log(4)) )
                  
error=(abs( applog(100,4)- (np.log(4))   ) )                    
print("the error is : ", error)   
    
 
plt.show()
plt.plot((applog(100,4)) )
plt.plot(np.log(4))
plt.show()          #should plot both funtctions in the same graph
plt.plot(error )
plt.show()         # should plot the difference of both functions
Reply
#4
Ok, now iterative process is converged! Take a look at the following piece of code:
from math import sqrt, log
import numpy as np
import matplotlib.pyplot as plt


@np.vectorize
def applog(n, x):
    a = (1 + x) / 2
    b = sqrt(x)
    for i in range(n):
        a = (a + b) / 2
        b = sqrt(a * b)
    return (x - 1) / a

allowed_n = 2, 3, 4, 5, 6
colors = 'crgby'

fig = plt.figure()
ax = fig.add_subplot(111)
x = np.linspace(10, 500, 100)
for n, c in zip(allowed_n, colors):
    ax.plot(x, applog(n, x), color=c, label=n)
plt.legend(title='N')
plt.show()
Reply
#5
Thanks for your help.
After looking at your code, I tried to come up with the same result
even though I mainly used code I am already familiar with.
I am trying to plot in the same graph, the function for different values
of the range, that's why I turned it into a list, however, I am still getting
only one value.
Can you please tell me how my code should be corrected?

def applog(a,x):
    a0=(1+x)/2
    b0=sqrt(x)
    a=[]
   
    for i in range(n):
        a0=(a0+b0)/2
        b0=sqrt((a0)*b0)
        a.append(n)
        
    return np.array((x-1)/a0)
  
 
 
 
print("the log approximation is: " , ((applog(4,4)))) 
print("log value-------------------:" , (np.log(4)) )
                   
error=(abs( applog(4,4)- (np.log(4))   ) )                    
print("the error is : ", error)   
     
  
x = np.linspace(10, 500, 100)
plt.plot(x, (applog(4,x)),color='blue', label='approx ln(x)' ) 
plt.plot(x, np.log(x), color='red', label='ln(x)') 
plt.legend(loc='upper left')
plt.show()          
plt.plot(x,abs(np.log(x)-applog(4,x)) )
plt.show()         
Reply
#6
You have two issues with your code:
1) def applog(a,x): should be def applog(n,x):

2)You need to add the following lines to your code:
y = [applog(4, _) for _ in x]
plt.plot(x, y,color='blue', label='approx ln(x)' ) 
In my code, I used np.vectorize decorator to be able to pass vectors to the applog function.
E.g. after applying np.vectorize we are able to pass vectors to applog: e.g. applog(4, [1,2,3,4,5]) is allowed now.
So, if don't want to use np.vectorize you need to precompute y-values corresponding
to x-values. This is why I add a line y = .....
Reply
#7
thank you, I solved it.
Now there is a continuation which makes me feel a bit lost.
the new a sub n is called d sub (0,n) and
d sub (k,n)=( d sub(k-1, n) -2^(-2k) d sub(k-1, n-1) )/(1-2^(-2k))
where n=0,1,2.... and k=1,2,3...n
The function should return (x-1)/d sub(n,n). I really have no idea how to even start this.
I hope to get some help as this is very confusing.
Reply
#8
This problem seems to me unclear and confuses me too. I would like to see its solution...
Reply
#9
The solution is similar to the previous task, it just reaches convergence faster.
I am here including a link where this formula is written (2.4).
Let me know if this is enough or you need more info.

https://www.ams.org/journals/mcom/1972-2...7438-2.pdf
Reply
#10
anyone?
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020