|
|
|
|
@ -2,91 +2,113 @@ from sympy import *
|
|
|
|
|
from convert_formula import *
|
|
|
|
|
import numpy as np
|
|
|
|
|
from sympy.utilities.lambdify import lambdify
|
|
|
|
|
from scipy.optimize import brentq, differential_evolution
|
|
|
|
|
|
|
|
|
|
def extreme_value(function):
|
|
|
|
|
################################################################################################################
|
|
|
|
|
##################################################### 修改 #####################################################
|
|
|
|
|
def get_domain(func_expr, var):
|
|
|
|
|
"""
|
|
|
|
|
计算函数的极值点和极值
|
|
|
|
|
:param function: 函数表达式
|
|
|
|
|
:return: 极值点与极值
|
|
|
|
|
确定函数的定义域(针对常见问题如 ln(x), 1/x 等)
|
|
|
|
|
:param func_expr: sympy 函数表达式
|
|
|
|
|
:param var: 自变量
|
|
|
|
|
:return: 有效定义域 (x_min, x_max)
|
|
|
|
|
"""
|
|
|
|
|
function = convert_formula(function)
|
|
|
|
|
independent_variable, function = split_function(function)
|
|
|
|
|
independent_variable = symbols(independent_variable)
|
|
|
|
|
function = sympify(function)
|
|
|
|
|
try:
|
|
|
|
|
extreme_points = solve(diff(function, independent_variable), independent_variable)
|
|
|
|
|
except NotImplementedError: # 捕获sympy无法解超越方程的错误
|
|
|
|
|
# 定义牛顿迭代法函数(新增容差参数说明)
|
|
|
|
|
def newton_iteration(func, func_derivative, x0, tol=1e-8, max_iter=100):
|
|
|
|
|
x = x0
|
|
|
|
|
for _ in range(max_iter):
|
|
|
|
|
fx = func(x)
|
|
|
|
|
if abs(fx) < tol: # 达到精度要求时返回
|
|
|
|
|
return x
|
|
|
|
|
f_prime_x = func_derivative(x)
|
|
|
|
|
if f_prime_x == 0: # 避免除零错误
|
|
|
|
|
break
|
|
|
|
|
x = x - fx / f_prime_x
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
# 将符号函数转换为可调用的数值函数
|
|
|
|
|
derivative_expr = diff(function, independent_variable)
|
|
|
|
|
func_num = lambdify(independent_variable, derivative_expr)
|
|
|
|
|
func_derivative_num = lambdify(independent_variable, diff(derivative_expr, independent_variable))
|
|
|
|
|
|
|
|
|
|
# 改进:通过区间扫描生成初始猜测(覆盖函数定义域)
|
|
|
|
|
x_min, x_max = -10, 10 # 可根据实际函数调整扫描区间
|
|
|
|
|
step = 0.5 # 扫描步长(更小步长可检测更多极值点)
|
|
|
|
|
x_scan = np.arange(x_min, x_max + step, step)
|
|
|
|
|
f_scan = [func_num(xi) for xi in x_scan]
|
|
|
|
|
|
|
|
|
|
# 检测导数符号变化区间(中间值定理)
|
|
|
|
|
candidate_intervals = []
|
|
|
|
|
for i in range(len(f_scan)-1):
|
|
|
|
|
if f_scan[i] * f_scan[i+1] <= 0: # 符号变化或零点
|
|
|
|
|
candidate_intervals.append((x_scan[i], x_scan[i+1]))
|
|
|
|
|
|
|
|
|
|
# 改进:在每个候选区间中点启动牛顿法
|
|
|
|
|
extreme_points = []
|
|
|
|
|
for a, b in candidate_intervals:
|
|
|
|
|
x0 = (a + b) / 2 # 区间中点作为初始值
|
|
|
|
|
root = newton_iteration(func_num, func_derivative_num, x0)
|
|
|
|
|
if root is not None:
|
|
|
|
|
# 去重:保留6位小数避免重复
|
|
|
|
|
root_rounded = round(root, 6)
|
|
|
|
|
if root_rounded not in [round(r, 6) for r in extreme_points]:
|
|
|
|
|
extreme_points.append(root)
|
|
|
|
|
extreme_values = [function.subs(independent_variable, point) for point in extreme_points]
|
|
|
|
|
extreme_dict = {point: value for point, value in zip(extreme_points, extreme_values)}
|
|
|
|
|
return extreme_dict
|
|
|
|
|
if any(f in str(func_expr) for f in ['ln', 'log', '/']):
|
|
|
|
|
x_min = 1e-6 # 避免 x=0
|
|
|
|
|
else:
|
|
|
|
|
x_min = -10
|
|
|
|
|
x_max = 10
|
|
|
|
|
try:
|
|
|
|
|
func_expr.subs(var, x_min)
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
x_min = 1e-6
|
|
|
|
|
try:
|
|
|
|
|
func_expr.subs(var, x_max)
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
x_max = 10
|
|
|
|
|
return x_min, x_max
|
|
|
|
|
except Exception:
|
|
|
|
|
return 1e-6, 10
|
|
|
|
|
|
|
|
|
|
def max_min(function):
|
|
|
|
|
def extreme_value(function):
|
|
|
|
|
"""
|
|
|
|
|
计算函数的最大值和最小值
|
|
|
|
|
计算函数的极值点和极值
|
|
|
|
|
:param function: 函数表达式
|
|
|
|
|
:return: 最大值和最小值
|
|
|
|
|
"""
|
|
|
|
|
extreme_dict = extreme_value(function)
|
|
|
|
|
max_value = max(extreme_dict.values())
|
|
|
|
|
min_value = min(extreme_dict.values())
|
|
|
|
|
return max_value, min_value
|
|
|
|
|
|
|
|
|
|
def taylor_series(function, n, x0=0):
|
|
|
|
|
"""
|
|
|
|
|
计算泰勒展开式
|
|
|
|
|
:param function: 函数表达式
|
|
|
|
|
:param x0: 展开点
|
|
|
|
|
:param n: 展开阶数
|
|
|
|
|
:return: 泰勒展开式
|
|
|
|
|
:return: 极值点与极值(字典形式)
|
|
|
|
|
"""
|
|
|
|
|
function = convert_formula(function)
|
|
|
|
|
independent_variable, function = split_function(function)
|
|
|
|
|
independent_variable = symbols(independent_variable)
|
|
|
|
|
function = sympify(function)
|
|
|
|
|
taylor_series = function.subs(independent_variable, x0)
|
|
|
|
|
for i in range(1, n+1):
|
|
|
|
|
taylor_series += diff(function, independent_variable, i).subs(independent_variable, x0) * (independent_variable - x0)**i / factorial(i)
|
|
|
|
|
return taylor_series
|
|
|
|
|
var = symbols(independent_variable)
|
|
|
|
|
func_expr = sympify(function)
|
|
|
|
|
derivative = diff(func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 获取定义域
|
|
|
|
|
x_min, x_max = get_domain(func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 转换为数值函数
|
|
|
|
|
try:
|
|
|
|
|
deriv_num = lambdify(var, derivative, 'numpy')
|
|
|
|
|
func_num = lambdify(var, func_expr, 'numpy')
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"导数或函数转换失败:{e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
# 区间扫描
|
|
|
|
|
step = 0.1 # 减小步长以提高精度
|
|
|
|
|
x_vals = np.arange(x_min, x_max + step, step)
|
|
|
|
|
f_scan = []
|
|
|
|
|
for xi in x_vals:
|
|
|
|
|
try:
|
|
|
|
|
f_scan.append(deriv_num(xi))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
f_scan.append(np.nan)
|
|
|
|
|
|
|
|
|
|
# 检测导数符号变化区间
|
|
|
|
|
candidate_intervals = []
|
|
|
|
|
for i in range(len(f_scan)-1):
|
|
|
|
|
if np.isnan(f_scan[i]) or np.isnan(f_scan[i+1]):
|
|
|
|
|
continue
|
|
|
|
|
if f_scan[i] * f_scan[i+1] <= 0:
|
|
|
|
|
candidate_intervals.append((x_vals[i], x_vals[i+1]))
|
|
|
|
|
|
|
|
|
|
# 使用布伦特法寻找零点
|
|
|
|
|
extreme_points = []
|
|
|
|
|
for a, b in candidate_intervals:
|
|
|
|
|
try:
|
|
|
|
|
root = brentq(deriv_num, a, b, xtol=1e-8)
|
|
|
|
|
root_rounded = round(float(root), 6)
|
|
|
|
|
if root_rounded not in [round(r, 6) for r in extreme_points]:
|
|
|
|
|
extreme_points.append(root_rounded)
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 全局搜索补充可能的漏掉零点
|
|
|
|
|
def objective(x):
|
|
|
|
|
try:
|
|
|
|
|
return abs(deriv_num(x[0]))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
return np.inf
|
|
|
|
|
try:
|
|
|
|
|
result = differential_evolution(objective, bounds=[(x_min, x_max)], tol=1e-6)
|
|
|
|
|
if result.success and result.fun < 1e-6:
|
|
|
|
|
root_rounded = round(float(result.x[0]), 6)
|
|
|
|
|
if root_rounded not in [round(r, 6) for r in extreme_points]:
|
|
|
|
|
extreme_points.append(root_rounded)
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 计算极值
|
|
|
|
|
extreme_values = []
|
|
|
|
|
for point in extreme_points:
|
|
|
|
|
try:
|
|
|
|
|
value = func_num(point)
|
|
|
|
|
extreme_values.append(float(value))
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
extreme_dict = {point: value for point, value, in zip(extreme_points, extreme_values)}
|
|
|
|
|
return extreme_dict
|
|
|
|
|
|
|
|
|
|
def monotonicity(function):
|
|
|
|
|
"""
|
|
|
|
|
@ -98,53 +120,64 @@ def monotonicity(function):
|
|
|
|
|
independent_variable, function = split_function(function)
|
|
|
|
|
var = symbols(independent_variable)
|
|
|
|
|
func_expr = sympify(function)
|
|
|
|
|
derivative = diff(func_expr, var) # 一阶导数
|
|
|
|
|
derivative = diff( func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 转换为数值计算函数
|
|
|
|
|
deriv_num = lambdify(var, derivative, 'numpy')
|
|
|
|
|
# 获取定义域
|
|
|
|
|
x_min, x_max = get_domain(func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 定义扫描参数(可根据实际函数调整)
|
|
|
|
|
x_min, x_max = -10, 10 # 扫描区间
|
|
|
|
|
step = 0.1 # 扫描步长(更小步长更精确但计算量更大)
|
|
|
|
|
# 转换为数值函数
|
|
|
|
|
try:
|
|
|
|
|
deriv_num = lambdify(var, derivative, 'numpy')
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"导数转换失败:{e}")
|
|
|
|
|
return [], []
|
|
|
|
|
|
|
|
|
|
# 区间扫描
|
|
|
|
|
step = 0.1
|
|
|
|
|
x_vals = np.arange(x_min, x_max + step, step)
|
|
|
|
|
f_scan = []
|
|
|
|
|
for xi in x_vals:
|
|
|
|
|
try:
|
|
|
|
|
f_scan.append(deriv_num(xi))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
f_scan.append(np.nan)
|
|
|
|
|
|
|
|
|
|
# 检测导数符号变化区间
|
|
|
|
|
candidate_intervals = []
|
|
|
|
|
for i in range(len(f_scan)-1):
|
|
|
|
|
if np.isnan(f_scan[i]) or np.isnan(f_scan[i+1]):
|
|
|
|
|
continue
|
|
|
|
|
if f_scan[i] * f_scan[i+1] <= 0:
|
|
|
|
|
candidate_intervals.append((x_vals[i], x_vals[i+1]))
|
|
|
|
|
|
|
|
|
|
# 检测符号变化点(使用二分法精确化)
|
|
|
|
|
# 使用布伦特法寻找零点
|
|
|
|
|
change_points = []
|
|
|
|
|
prev_sign = np.sign(deriv_num(x_vals[0]))
|
|
|
|
|
for i in range(1, len(x_vals)):
|
|
|
|
|
current_sign = np.sign(deriv_num(x_vals[i]))
|
|
|
|
|
if prev_sign != current_sign:
|
|
|
|
|
# 二分法查找精确交点
|
|
|
|
|
a, b = x_vals[i-1], x_vals[i]
|
|
|
|
|
for _ in range(10): # 迭代10次足够精确
|
|
|
|
|
mid = (a + b) / 2
|
|
|
|
|
mid_sign = np.sign(deriv_num(mid))
|
|
|
|
|
if mid_sign == prev_sign:
|
|
|
|
|
a = mid
|
|
|
|
|
else:
|
|
|
|
|
b = mid
|
|
|
|
|
# 转换为Python原生浮点数并保留3位小数
|
|
|
|
|
point = float(round((a + b)/2, 3))
|
|
|
|
|
change_points.append(point)
|
|
|
|
|
prev_sign = current_sign
|
|
|
|
|
for a, b in candidate_intervals:
|
|
|
|
|
try:
|
|
|
|
|
root = brentq(deriv_num, a, b, xtol=1e-8)
|
|
|
|
|
change_points.append(float(round(root, 3)))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 生成单调区间(数值均为普通浮点数)
|
|
|
|
|
up_intervals = []
|
|
|
|
|
down_intervals = []
|
|
|
|
|
current_sign = np.sign(deriv_num(x_min + 1e-6)) # 避免端点误差
|
|
|
|
|
start = float(round(x_min, 3)) # 转换为普通浮点数
|
|
|
|
|
# 生成单调区间
|
|
|
|
|
change_points = sorted(change_points)
|
|
|
|
|
up_intervals, down_intervals = [], []
|
|
|
|
|
try:
|
|
|
|
|
current_sign = np.sign(deriv_num(x_min + 1e-6))
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
current_sign = 0
|
|
|
|
|
start = float(round(x_min, 3))
|
|
|
|
|
for point in change_points:
|
|
|
|
|
if current_sign > 0:
|
|
|
|
|
up_intervals.append((start, point))
|
|
|
|
|
else:
|
|
|
|
|
elif current_sign < 0:
|
|
|
|
|
down_intervals.append((start, point))
|
|
|
|
|
current_sign *= -1
|
|
|
|
|
start = point
|
|
|
|
|
# 处理最后一个区间(终点转换为普通浮点数)
|
|
|
|
|
end = float(round(x_max, 3))
|
|
|
|
|
if current_sign > 0:
|
|
|
|
|
up_intervals.append((start, end))
|
|
|
|
|
else:
|
|
|
|
|
elif current_sign < 0:
|
|
|
|
|
down_intervals.append((start, end))
|
|
|
|
|
|
|
|
|
|
return up_intervals, down_intervals
|
|
|
|
|
@ -161,55 +194,123 @@ def aotu(function):
|
|
|
|
|
func_expr = sympify(function)
|
|
|
|
|
derivative = diff(func_expr, var, 2) # 二阶导数
|
|
|
|
|
|
|
|
|
|
# 转换为数值计算函数
|
|
|
|
|
deriv_num = lambdify(var, derivative, 'numpy')
|
|
|
|
|
# 获取定义域
|
|
|
|
|
x_min, x_max = get_domain(func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 定义扫描参数(可根据实际函数调整)
|
|
|
|
|
x_min, x_max = -10, 10 # 扫描区间
|
|
|
|
|
step = 0.1 # 扫描步长(更小步长更精确但计算量更大)
|
|
|
|
|
# 转换为数值函数
|
|
|
|
|
try:
|
|
|
|
|
deriv_num = lambdify(var, derivative, 'numpy')
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"二阶导数转换失败:{e}")
|
|
|
|
|
return [], []
|
|
|
|
|
|
|
|
|
|
# 区间扫描
|
|
|
|
|
step = 0.1
|
|
|
|
|
x_vals = np.arange(x_min, x_max + step, step)
|
|
|
|
|
f_scan = []
|
|
|
|
|
for xi in x_vals:
|
|
|
|
|
try:
|
|
|
|
|
f_scan.append(deriv_num(xi))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
f_scan.append(np.nan)
|
|
|
|
|
|
|
|
|
|
# 检测二阶导数符号变化区间
|
|
|
|
|
candidate_intervals = []
|
|
|
|
|
for i in range(len(f_scan)-1):
|
|
|
|
|
if np.isnan(f_scan[i]) or np.isnan(f_scan[i+1]):
|
|
|
|
|
continue
|
|
|
|
|
if f_scan[i] * f_scan[i+1] <= 0:
|
|
|
|
|
candidate_intervals.append((x_vals[i], x_vals[i+1]))
|
|
|
|
|
|
|
|
|
|
# 检测符号变化点(使用二分法精确化)
|
|
|
|
|
# 使用布伦特法寻找零点
|
|
|
|
|
change_points = []
|
|
|
|
|
prev_sign = np.sign(deriv_num(x_vals[0]))
|
|
|
|
|
for i in range(1, len(x_vals)):
|
|
|
|
|
current_sign = np.sign(deriv_num(x_vals[i]))
|
|
|
|
|
if prev_sign != current_sign:
|
|
|
|
|
# 二分法查找精确交点
|
|
|
|
|
a, b = x_vals[i-1], x_vals[i]
|
|
|
|
|
for _ in range(10): # 迭代10次足够精确
|
|
|
|
|
mid = (a + b) / 2
|
|
|
|
|
mid_sign = np.sign(deriv_num(mid))
|
|
|
|
|
if mid_sign == prev_sign:
|
|
|
|
|
a = mid
|
|
|
|
|
else:
|
|
|
|
|
b = mid
|
|
|
|
|
# 转换为Python原生浮点数并保留3位小数(与monotonicity统一)
|
|
|
|
|
point = float(round((a + b)/2, 3))
|
|
|
|
|
change_points.append(point)
|
|
|
|
|
prev_sign = current_sign
|
|
|
|
|
for a, b in candidate_intervals:
|
|
|
|
|
try:
|
|
|
|
|
root = brentq(deriv_num, a, b, xtol=1e-8)
|
|
|
|
|
change_points.append(float(round(root, 3)))
|
|
|
|
|
except (ValueError, ZeroDivisionError, OverflowError):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 生成凹凸区间(数值均为普通浮点数)
|
|
|
|
|
ao_intervals = [] # 凹区间(二阶导数≥0)
|
|
|
|
|
tu_intervals = [] # 凸区间(二阶导数≤0)
|
|
|
|
|
current_sign = np.sign(deriv_num(x_min + 1e-6)) # 避免端点误差
|
|
|
|
|
start = float(round(x_min, 3)) # 转换为普通浮点数
|
|
|
|
|
# 生成凹凸区间
|
|
|
|
|
ao_intervals, tu_intervals = [], []
|
|
|
|
|
try:
|
|
|
|
|
current_sign = np.sign(deriv_num(x_min + 1e-6))
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
current_sign = 0
|
|
|
|
|
start = float(round(x_min, 3))
|
|
|
|
|
for point in change_points:
|
|
|
|
|
if current_sign > 0:
|
|
|
|
|
if current_sign >= 0:
|
|
|
|
|
ao_intervals.append((start, point))
|
|
|
|
|
else:
|
|
|
|
|
tu_intervals.append((start, point))
|
|
|
|
|
current_sign *= -1
|
|
|
|
|
start = point
|
|
|
|
|
# 处理最后一个区间(终点转换为普通浮点数)
|
|
|
|
|
end = float(round(x_max, 3))
|
|
|
|
|
if current_sign > 0:
|
|
|
|
|
if current_sign >= 0:
|
|
|
|
|
ao_intervals.append((start, end))
|
|
|
|
|
else:
|
|
|
|
|
tu_intervals.append((start, end))
|
|
|
|
|
|
|
|
|
|
return ao_intervals, tu_intervals
|
|
|
|
|
|
|
|
|
|
def max_min(function):
|
|
|
|
|
"""
|
|
|
|
|
计算函数的极大值和极小值,若存在极值点,则返回极大值和极小值;
|
|
|
|
|
否则返回定义域边界 [x_min, x_max] 内的函数值作为最大最小值的估计。
|
|
|
|
|
:param function: 函数表达式
|
|
|
|
|
:return: 极大值和极小值(或边界值的最大最小值)
|
|
|
|
|
"""
|
|
|
|
|
extreme_dict = extreme_value(function)
|
|
|
|
|
function = convert_formula(function)
|
|
|
|
|
independent_variable, function = split_function(function)
|
|
|
|
|
var = symbols(independent_variable)
|
|
|
|
|
func_expr = sympify(function)
|
|
|
|
|
func_num = lambdify(var, func_expr, 'numpy')
|
|
|
|
|
|
|
|
|
|
# 获取定义域
|
|
|
|
|
x_min, x_max = get_domain(func_expr, var)
|
|
|
|
|
|
|
|
|
|
# 如果没有极值点,检查边界值
|
|
|
|
|
if not extreme_dict:
|
|
|
|
|
try:
|
|
|
|
|
boundary_values = [float(func_num(x_min)), float(func_num(x_max))]
|
|
|
|
|
max_value = max(boundary_values)
|
|
|
|
|
min_value = min(boundary_values)
|
|
|
|
|
print(f"未找到极值点,使用边界值 x={x_min} 和 x={x_max} 估计最大最小值")
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
print("无法计算边界值,可能由于定义域问题")
|
|
|
|
|
return None, None
|
|
|
|
|
else:
|
|
|
|
|
max_value = max(extreme_dict.values())
|
|
|
|
|
min_value = min(extreme_dict.values())
|
|
|
|
|
# 打印极值点信息
|
|
|
|
|
max_points = [p for p, v in extreme_dict.items() if v == max_value]
|
|
|
|
|
min_points = [p for p, v in extreme_dict.items() if v == min_value]
|
|
|
|
|
print(f"极大值点:{[f'x={p:.6f}' for p in max_points]}, 极大值:{max_value:.4f}")
|
|
|
|
|
print(f"极小值点:{[f'x={p:.6f}' for p in min_points]}, 极小值:{min_value:.4f}")
|
|
|
|
|
|
|
|
|
|
return max_value, min_value
|
|
|
|
|
|
|
|
|
|
##################################################### 修改 #####################################################
|
|
|
|
|
################################################################################################################
|
|
|
|
|
|
|
|
|
|
def taylor_series(function, n, x0=0):
|
|
|
|
|
"""
|
|
|
|
|
计算泰勒展开式
|
|
|
|
|
:param function: 函数表达式
|
|
|
|
|
:param x0: 展开点
|
|
|
|
|
:param n: 展开阶数
|
|
|
|
|
:return: 泰勒展开式
|
|
|
|
|
"""
|
|
|
|
|
function = convert_formula(function)
|
|
|
|
|
independent_variable, function = split_function(function)
|
|
|
|
|
independent_variable = symbols(independent_variable)
|
|
|
|
|
function = sympify(function)
|
|
|
|
|
taylor_series = function.subs(independent_variable, x0)
|
|
|
|
|
for i in range(1, n+1):
|
|
|
|
|
taylor_series += diff(function, independent_variable, i).subs(independent_variable, x0) * (independent_variable - x0)**i / factorial(i)
|
|
|
|
|
return taylor_series
|
|
|
|
|
|
|
|
|
|
def curvature(function, x0):
|
|
|
|
|
"""
|
|
|
|
|
计算函数在某一点的曲率
|
|
|
|
|
@ -287,10 +388,17 @@ def UI():
|
|
|
|
|
print(f"| {str(point).ljust(max_point_len)} | {str(value).ljust(max_value_len)} |")
|
|
|
|
|
else:
|
|
|
|
|
print("未找到极值点。")
|
|
|
|
|
######################################################################################################
|
|
|
|
|
############################################## 修改 ##################################################
|
|
|
|
|
elif command == "2":
|
|
|
|
|
function = input("请输入函数表达式:(注:只支持形如f(x)=的表达式,不支持y=的表达式)")
|
|
|
|
|
max_value, min_value = max_min(function)
|
|
|
|
|
print(f"最大值:{max_value:.4f},最小值:{min_value:.4f}")
|
|
|
|
|
if max_value is not None and min_value is not None:
|
|
|
|
|
print(f"最大值:{max_value:.4f},最小值:{min_value:.4f}")
|
|
|
|
|
else:
|
|
|
|
|
print("无法计算最大最小值,请检查函数定义域或表达式")
|
|
|
|
|
############################################## 修改 ##################################################
|
|
|
|
|
######################################################################################################
|
|
|
|
|
elif command == "3":
|
|
|
|
|
function = input("请输入函数表达式:(注:只支持形如f(x)=的表达式,不支持y=的表达式)")
|
|
|
|
|
point = float(input("请输入自变量的取值点:"))
|
|
|
|
|
|