大家在做高数题的时候很多都需要用到导数
虽然求导很简单,但是很费脑细胞
所以我有了一个大胆的想法
教我的电脑学习函数求导~
话不多说,开干!!
求导计算器的整体思路:(主要是递归思想)
class Expr:
def __init__(self):
pass
def eval(self, **values):
pass
def simplify(self):
return self
def __repr__(self):
return str(self.value)
其中
def __add__(self, other):
return Add(self,to_expr(other)).simplify()
def __radd__(self,other):
return Add(to_expr(other),self).simplify()
其中 Add是定义的加法类
to_expr()方法是将当前输入的字符的类型转换成表达式的类型,代码如下:
def to_expr(value):
if isinstance(value,Expr):
return value
elif type(value) in (float, int):
return Const(value)
else:
raise Exception("Can't not convert into expr")
class Const(Expr):
def __init__(self,value):
self.value = value
def eval(self, **values):
return self.value
def __repr__(self):
return str(self.value)
def deriv(self,x):
return Const(0)
其中 deriv是求导的方法,因为常数项求导的结果为0所以返回的结果应该是0,但要注意类型
(2)变量
class Variable(Expr):
def __init__(self,name):
self.name = name
def eval(self, **values):
if self.name in values:
return values[self.name]
raise Exception(f'Variable {self.name} is not exit')
def __repr__(self):
return self.name
def deriv(self,x):
name = _get_name(x)
return Const(1 if name == self.name else 0)
变量的定义和常量的定义是比较相似的,主要不同就是求导功能的实现
如果当前的函数名称是需要求导的则返回常量1(因为x的导数为1)
如果当前的函数名称不是需要求导的则返回常量0(比如y=x+z对z求偏导,x就为0咯~)
class Add(Expr):
#----------------------------------------------------------------------
def __init__(self, left, right):
self.left = left
self.right = right
#----------------------------------------------------------------------
def eval(self,**values):
return self.left.eval(**values) + self.right.eval(**values)
#----------------------------------------------------------------------
def __repr__(self):
return f"({self.left}+{self.right})"
#----------------------------------------------------------------------
def simplify(self):
"""简化表达式"""
left, right = self.left,self.right
if isinstance(left, Const):
if left.value == 0:
return right
if isinstance(right, Const):
return Const(left.value + right.value)
elif isinstance(right, Const) and right.value == 0:
return left
return self
#----------------------------------------------------------------------
def deriv(self,x):
""""""
return self.left.deriv(x) + self.right.deriv(x)
对于相加类来说,主要关注的是求导的实现
两个函数相加的求导等于各自求导的相加
同时还有simplify的类就是将实现的表达式进行简化(不然一大串~~)
当我还定义了减、乘、除、取反、取对数、取幂、正弦、余弦、正切、余切、以及反三角函数的类
(原理类似,就不一一列举了)