函数在某点处连续是在该点可导的一个必要非充分条件,即函数在该点有定义,以及该点的左侧极限和右侧极限存在且等于该点处的函数值。考虑函数f(x)在x=a点的情形,数学表达式为。
你的挑战是编写一个程序实现以下两点:接受一个单变量函数和变量的一个值作为输入参数:验证所输入的函数是否在输入点处连续。
下面演示了一个输出案例:
Enter a function in one variable: 1/x
Enter the variable: x
Enter the point to check the continuity at: 1
1/x is continue at 1.0
函数1/x在0点处不连续,下面来验证一下:
Enter a function in one variable: 1/x
Enter the variable: x
Enter the point to check the continuity at: 0
1/x is not continue at 0.0
代码实现:
from sympy.core import SympifyError
from sympy import Symbol, sympify, Limit
def check_continue(f, var, point):
var = Symbol(var)
left = Limit(f, var, point, '-').doit().evalf()
right = Limit(f, var, point, ' ').doit().evalf()
value = f.subs({var:point}).evalf()
if left == right and left == value:
print('{0} is continue at {1}'.format(f, point))
else:
print('{0} is not continue at {1}'.format(f, point))
if __name__ == '__main__':
f = input('Enter a function in one variable: ')
var = input('Enter the variable: ')
point = float(input('Enter the point to check the continuity at: '))
try:
f = sympify(f)
except SympifyError:
print('Invalid input entered')
else:
check_continue(f, var, point)
二、梯度下降实现
梯度下降法用来计算函数的最小值。类似于梯度上升法,梯度下降法也是一种迭代方法:首先从变量的一个初始值开始,逐渐接近函数最小值对应的变量值。公式为,其中λ是步长,是函数的导数。因此,梯度下降法与梯度上升法唯一的区别就是如何从到。
你的挑战就是使用梯度下降法实现一个通用程序,以找到用户输入的单变量函数的最小值。程序应该还创建一副函数图像,在找到最小值之前还需要显示找到的所有中间值。
代码实现:
'''
Use gradient ascent to find the maximum value of a
single_variable function. This also checks for the existence
of a solution for the equation f'(x) = 0
'''
import math
from sympy import Derivative, Symbol, solve, exp
from sympy import sympify
from sympy.core import SympifyError
import matplotlib.pyplot as plt
def grad_descend(x0, f1x, x):
# Check if f1x=0 has a solution
if not solve(f1x):
print('Cannot continue, solution for {0} = 0 does not exist'.format(f1x))
return
epsilon = 1e-6
step_size = 1e-4
x_new_l = []
x_old = x0
x_new = x_old - step_size*f1x.subs({x:x_old}).evalf()
while abs(x_old - x_new) > epsilon:
x_new_l.append(x_new)
x_old = x_new
x_new = x_old - step_size * f1x.subs({x: x_old}).evalf()
return x_new, x_new_l
def frange(start, end, interval):
x_range = []
while start < end:
x_range.append(start)
start = interval
return x_range
def create_draw(x_new_l, f, var):
x_range = frange(-1, 1, 0.01)
y_range = [f.subs({var:x}) for x in x_range]
plt.plot(x_range, y_range, 'bo')
y_new_l = [f.subs({var:x}) for x in x_new_l]
plt.plot(x_new_l, y_new_l, 'r')
plt.legend(['function', 'Intermediate points'], loc='best')
plt.show()
if __name__ == '__main__':
f = input('Enter a function in one variable: ')
var = input('Enter the variable to differnetiate with respect to: ')
var0 = float(input('Enter the initial value of the variable: '))
try:
f = sympify(f)
except SympifyError:
print('Invalid function entered')
else:
var = Symbol(var)
d = Derivative(f, var).doit()
var_min, x_new_l = grad_descend(var0, d, var)
if var_min:
print('{0}: {1}'.format(var.name, var_min))
print('Maximum value : {0}'.format(f.subs({var:var_min})))
create_draw(x_new_l, f, var)
三、两条曲线围成的面积
我们知道积分式八十函数f(x)在两点x=a和x=b之间与x轴围成的面积。因此两条曲线围成的面积可以表达成,其中a和b是两条曲线的交点且a<b。函数f(x)称为上函数,g(x)称为下函数。下图就展示了,且a=0,b=1的情形。
你的挑战是编写一个程序,让用户输入关于x的任意两个单变量函数,然后输出这两个函数所围成的面积。程序应该清楚地表明,输入的第一个函数是上函数,也应该提示用户输入要计算面积的图形的两个端点值:
运行示例:
Enter the upper function in one variable: x
Enter the lower upper function in one variable: x**2
Enter the variable: x
Enter the lower bound of the enclosed region: 0
Enter the upper bound of the enclosed region: 1
Area enclosed by x and x**2 is: 0.166666666666667
代码实现:
from sympy import Integral, Symbol, SympifyError, sympify
def find_area(f1x, f2x, var, a, b):
a = Integral(f1x - f2x, (var, a, b)).doit()
return a
if __name__ == '__main__':
f1x = input('Enter the upper function in one variable: ')
f2x = input('Enter the lower upper function in one variable: ')
var = input('Enter the variable: ')
l = float(input('Enter the lower bound of the enclosed region: '))
u = float(input('Enter the upper bound of the enclosed region: '))
try:
f1x = sympify(f1x)
f2x = sympify(f2x)
except SympifyError:
print('One of the functions entered is invalid')
else:
var = Symbol(var)
print('Area enclosed by {0} and {1} is: {2} '.format(f1x, f2x, find_area(f1x, f2x, var, l, u)))
四、计算曲线的长度
假设我们刚沿路完成了一段骑行,路线看起来大致如下图所示。因为你没有里程表,你想知道是否有一个数学的方法可以计算出这段骑行距离。首先,我们需要一个方程来近似的描述这段路程。
注意到看上去函数曲线非常像我们在前面章节讨论的二次函数。事实上对于这个问题,我们家假设方程是,并假设你从点A(-5,36)开始骑行到B(10,231)结束。为计算这段弧的长度(即骑行距离),我们需要计算如下积分:
其中,。你的挑战是编写一个程序计算弧AB的长度。
骑行大致路径
运行实例:
The distance from (-5, 36) to (10, 231) is 268.37 (m)
代码实现:
from sympy import Symbol, sympify, Derivative, Integral, sqrt
def calculate_distance(df, var, a, b):
expression = sqrt(1 df**2)
dis = Integral(expression, (var, a, b)).doit().evalf()
return dis
if __name__ == '__main__':
f = '2*x**2 3*x 1'
var = Symbol('x')
f = sympify(f)
df = Derivative(f, var).doit()
a = -5
b = 10
s = calculate_distance(df, var, a, b)
print('The distance from (-5, 36) to (10, 231) is {0:.2f} (m)'.format(s))
,