SICP-Python版本(1.7)

来源:互联网 发布:网络用语及其意思 编辑:程序博客网 时间:2024/06/07 22:44

因为无意中看见有人推荐的伯克利的这本教材,使用python教SICP,感觉使用起来更得心应手,毕竟scheme的括号太多用起来不习惯…虽然python不能支持所有的FP特性,但是作为一个初学者,让自己学起来有兴趣才是最重要的,以后全部都用Python来做啦!

(1)首先用python实现一个抽象的Product,并用来定义一个计算
PI4=23434565....
这个PI的逼近式。代码如下:

主要就是注意要把(k+1/K)这个式子凑出来!

def product(n,term,next,initial):    total,k = initial,0    while k<=n:        total,k = total*term(k),next(k)    return totaldef pi_next(k):    return k+2def pi_term(k):    return ((k+4)/(k+3))**2def pi_product(n=10**6):    return product(n,pi_term,pi_next,8/(n+4))print(pi_product())

(2)使f(x)=0.

首先只考虑两种形式的f(x):

通过这一层的抽象确定了f(x)的基本形式

def square_root(root):    return find_root(lambda x:x*x-root)def logarithm(a,base = 2):    return find_root(lambda x:base**x - a)

接着定义find_root:

这一层的函数则是利用迭代改进过程来定义的

def find_root(f,initial_guess = 10):    def test(x):        return approx_eq(f(x),0)    return iter_improve(newton_update(f), test, initial_guess)

再看迭代改进函数:

这其实是最抽象的一层了,在不满足条件的情况下不断的进行改善

def iter_improve(update, test, guess=1):    while not test(guess):        guess = update(guess)    return guess

最后注意更新函数的定义:

这里的公式可以自行推导

def newton_update(f):    def update(x):        return x - f(x)/approx_derivative(f,x)    return update
ef approx_derivative(f,x,delta = 1e-5):    df = f(x+delta) - f(x)    return df/deltadef approx_eq(a,b):    if not a or b:return True    return abs(a-b)<1e-5 and ( abs((a-b)/b) <1e-5 if b else abs((a-b)/a -1)<1e-5)

:

f=N1D1+N2D2+N3.......(1)

(a):迭代计算:

def cont_frac(term_n,term_d,k):#compute the infinite fraction    i,total = k,0    while i!=0:        total,i = term_n(i)/(total+term_d(i)),i-1    return totalprint(cont_frac(lambda i:1.0,lambda i:1.0,100))

(b):递归计算

def rec_confrac(term_n,term_d,k):    def contfrac(i):        if i==k:return 0        return term_n(i)/(term_d(i)+contfrac(i+1))    return contfrac(0)

(c):利用这个过程计算关于e的连分式:

Di=1,2,1,1,4,1,1,6,1,1,8,....;Ni=1

def compute_e(k):    def term_d(i):        if (i-2)%3:return 1        else:return 2*((i-2)//3+1)    return 2+cont_frac(lambda i:1,term_d,k)print(compute_e(100))

:

def cubic(a,b,c):    return find_root(lambda x:x**3+a*x**2+b*x+c)print(cubic(0,-300,0))

:double,:

def repeat(f,n):    def wrap(x):        i = 1        while i<=n:            i,x = i+1,f(x)        return x    return wrapdef double(f):    return repeat(f,n=2)t = double(lambda x:x*5)

double(double(double))(lambdax:x+1)(5)得到的结果是21。它的规律是每次都是上一次调用次数的平方。

f,repeatn .:
s(x)=average(f(xdx),f(x),f(x+dx))....

def abstract_smooth(f,average):    def wrapper(x):        dx = 1e-5        return average(f,x,dx)    return wrapperdef average3(f,x,dx):    return (f(x)+f(x-dx)+f(x+dx))/3def smooth(f):    return abstract_smooth(f,average3)def mul_smooth(f,n=3):    return repeat(smooth,n)(f)t = mul_smooth(lambda x:x**6 if x>=10 else 100)
0 0