SICP_Python版第二章:符号数据(简易求导系统)

2.54

和scheme里面不同,这里需要加上类型判断,长度的判断可以通过对最终情况的分析来避免。当然python早就内置好了==运算符号…

def equal(a,b):
    def rest(x):return x[1:] if len(x)!=0 else None
    if not (a and b):return True if a==b else False # one of a,b is None
    if isinstance(a,Iterable) and isinstance(b,Iterable):
        return equal(a[0],b[0]) and equal(rest(a),rest(b))
    elif type(a)==type(b):# a and b is both not iterable
        return a==b
    else:return False#the type of is not same

2.552.58 :构造一个简易的符号求导系统

基本思路就是利用闭合性质来不断的复合型的构造一个函数表达式,利用 +/ 等符号来递归的构造式子。接着将中缀输入表达式转化成前缀表达式再转换成一我们需要的tuple形式。求导的时候则需要针对具体的求导法则来进行组合。注意需要遵循一些基本的法则。最后再将生成的求导表达式转换成中缀表达式。当然很多显而易见的地方可以化简,但是对于符号的化简则相当困难了,这一部分超出我的能力。

def derive(exp,var):
    if is_number(exp):return 0
    elif is_var(exp):return 1 if is_same_var(exp,var) else 0
    elif is_sum(exp):return make_sum(derive(addend(exp),var),derive(augend(exp),var))
    elif is_product(exp):return make_sum(\
    make_product(multiplier(exp),derive(multiplicand(exp),var))\
    ,make_product(multiplicand(exp),derive(multiplier(exp),var)))
    elif is_division(exp):return make_divsion(make_minus\
    (make_product(derive(numer(exp),var),deno(exp)),make_product(derive(deno(exp),var),numer(exp))),\
    make_exponentiation(deno(exp),2))
    elif is_minus(exp):return  make_minus(derive(minuend(exp),var),derive(subtractend(exp),var))
    elif is_exponentiation(exp):return make_product(exponent(exp),\
    make_product(make_exponentiation(base(exp),make_minus(exponent(exp),1)),\
    derive(base(exp),var))) 
    else:
        assert(is_var(exp),'may lost some symbol as **')
def is_number(exp):
    return isinstance(exp,int) or isinstance(exp,float)
def is_var(exp):
    return isinstance(exp,str)
def is_same_var(v1,v2):
    return v1==v2
def make_sum(a1,a2):
    if   a1==0:return a2
    elif a2==0:return a1
    elif is_number(a1) and is_number(a2):return a1+a2
    return ('+',a1,a2)
def make_product(m1,m2):
    if m1==0 or m2==0:return 0
    elif m1==1:return m2
    elif m2==1:return m1
    elif is_number(m1) and is_number(m2):return m1*m2
    return ('*',m1,m2)
def is_sum(x):return isinstance(x,tuple) and x[0]=='+'
def addend(x):return x[1]
def augend(x):return x[2]
def is_product(x):return isinstance(x,tuple) and x[0]=='*'
def multiplier(p):return p[1]
def multiplicand(p):return p[2]
def make_minus(s1,s2):
    if s2==0:return s1
    return ('-',s1,s2)
def is_minus(exp):return exp[0]=='-'
def minuend(x):return x[1]
def subtractend(x):return x[2]
def is_exponentiation(exp):return exp[0]=='**'
def make_exponentiation(u,n):return ('**',u,n)
def base(x):return x[1]
def exponent(x):return x[2]
def is_division(exp):return exp[0]=='/'
def make_divsion(num,dem):
    if num==0:return dem
    if dem == 0:return 'Infinity'
    if dem==1:return num
    return ('/',num,dem)
def numer(x):return x[1]
def deno(x):return x[2]

def transfer(s):
    i,n = 0,len(s)
    s1,s2 = [],[]
    priority = {'+':1,'-':1,'*':2,'/':2,'**':3}
    s = s[::-1]
    while i < n:
        each = s[i]
        if each in ['+','-','*','/','**']:
            if len(s1)==0 or s1[-1]==')':s1.append(each)
            elif priority[each] >= priority[s1[-1]]:s1.append(each)
            else:
                s2.append(s1.pop())
                i-=1
        elif each in ['(',')']:
            if each==')':s1.append(each)
            else:
                while 1:
                    top = s1.pop()
                    if top==')':break
                    s2.append(top)
        else:s2.append(each)
        i+=1
    s2+=s1[::-1]
    return s2
def make_expression(exp):
    s = exp.pop()
    if s in ['+','-','*','/','**']:
        sub1 = make_expression(exp)
        sub2 = make_expression(exp)
        return (s,sub1,sub2)
    else:return s
def simplify(exp):
    if is_var(exp) or is_number(exp):return exp
    s1,s2 = exp[1],exp[2]
    sub1 = '{0}'.format(simplify(s1)) if (is_var(s1) or is_number(s1)) else '({0})'.format(simplify(s1))
    sub2 = '{0}'.format(simplify(s2)) if (is_var(s2) or is_number(s2)) else '({0})'.format(simplify(s2))
    return '{0}{1}{2}'.format(sub1,exp[0],sub2)

print(simplify(derive(make_expression(transfer([‘x’, , ‘y’,’+’,’(‘,1,’+’,’x’,’)’,’‘,’y’,’-‘,5,’‘,’x’,’*’,’z’,’+’,’x’,’/’,’e’])),’x’)))

xy+(x+1)y5xy+xe:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值