Compare commits

..

No commits in common. 'main' and 'main' have entirely different histories.
main ... main

@ -20,43 +20,8 @@
## 使用说明
### 一、安装准备
1. **安装Python**如果您的电脑还没有安装Python请先从[Python官网](https://www.python.org/)下载并安装Python 3.8及以上版本推荐安装最新稳定版。安装时请勾选「Add Python to PATH」选项Windows系统方便后续操作。
2. **安装依赖库**
- 打开「命令提示符」Windows键+R输入`cmd`后回车);
- 输入`cd C:\Users\您的用户名\Documents\PythonScripts\college_computing_final_project`(请将路径替换为您实际的项目文件夹路径);
- 输入命令:`pip install -r requirement.txt`,等待所有库安装完成(可能需要几分钟)。
### 二、启动程序
安装完成后,可在命令提示符中输入:`python main.py`,按回车键;部分设备也可通过双击`main.py`文件打开。程序会显示如下菜单:
```
欢迎使用高等数学综合实用计算器
请选择要使用的功能
1.初等数学运算
2.映射与函数
3.数列极限与数值级数
...(其他功能)
0.退出
```
### 三、功能使用示例
以「初等数学运算」为例:
1. 在菜单中输入`1`并回车,进入初等数学运算功能;
2. 根据提示选择具体操作(如输入`1`选择「基本计算」);
3. 输入算式(例如:`3×4÷2`),注意使用半角符号(如`*`代替`×``/`代替`÷`
4. 程序会直接显示计算结果(示例结果:`6`)。
其他功能操作类似按菜单提示选择数字并输入对应内容即可。需要注意的是输入区间时只接受开区间或闭区间不能输入半开半闭区间这是因为元组和列表的语法恰好和数学上开闭区间的表示方法相同此说明供了解Python的用户参考
## 注意事项
1. **输入格式**:所有数学符号请使用英文半角符号(如`+`、`-`、`*`、`/`、`()`),避免使用中文符号(如``、`×`)。程序会自动转换部分符号,但复杂表达式可能识别失败。
2. **依赖问题**:如果启动程序时提示「模块未找到」,请检查是否已正确执行`pip install -r requirement.txt`命令。
3. **特殊函数**:支持`sin(x)`、`cos(x)`、`ln(x)`等常见函数,输入时需完整拼写(如`sin(x)`不能简写为`sx`)。
4. **输入习惯**无需专门学习Python语法按照数学书写习惯输入即可程序会自动进行符号转换。若遇到无法转换的内容请按「联系我们」部分的方式反馈。
5. **退出程序**:输入`0`并回车可退出主菜单,返回电脑桌面。
## 联系我们
如果您在使用高等数学综合实用计算器应用程序过程中遇到任何问题或有任何建议,欢迎联系我们。您可以通过以下方式与我们联系:

@ -1,226 +0,0 @@
from numpy import *
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from convert_formula import convert_formula # 导入转换函数
import matplotlib
# 全局配置中文字体(新增)
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体Windows系统常用中文字体
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def plot_plane_curve(a, b, M, f1, f2, title='平面曲线'):
'''
绘制平面参数曲线
参数:
a (float): 参数t的起始值
b (float): 参数t的终止值需满足 a <= b
M (int): 参数t的采样点数需为正整数
f1 (callable): X坐标关于t的函数输入一维数组输出一维数组
f2 (callable): Y坐标关于t的函数输入一维数组输出一维数组
title (str): 图形标题
'''
# 参数校验
if not (isinstance(M, int) and M > 0):
raise ValueError(f'采样点数M={M}需为正整数')
if a > b:
raise ValueError(f'参数范围需满足a={a} <= b={b}')
t = linspace(a, b, M)
X = f1(t)
Y = f2(t)
plt.figure()
plt.plot(X, Y)
plt.xlabel('X')
plt.ylabel('Y')
plt.title(title) # 标题使用用户输入的中文
plt.grid(True)
plt.show()
def plot_space_surface(a, b, M, c, d, N, F1, F2, F3, title='空间曲面'):
'''
绘制空间参数曲面
参数:
a/b (float): 参数t的取值范围a <= b
M (int): t的采样点数正整数
c/d (float): 参数s的取值范围c <= d
N (int): s的采样点数正整数
F1/F2/F3 (callable): X/Y/Z坐标关于s,t的函数输入二维网格输出二维网格
title (str): 图形标题
'''
# 参数校验
for var, name in [(M, 'M'), (N, 'N')]:
if not (isinstance(var, int) and var > 0):
raise ValueError(f'采样点数{name}={var}需为正整数')
for start, end, name in [(a, b, 't'), (c, d, 's')]:
if start > end:
raise ValueError(f'{name}参数范围需满足{start} <= {end}')
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
t = linspace(a, b, M)
s = linspace(c, d, N)
s_grid, t_grid = meshgrid(s, t)
X = F1(s_grid, t_grid)
Y = F2(s_grid, t_grid)
Z = F3(s_grid, t_grid)
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title(title) # 标题使用用户输入的中文
plt.show()
def plot_space_curve(a, b, M, F1, F2, F3, title='空间曲线'):
'''
绘制单参数空间曲线如螺旋线
参数:
a/b (float): 参数t的取值范围a <= b
M (int): t的采样点数正整数
F1/F2/F3 (callable): X/Y/Z坐标关于t的函数输入一维数组输出一维数组
title (str): 图形标题
'''
# 参数校验
if not (isinstance(M, int) and M > 0):
raise ValueError(f'采样点数M={M}需为正整数')
if a > b:
raise ValueError(f'参数范围需满足a={a} <= b={b}')
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
t = linspace(a, b, M)
X = F1(t)
Y = F2(t)
Z = F3(t)
ax.plot3D(X, Y, Z, color='blue', linewidth=2) # 使用plot3D绘制曲线
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title(title) # 标题使用用户输入的中文
plt.show()
def test_plane_and_space_curves():
# 测试平面曲线:单位圆
plot_plane_curve(
a=0, b=2*pi, M=1000,
f1=lambda t: np.cos(t),
f2=lambda t: np.sin(t),
title='单位圆(参数方程)'
)
# 测试平面曲线:抛物线y=x²
plot_plane_curve(
a=-2, b=2, M=100,
f1=lambda t: t,
f2=lambda t: t**2,
title='抛物线 y=x²参数方程'
)
# 测试空间曲面:球面
plot_space_surface(
a=0, b=pi, M=50,
c=0, d=2*pi, N=50,
F1=lambda s,t: np.sin(t)*np.cos(s),
F2=lambda s,t: np.sin(t)*np.sin(s),
F3=lambda s,t: np.cos(t),
title='球面(参数方程)'
)
# 新增测试空间曲线圆锥螺旋线半径随z轴增大
plot_space_curve(
a=0, b=8*pi, M=1000,
F1=lambda t: t * np.cos(t),
F2=lambda t: t * np.sin(t),
F3=lambda t: t,
title='圆锥螺旋线(参数方程)'
)
def UI():
'''命令行交互界面(支持用户输入采样点范围)'''
while True:
print("\n=== 解析几何绘图工具 ===")
print("1. 绘制平面曲线")
print("2. 绘制空间曲线")
print("3. 绘制空间曲面")
print("4. 退出程序")
choice = input("请选择功能输入1-4: ")
if choice == '4':
print("已退出程序")
break
# 平面曲线单参数t
elif choice == '1':
print("\n--- 平面曲线绘制 ---\n提示变量用t如输入cos(t)会自动转换为np.cos(t)参数范围支持输入pi如2*pi")
x_expr = input("X(t)表达式: ")
y_expr = input("Y(t)表达式: ")
a_input = input("请输入t的起始值如0或pi: ").strip().lower() # 支持pi输入
b_input = input("请输入t的结束值如2*pi: ").strip().lower()
try:
a = eval(a_input)
b = eval(b_input)
x_func = eval(f"lambda t: {convert_formula(x_expr)}")
y_func = eval(f"lambda t: {convert_formula(y_expr)}")
plot_plane_curve(a=a, b=b, M=1000, f1=x_func, f2=y_func, title=f"平面曲线: X(t)={x_expr}, Y(t)={y_expr}")
except Exception as e:
print(f"错误: {str(e)}")
# 空间曲线单参数t
elif choice == '2':
print("\n--- 空间曲线绘制 ---\n提示变量用t参数范围支持输入pi如8*pi")
x_expr = input("X(t)表达式: ")
y_expr = input("Y(t)表达式: ")
z_expr = input("Z(t)表达式: ")
a_input = input("请输入t的起始值如0或pi: ").strip().lower()
b_input = input("请输入t的结束值如8*pi: ").strip().lower()
try:
a = eval(a_input)
b = eval(b_input)
x_func = eval(f"lambda t: {convert_formula(x_expr)}")
y_func = eval(f"lambda t: {convert_formula(y_expr)}")
z_func = eval(f"lambda t: {convert_formula(z_expr)}")
plot_space_curve(a=a, b=b, M=10000, F1=x_func, F2=y_func, F3=z_func, title=f"空间曲线: X(t)={x_expr}, Y(t)={y_expr}, Z(t)={z_expr}")
except Exception as e:
print(f"错误: {str(e)}")
# 空间曲面双参数s/t
elif choice == '3':
print("\n--- 空间曲面绘制 ---\n提示变量用s和t参数范围支持输入pi如2*pi")
x_expr = input("X(s,t)表达式: ")
y_expr = input("Y(s,t)表达式: ")
z_expr = input("Z(s,t)表达式: ")
c_input = input("请输入s的起始值如0或pi: ").strip().lower()
d_input = input("请输入s的结束值如2*pi: ").strip().lower()
a_input = input("请输入t的起始值如0或pi: ").strip().lower()
b_input = input("请输入t的结束值如pi: ").strip().lower()
try:
c = eval(c_input)
d = eval(d_input)
a = eval(a_input)
b = eval(b_input)
x_func = eval(f"lambda s,t: {convert_formula(x_expr)}")
y_func = eval(f"lambda s,t: {convert_formula(y_expr)}")
z_func = eval(f"lambda s,t: {convert_formula(z_expr)}")
plot_space_surface(a=a, b=b, M=50, c=c, d=d, N=50, F1=x_func, F2=y_func, F3=z_func, title=f"空间曲面: X(s,t)={x_expr}, Y(s,t)={y_expr}, Z(s,t)={z_expr}")
except Exception as e:
print(f"错误: {str(e)}")
else:
print("输入无效,请重新选择")
if __name__ == "__main__":
UI() # 启动命令行界面
#test_plane_and_space_curves()

@ -1,91 +0,0 @@
from sympy import *
from matplotlib.pyplot import *
from convert_formula import *
def basic_caculate(formula):
return eval(convert_formula(formula).replace('*j', 'j'))
def solve_formula(formula, independent_variable=1):
"""
求解方程
:param formula: 方程列表
:param independent_variable: 变量个数
:return: 方程解
"""
llist = []
x, y, z = symbols('x y z')
for i in formula:
l = i.split('=')
left = l[0] + '-(' + l[1] + ')'
llist.append(sympify(convert_formula(left)))
if independent_variable == 1:
return solve(llist[0], x)
elif independent_variable == 2:
return solve((llist[0], llist[1]), (x, y))
elif independent_variable == 3:
return solve((llist[0], llist[1], llist[2]), (x, y, z))
def plot_function(formula, length):
"""
绘制函数图像
:param formula: 函数表达式
:param length: 自变量取值范围
:return: 图像
"""
x = np.linspace(length[0], length[1], 1000)
independent, formula = split_function(convert_formula(formula))
y = eval('lambda %s: %s' % (independent, formula)) # 使用eval直接生成lambda函数
plot(x, y(x))
show()
def plot_implicit_function(formula, x_range=(-5, 5), y_range=(-5, 5), density=200):
'''
绘制隐函数图像 +=1
:param formula: 隐函数表达式字符串 "x**2 + y**2 - 1"
:param x_range: x轴取值范围元组 (-5,5)
:param y_range: y轴取值范围元组 (-5,5)
:param density: 网格点密度数值越大越平滑
'''
# 生成x和y的网格点
x = np.linspace(x_range[0], x_range[1], density)
y = np.linspace(y_range[0], y_range[1], density)
X, Y = np.meshgrid(x, y)
# 转换表达式复用现有convert_formula处理符号
formula = convert_formula(formula)
l = formula.split('=')
formula = l[0]+'-('+l[1]+')'
# 计算网格点的函数值F(x,y)
try:
F = eval(formula.replace('x', 'X').replace('y', 'Y')) # 将表达式中的x/y替换为二维网格X/Y
except Exception as e:
raise ValueError(f"表达式错误:{e}")
# 绘制F(x,y)=0的等高线即隐函数图像
contour(X, Y, F, levels=[0], colors='blue')
grid(True)
show()
def UI():
while True:
command = input('请选择功能1.基本计算 2.解方程 3.绘制函数图像 4.绘制平面解析几何图像 5.退出\n')
if command == '1':
formula = input('请输入算式:')
print(basic_caculate(formula))
elif command == '2':
independent_variable = input('请输入方程未知量个数:')
formula = input('请输入方程组(方程之间用英文逗号分隔):')
print(solve_formula(formula.split(','), int(independent_variable)))
elif command == '3':
formula = input('请输入函数表达式(如 f(x)=x^2')
length = input('请输入自变量取值范围(区间形式,不支持半开半闭区间):')
plot_function(formula, eval(length))
elif command == '4':
formula = input('请输入隐函数表达式(如 x^2+y^2=1')
plot_implicit_function(formula)
elif command == '5':
print('谢谢使用!')
break
else:
print('输入错误,请重新输入!')
if __name__ == '__main__':
UI()

@ -12,8 +12,6 @@ def convert_formula(input):
# 正则说明:\b确保匹配完整函数名([a-zA-Z0-9])捕获后续字符
input = re.sub(rf'\b{func}([a-zA-Z0-9])', rf'{func}(\1)', input)
input = re.sub(r'(\d+\.?\d*|\.\d+|\))([a-zA-Z]|\d+\.?\d*|\.\d*|\()', r'\1*\2', input)
# 新增处理x/y/z等字母相乘省略乘号的情况如xy→x*yxyz→x*y*z
input = re.sub(r'([xyzXYZ])(?=[xyzXYZ])', r'\1*', input)
# 替换所有的乘除符号为 Python 中的运算符
input = input.replace("×", "*")
input = input.replace("÷", "/")

@ -1,303 +0,0 @@
#曲线积分与曲面积分:包括两类曲线积分计算、两类曲面积分计算、环量流量计算、散度旋度计算等
import unittest
import sympy as sp
from convert_formula import *
import math
def first_kind_curve_integration(r, t_range, function):
"""
计算第一类曲线积分
:param r: 曲线的参数方程以元组形式给出 (x(t), y(t)) (x(t), y(t), z(t))
:param t_range: 参数 t 的积分区间 (t1, t2)
:param function: 被积函数用参数 t 表示
:return: 第一类曲线积分的值
"""
t = sp.symbols('t')
r_tuple = eval(r) # 将输入的字符串转换为元组
# 将元组中每个元素转换为sympy表达式类似处理function的方式
r = tuple(sp.sympify(convert_formula(elem)) for elem in r_tuple)
if len(r) == 2:
x, y = r
dx_dt = sp.diff(x, t)
dy_dt = sp.diff(y, t)
ds = sp.sqrt(dx_dt**2 + dy_dt**2)
elif len(r) == 3:
x, y, z = r
dx_dt = sp.diff(x, t)
dy_dt = sp.diff(y, t)
dz_dt = sp.diff(z, t)
ds = sp.sqrt(dx_dt**2 + dy_dt**2 + dz_dt**2)
else:
raise ValueError("参数方程长度必须为2二维曲线或3三维曲线")
function = sp.sympify(convert_formula(function))
lower, upper = eval(t_range)
result = sp.integrate(function * ds, (t, lower, upper))
return result
def second_kind_curve_integration(P, Q, r, t_range):
"""
计算第二类曲线积分
:param P: 向量场的 P 分量用参数 t 表示
:param Q: 向量场的 Q 分量用参数 t 表示
:param r: 曲线的参数方程以元组形式给出 (x(t), y(t))
:param t_range: 参数 t 的积分区间 (t1, t2)
:return: 第二类曲线积分的值
"""
t = sp.symbols('t')
# 转换r为sympy表达式元组
r_tuple = eval(r)
r = tuple(sp.sympify(convert_formula(elem)) for elem in r_tuple)
x, y = r
dx_dt = sp.diff(x, t)
dy_dt = sp.diff(y, t)
# 将 P 和 Q 中的 x、y 替换为 t 的函数
P_expr = sp.sympify(convert_formula(P)).subs({sp.symbols('x'): x, sp.symbols('y'): y})
Q_expr = sp.sympify(convert_formula(Q)).subs({sp.symbols('x'): x, sp.symbols('y'): y})
lower, upper = eval(t_range)
result = sp.integrate(P_expr * dx_dt + Q_expr * dy_dt, (t, lower, upper))
return result
def first_kind_surface_integration(r, u_range, v_range, function):
"""
计算第一类曲面积分
:param r: 曲面的参数方程以元组形式给出 (x(u, v), y(u, v), z(u, v))
:param u_range: 参数 u 的积分区间 (u1, u2)
:param v_range: 参数 v 的积分区间 (v1, v2)
:param function: 被积函数用参数 u v 表示
:return: 第一类曲面积分的值
"""
u, v = sp.symbols('u v')
# 转换r为sympy表达式元组
r_tuple = eval(r)
r = tuple(sp.sympify(convert_formula(elem)) for elem in r_tuple)
x, y, z = r
ru = (sp.diff(x, u), sp.diff(y, u), sp.diff(z, u))
rv = (sp.diff(x, v), sp.diff(y, v), sp.diff(z, v))
cross_product = (ru[1]*rv[2] - ru[2]*rv[1], ru[2]*rv[0] - ru[0]*rv[2], ru[0]*rv[1] - ru[1]*rv[0])
E = sp.sqrt(cross_product[0]**2 + cross_product[1]**2 + cross_product[2]**2)
# 转换function为sympy表达式
function = sp.sympify(convert_formula(function))
u1, u2 = eval(u_range)
v1, v2 = eval(v_range)
integration1 = sp.integrate(function * E, (u, u1, u2))
result = sp.integrate(integration1, (v, v1, v2))
return result
# 第二类曲面积分
def second_kind_surface_integration(P, Q, R, r, u_range, v_range):
"""
计算第二类曲面积分
:param P: 向量场的 P 分量用参数 u v 表示
:param Q: 向量场的 Q 分量用参数 u v 表示
:param R: 向量场的 R 分量用参数 u v 表示
:param r: 曲面的参数方程以元组形式给出 (x(u, v), y(u, v), z(u, v))
:param u_range: 参数 u 的积分区间 (u1, u2)
:param v_range: 参数 v 的积分区间 (v1, v2)
:return: 第二类曲面积分的值
"""
u, v = sp.symbols('u v')
# 转换r为sympy表达式元组
r_tuple = eval(r)
r = tuple(sp.sympify(convert_formula(elem)) for elem in r_tuple)
x, y, z = r
ru = (sp.diff(x, u), sp.diff(y, u), sp.diff(z, u))
rv = (sp.diff(x, v), sp.diff(y, v), sp.diff(z, v))
# 计算叉乘 cross_product原方向指向内部取反后指向外侧
cross_product = (ru[1]*rv[2] - ru[2]*rv[1], ru[2]*rv[0] - ru[0]*rv[2], ru[0]*rv[1] - ru[1]*rv[0])
# 取反叉乘结果以匹配外侧法向量
cross_product = (-cross_product[0], -cross_product[1], -cross_product[2])
# 将 P、Q、R 中的 x、y、z 替换为 u、v 的函数
P_expr = sp.sympify(convert_formula(P)).subs({sp.symbols('x'): x, sp.symbols('y'): y, sp.symbols('z'): z})
Q_expr = sp.sympify(convert_formula(Q)).subs({sp.symbols('x'): x, sp.symbols('y'): y, sp.symbols('z'): z})
R_expr = sp.sympify(convert_formula(R)).subs({sp.symbols('x'): x, sp.symbols('y'): y, sp.symbols('z'): z})
u1, u2 = eval(u_range)
v1, v2 = eval(v_range)
integration1 = sp.integrate(P_expr * cross_product[0] + Q_expr * cross_product[1] + R_expr * cross_product[2], (u, u1, u2))
result = sp.integrate(integration1, (v, v1, v2))
return result
# 环量计算
def circulation(P, Q, r, t_range):
"""
计算环量
:param P: 向量场的 P 分量用参数 t 表示
:param Q: 向量场的 Q 分量用参数 t 表示
:param r: 曲线的参数方程以元组形式给出 (x(t), y(t))
:param t_range: 参数 t 的积分区间 (t1, t2)
:return: 环量的值
"""
return second_kind_curve_integration(P, Q, r, t_range)
# 流量计算
def flux(P, Q, R, r, u_range, v_range):
"""
计算流量
:param P: 向量场的 P 分量用参数 u v 表示
:param Q: 向量场的 Q 分量用参数 u v 表示
:param R: 向量场的 R 分量用参数 u v 表示
:param r: 曲面的参数方程以元组形式给出 (x(u, v), y(u, v), z(u, v))
:param u_range: 参数 u 的积分区间 (u1, u2)
:param v_range: 参数 v 的积分区间 (v1, v2)
:return: 流量的值
"""
return second_kind_surface_integration(P, Q, R, r, u_range, v_range)
# 散度计算
def divergence(P, Q, R):
"""
计算散度
:param P: 向量场的 P 分量 x, y, z 表示
:param Q: 向量场的 Q 分量 x, y, z 表示
:param R: 向量场的 R 分量 x, y, z 表示
:return: 散度的值
"""
x, y, z = sp.symbols('x y z')
P = sp.sympify(convert_formula(P))
Q = sp.sympify(convert_formula(Q))
R = sp.sympify(convert_formula(R))
div = sp.diff(P, x) + sp.diff(Q, y) + sp.diff(R, z)
return div
# 旋度计算
def curl(P, Q, R):
"""
计算旋度
:param P: 向量场的 P 分量 x, y, z 表示
:param Q: 向量场的 Q 分量 x, y, z 表示
:param R: 向量场的 R 分量 x, y, z 表示
:return: 旋度的值以元组形式给出 (curl_x, curl_y, curl_z)
"""
x, y, z = sp.symbols('x y z')
P = sp.sympify(convert_formula(P))
Q = sp.sympify(convert_formula(Q))
R = sp.sympify(convert_formula(R))
curl_x = sp.diff(R, y) - sp.diff(Q, z)
curl_y = sp.diff(P, z) - sp.diff(R, x)
curl_z = sp.diff(Q, x) - sp.diff(P, y)
return curl_x, curl_y, curl_z
class TestIntegralFunctions(unittest.TestCase):
def test_first_kind_curve_integration(self):
"""测试第一类曲线积分"""
t = sp.symbols('t')
r = (sp.cos(t), sp.sin(t))
t_range = (0, 2*math.pi)
function = "1"
result = first_kind_curve_integration(r, t_range, function)
# 圆的周长为 2π
self.assertEqual(result, 2*math.pi)
def test_second_kind_curve_integration(self):
"""测试第二类曲线积分"""
t = sp.symbols('t')
r = (sp.cos(t), sp.sin(t))
t_range = (0, 2*math.pi)
P = "-y"
Q = "x"
result = second_kind_curve_integration(P, Q, r, t_range)
# 环量为 2π
self.assertEqual(result, 2*math.pi)
def test_first_kind_surface_integration(self):
"""测试第一类曲面积分"""
u, v = sp.symbols('u v')
r = (sp.cos(u)*sp.sin(v), sp.sin(u)*sp.sin(v), sp.cos(v))
u_range = (0, 2*math.pi)
v_range = (0, math.pi)
function = "1"
result = first_kind_surface_integration(r, u_range, v_range, function)
# 单位球的表面积为 4π
self.assertEqual(result, 4*math.pi)
def test_second_kind_surface_integration(self):
"""测试第二类曲面积分"""
u, v = sp.symbols('u v')
r = (sp.cos(u)*sp.sin(v), sp.sin(u)*sp.sin(v), sp.cos(v))
u_range = (0, 2*math.pi)
v_range = (0, math.pi)
P = "x"
Q = "y"
R = "z"
result = second_kind_surface_integration(P, Q, R, r, u_range, v_range)
# 流量为 4π
self.assertEqual(result, 4*math.pi)
def test_divergence(self):
"""测试散度计算"""
P = "x"
Q = "y"
R = "z"
result = divergence(P, Q, R)
self.assertEqual(result, 3)
def test_curl(self):
"""测试旋度计算"""
P = "x"
Q = "y"
R = "z"
result = curl(P, Q, R)
self.assertEqual(result, (0, 0, 0))
def UI():
while True:
command = input('请选择将要进行的操作1.第一类曲线积分 2.第二类曲线积分 3.第一类曲面积分 4.第二类曲面积分 5.环量计算 6.流量计算 7.散度计算 8.旋度计算 9.退出(所有积分区间请以元组或列表的形式给出)')
if command == '1':
r = input('请输入曲线的参数方程,以元组形式给出 (x(t), y(t)) 或 (x(t), y(t), z(t))')
t_range = input('请输入参数 t 的积分区间:')
function = input('请输入被积函数,用参数 t 表示:')
print('第一类曲线积分值:', first_kind_curve_integration(r, t_range, function))
if command == '2':
P = input('请输入向量场的 P 分量,用参数 t 表示:')
Q = input('请输入向量场的 Q 分量,用参数 t 表示:')
r = input('请输入曲线的参数方程,以元组形式给出 (x(t), y(t))')
t_range = input('请输入参数 t 的积分区间:')
print('第二类曲线积分值:', second_kind_curve_integration(P, Q, r, t_range))
if command == '3':
r = input('请输入曲面的参数方程,以元组形式给出 (x(u, v), y(u, v), z(u, v))')
u_range = input('请输入参数 u 的积分区间:')
v_range = input('请输入参数 v 的积分区间:')
function = input('请输入被积函数,用参数 u 和 v 表示:')
print('第一类曲面积分:', first_kind_surface_integration(r, u_range, v_range, function))
if command == '4':
P = input('请输入向量场的 P 分量,用参数 u 和 v 表示:')
Q = input('请输入向量场的 Q 分量,用参数 u 和 v 表示:')
R = input('请输入向量场的 R 分量,用参数 u 和 v 表示:')
r = input('请输入曲面的参数方程,以元组形式给出 (x(u, v), y(u, v), z(u, v))')
u_range = input('请输入参数 u 的积分区间:')
v_range = input('请输入参数 v 的积分区间:')
print('第二类曲面积分:', second_kind_surface_integration(P, Q, R, r, u_range, v_range))
if command == '5':
P = input('请输入向量场的 P 分量,用参数 t 表示:')
Q = input('请输入向量场的 Q 分量,用参数 t 表示:')
r = input('请输入曲线的参数方程,以元组形式给出 (x(t), y(t))')
t_range = input('请输入参数 t 的积分区间:')
print('环量:', circulation(P, Q, r, t_range))
if command == '6':
P = input('请输入向量场的 P 分量,用参数 u 和 v 表示:')
Q = input('请输入向量场的 Q 分量,用参数 u 和 v 表示:')
R = input('请输入向量场的 R 分量,用参数 u 和 v 表示:')
r = input('请输入曲面的参数方程,以元组形式给出 (x(u, v), y(u, v), z(u, v))')
u_range = input('请输入参数 u 的积分区间:')
v_range = input('请输入参数 v 的积分区间:')
print('流量:', flux(P, Q, R, r, u_range, v_range))
if command == '7':
P = input('请输入向量场的 P 分量,用 x, y, z 表示:')
Q = input('请输入向量场的 Q 分量,用 x, y, z 表示:')
R = input('请输入向量场的 R 分量,用 x, y, z 表示:')
print('散度:', divergence(P, Q, R))
if command == '8':
P = input('请输入向量场的 P 分量,用 x, y, z 表示:')
Q = input('请输入向量场的 Q 分量,用 x, y, z 表示:')
R = input('请输入向量场的 R 分量,用 x, y, z 表示:')
print('旋度:', curl(P, Q, R))
if command == '9':
break
if __name__ == "__main__":
UI()
unittest.main(exit=False)

@ -2,114 +2,92 @@ 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 get_domain(func_expr, var):
"""
确定函数的定义域针对常见问题如 ln(x), 1/x
:param func_expr: sympy 函数表达式
:param var: 自变量
:return: 有效定义域 (x_min, x_max)
"""
try:
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 extreme_value(function):
"""
计算函数的极值点和极值
:param function: 函数表达式
:return: 极值点与极值字典形式
:return: 极值点与极值
"""
function = convert_formula(function)
independent_variable, function = split_function(function)
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
independent_variable = symbols(independent_variable)
function = sympify(function)
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)}
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
def max_min(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: 泰勒展开式
"""
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 monotonicity(function):
"""
计算函数的单调性改进版支持超越方程输出易读格式
@ -120,64 +98,53 @@ 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) # 一阶导数
# 获取定义域
x_min, x_max = get_domain(func_expr, var)
# 转换为数值计算函数
deriv_num = lambdify(var, derivative, 'numpy')
# 转换为数值函数
try:
deriv_num = lambdify(var, derivative, 'numpy')
except Exception as e:
print(f"导数转换失败:{e}")
return [], []
# 区间扫描
step = 0.1
# 定义扫描参数(可根据实际函数调整)
x_min, x_max = -10, 10 # 扫描区间
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 = []
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
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
# 生成单调区间
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))
# 生成单调区间(数值均为普通浮点数)
up_intervals = []
down_intervals = []
current_sign = np.sign(deriv_num(x_min + 1e-6)) # 避免端点误差
start = float(round(x_min, 3)) # 转换为普通浮点数
for point in change_points:
if current_sign > 0:
up_intervals.append((start, point))
elif current_sign < 0:
else:
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))
elif current_sign < 0:
else:
down_intervals.append((start, end))
return up_intervals, down_intervals
@ -194,123 +161,55 @@ def aotu(function):
func_expr = sympify(function)
derivative = diff(func_expr, var, 2) # 二阶导数
# 获取定义域
x_min, x_max = get_domain(func_expr, var)
# 转换为数值计算函数
deriv_num = lambdify(var, derivative, 'numpy')
# 转换为数值函数
try:
deriv_num = lambdify(var, derivative, 'numpy')
except Exception as e:
print(f"二阶导数转换失败:{e}")
return [], []
# 区间扫描
step = 0.1
# 定义扫描参数(可根据实际函数调整)
x_min, x_max = -10, 10 # 扫描区间
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 = []
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
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
# 生成凹凸区间
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))
# 生成凹凸区间(数值均为普通浮点数)
ao_intervals = [] # 凹区间二阶导数≥0
tu_intervals = [] # 凸区间二阶导数≤0
current_sign = np.sign(deriv_num(x_min + 1e-6)) # 避免端点误差
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):
"""
计算函数在某一点的曲率
@ -388,17 +287,10 @@ 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)
if max_value is not None and min_value is not None:
print(f"最大值:{max_value:.4f},最小值:{min_value:.4f}")
else:
print("无法计算最大最小值,请检查函数定义域或表达式")
############################################## 修改 ##################################################
######################################################################################################
print(f"最大值:{max_value:.4f},最小值:{min_value:.4f}")
elif command == "3":
function = input("请输入函数表达式只支持形如f(x)=的表达式不支持y=的表达式)")
point = float(input("请输入自变量的取值点:"))

@ -1,147 +0,0 @@
from sympy import *
from convert_formula import *
from number_list_limitation import limitation
from sympy import cos, sin
def mi_grade_number_zone(formula):
"""
计算幂级数的收敛域
:param formula: 幂级数的通项系数
:return: 收敛域
"""
expression = 'abs((' + formula.replace('n', '(n+1)') + ')/' + formula + ')'
r = limitation(expression)[0]
if r == 0:
return '(-oo, oo)'
else:
border = [False, False]
grade_num = '(' + formula + ')*(1/%s)^n'%r
if limitation(grade_num)[1] == True:
border[1] = True
grade_num = '(' + formula + ')*(-1/%s)^n'%r
if limitation(grade_num)[1] == True:
border[0] = True
if border[0] == True and border[1] == True:
return '['+ str(-1/r) + ', ' + str(1/r) + ']'
elif border[0] == False and border[1] == False:
return '('+ str(-1/r) + ', ' + str(1/r) + ')'
elif border[0] == True and border[1] == False:
return '('+ str(-1/r) + ', ' + str(1/r) + ']'
elif border[0] == False and border[1] == True:
return '['+ str(-1/r) + ', ' + str(1/r) + ')'
def mi_grade_number_sum(formula):
"""
计算幂级数的和函数
:param formula: 幂级数的通项
:return: 幂级数的和函数
"""
series_expr = convert_formula(formula)
x = symbols('x')
series_expr = str(series_expr).replace('n', 'i')
series_expr = convert_formula(series_expr)
series_expr = sympify(series_expr)
i, n = symbols('i n')
partial_sum = simplify(summation(series_expr, (i, 1, n)))
if isinstance(partial_sum, Piecewise):
for expr, condition in partial_sum.args:
if condition == True:
partial_sum = expr
break
return partial_sum
def mi_grade_number_series(function, n, x0=0):
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 fuliye_grade_number(formula, T=2*pi):
"""
把函数展开成傅里叶级数
param formula: 函数表达式在(-T/2, T/2)上的表达式
param T: 周期
:return: 傅里叶级数展开式
"""
# 转换公式格式(复用现有工具函数)
formula = convert_formula(formula)
# 拆分自变量和函数表达式假设split_function来自convert_formula.py
independent_variable, function = split_function(formula)
# 符号化自变量和nn作为符号保留
x, t = symbols(f'{independent_variable} t')
n = symbols('n', integer=True, positive=True)
# 转换为sympy表达式
f = sympify(function)
# 构造傅里叶系数
a_0 = ((2/t) * integrate(f, (x, -t/2, t/2))).subs(t, T)
a_n = ((2/t) * integrate(f * cos(2 * n * x * pi / t), (x, -t/2, t/2))).subs(t, T)
b_n = ((2/t) * integrate(f * sin(2 * n * x * pi / t), (x, -t/2, t/2))).subs(t, T)
# 构造傅里叶级数
f_series = a_0/2 + Sum(a_n * cos(2 * n * pi * x / T) + b_n * sin(2 * n * pi * x / T), (n, 1, oo))
return f_series
def test():
"""
测试上述所有函数的测试函数
"""
# 导入必要的库
# 测试 mi_grade_number_zone 函数
formula_zone = 'n'
print("mi_grade_number_zone 测试结果:", mi_grade_number_zone(formula_zone))
# 测试 mi_grade_number_sum 函数
formula_sum = 'n*x**n'
print("mi_grade_number_sum 测试结果:", mi_grade_number_sum(formula_sum))
# 测试 mi_grade_number_series 函数
formula_series = 'f(x)=exp(x)'
print("mi_grade_number_series 测试结果:", mi_grade_number_series(formula_series, 10))
# 测试 fuliye_grade_number 函数
formula_fourier = 'f(x)=x'
print("fuliye_grade_number 测试结果:", fuliye_grade_number(formula_fourier))
def UI():
while True:
print("欢迎使用级数计算器")
print("1. 计算幂级数的收敛域")
print("2. 计算幂级数的和函数")
print("3. 计算幂级数的展开式")
print("4. 计算傅里叶级数展开式")
print("5. 退出")
choice = input("请输入您的选择1/2/3/4/5")
if choice not in ['1', '2', '3', '4', '5']:
print("无效选择,请重新输入!")
continue
if choice == '1':
formula_zone = input("请输入幂级数的通项的系数:")
print("幂级数的收敛域为:", mi_grade_number_zone(formula_zone))
elif choice == '2':
formula_sum = input("请输入幂级数的通项:")
print("幂级数的和函数为:", mi_grade_number_sum(formula_sum))
elif choice == '3':
formula_series = input("请输入函数表达式格式f(x)=...")
n = int(input("请输入展开的项数:"))
print("幂级数的展开式为:", mi_grade_number_series(formula_series, n))
elif choice == '4':
formula_fourier = input("请输入函数表达式格式f(x)=...")
T = input("请输入周期T为2π请留空")
if T == '':
T = 2*pi
else:
T = float(T)
print("傅里叶级数展开式为:", fuliye_grade_number(formula_fourier, T))
elif choice == '5':
print("谢谢使用,再见!")
break
if __name__ == "__main__":
test()
UI()

@ -1,149 +0,0 @@
import unittest
from numpy import *
from sympy import *
from convert_formula import *
def definite_calculation(function,upper,lower):
"""
定积分计算
:param function: 被积函数
:param upper: 积分上限
:param lower: 积分下限
:return: 定积分值
"""
function= sympify(convert_formula(function))
x= symbols('x')
result= integrate(function, (x,lower,upper))
return float(result)
def variable_integral_calculation(function,upper,lower):
"""
变限积分计算
:param function: 被积函数
:param upper: 积分上限
:param lower: 积分下限
:return: 变限积分积分后函数
"""
function= sympify(convert_formula(function))
t,x= symbols('t x')
in_function= integrate(function, t)
if upper=='x':
num= in_function.subs(t,lower)
up=in_function.replace(t,x)
result=up-num
elif lower=='x':
num = in_function.subs(t, upper)
low = in_function.replace(t, x)
result = num - low
else:
return None
return result
def improper_integral_calculation(function,upper,lower):
"""
反常积分计算并判断敛散性
:param function: 被积函数
:param upper: 积分上限
:param lower: 积分下限
:return: 积分值
"""
function = sympify(convert_formula(function))
x = symbols('x')
in_function = integrate(function,x)
try:
if upper=='oo' and lower!= '-oo':
upper_num = limit(in_function, x, oo, dir="-")
lower_num = limit(in_function, x, lower, dir="+")
elif upper!='oo' and lower=='-oo':
upper_num = limit(in_function, x, upper, dir="-")
lower_num = limit(in_function, x, -oo, dir="+")
elif upper=='oo' and lower=='-oo':
upper_num = float(limit(in_function, x, oo, dir="-"))
lower_num = float(limit(in_function, x, -oo, dir="+"))
else:
in_function = integrate(function, x)
upper_num = in_function.subs(x,upper)
lower_num = in_function.subs(x,lower)
result = upper_num- lower_num
return result,True
except:
return None,False
class TestIntegralFunctions(unittest.TestCase):
def test_definite_integral(self):
"""测试定积分计算"""
# 测试案例1: ∫[0,1] x^2 dx = 1/3
self.assertEqual(definite_calculation('x^2', 1, 0), 1/3)
# 测试案例2: ∫[0,π] sin(x) dx = 2
self.assertEqual(definite_calculation('sin(x)', pi, 0), 2)
# 测试案例3: ∫[1,e] 1/x dx = 1
self.assertEqual(definite_calculation('1/x', E, 1), 1)
def test_variable_integral(self):
"""测试变限积分计算"""
x = symbols('x')
# 测试案例1: ∫[0,x] t dt = x^2/2
result = variable_integral_calculation('t', 'x', 0)
expected = x ** 2 / 2
self.assertEqual(simplify(result - expected), 0)
# 测试案例2: ∫[x,1] t^2 dt = 1/3 - x^3/3
result = variable_integral_calculation('t^2', 1, 'x')
expected = Rational(1, 3) - x ** 3 / 3
self.assertEqual(simplify(result - expected), 0)
def test_improper_integral(self):
"""测试反常积分计算"""
# 测试案例1: ∫[1,∞] 1/x^2 dx = 1 (收敛)
result, convergent = improper_integral_calculation('1/x^2', 'oo', 1)
self.assertEqual(result, 1)
self.assertTrue(convergent)
# 测试案例2: ∫[-∞,0] e^x dx = 1 (收敛)
result, convergent = improper_integral_calculation('exp(x)', 0, '-oo')
self.assertEqual(result, 1)
self.assertTrue(convergent)
# 测试案例3: ∫[-∞,∞] sin(x) dx (发散)
result, convergent = improper_integral_calculation('sin(x)', 'oo', '-oo')
self.assertIsNone(result)
self.assertFalse(convergent)
# 测试案例4: ∫[0,1] 1/sqrt(x) dx = 2 (收敛)
result, convergent = improper_integral_calculation('1/sqrt(x)', 1, 0)
self.assertEqual(result, 2)
self.assertTrue(convergent)
def UI():
while True:
command= input('请选择功能1.定积分计算2.变限积分计算3.反常积分计算和敛散性4.退出')
if command=='1':
function = input('请输入以x为变量的被积函数')
upper = input('请输入积分上限:')
lower = input('请输入积分下限:')
print('定积分积分结果:',definite_calculation(function, upper, lower))
elif command=='2':
function = input('请输入以t为变量的被积函数')
upper = input('请输入积分上限:')
lower = input('请输入积分下限:')
print('变限积分积分结果:',variable_integral_calculation(function, upper, lower))
elif command=='3':
function = input('请输入以x为变量的被积函数')
upper = input('请输入积分上限:')
lower = input('请输入积分下限:')
num,convergent= improper_integral_calculation(function,upper,lower)
print('反常积分的计算值:',num)
if convergent:
print('反常积分收敛')
else:
print('反常积分发散')
elif command=='4':
break
if __name__ == "__main__":
# 运行测试但不退出,允许后续代码执行
unittest.main(exit=False)
UI()

@ -1,70 +0,0 @@
import basic_operation as bo
import curvilinear_and_surface_integaration as ci
import differential_application as da
import differential_equation as de
import differential_integration as di
import function_limitation_continue as flc
import grade_number as gn
import integral_calculation as ic
import multiple_integration as mi
import number_list_limitation as nll
import reflect_function as rf
import analytic_geometry_of_space as agos
import multivariate_derivatives as md
def UI():
print("欢迎使用高等数学综合实用计算器")
while True:
print("请选择要使用的功能")
print("1.初等数学运算")
print("2.映射与函数")
print("3.数列极限与数值级数")
print("4.函数的极限与连续")
print("5.导数与不定积分")
print("6.导数的应用")
print("7.定积分及其应用")
print("8.常微分方程")
print("9.空间解析几何")
print("10.多元函数的导数及其应用")
print("11.重积分")
print("12.曲线积分与曲面积分")
print("13.幂级数与傅里叶级数")
print("0.退出")
choice = input("请输入您的选择:")
try:
choice = int(choice)
if choice == 0:
print("感谢使用,再见!")
break
elif choice == 1:
bo.UI()
elif choice == 2:
rf.UI()
elif choice == 3:
nll.UI()
elif choice == 4:
flc.UI()
elif choice == 5:
di.UI()
elif choice == 6:
da.UI()
elif choice == 7:
ic.UI()
elif choice == 8:
de.UI()
elif choice == 9:
agos.UI()
elif choice == 10:
md.UI()
elif choice == 11:
mi.UI()
elif choice == 12:
ci.UI()
elif choice == 13:
gn.UI()
else:
print("输入无效,请输入 0 - 13 之间的数字")
except ValueError:
print("输入无效,请输入有效的数字")
UI()

@ -1,300 +0,0 @@
#重积分:包括直角坐标、极坐标下二重积分的计算、直角坐标、柱坐标、球坐标下三重积分的计算等
import unittest
import sympy as sp
from convert_formula import *
import math
def rectangular_double_integration(region1, region2, function, integration_order=('y','x')):
var1, var2 = integration_order
lower1, upper1 = region1 # 直接使用符号表达式(可能包含外层变量)
lower2, upper2 = region2
function = sp.sympify(convert_formula(function))
x, y = sp.symbols('x y')
# 根据积分顺序动态选择积分变量
if var1 == 'y' and var2 == 'x':
integration1 = sp.integrate(function, (y, lower1, upper1)) # 内层积分限可包含x
result = sp.integrate(integration1, (x, lower2, upper2))
elif var1 == 'x' and var2 == 'y':
integration1 = sp.integrate(function, (x, lower1, upper1)) # 内层积分限可包含y
result = sp.integrate(integration1, (y, lower2, upper2))
else:
raise ValueError('积分顺序仅支持("y","x")或("x","y")')
return result
def polar_double_integration(function, rou_region, theta_region, integration_order=('rou','theta')):
var1, var2 = integration_order
function = sp.sympify(convert_formula(function)) * sp.symbols('rou') # 极坐标雅可比行列式
rou, theta = sp.symbols('rou theta')
# 根据顺序动态积分
if var1 == 'rou' and var2 == 'theta':
inner = sp.integrate(function, (rou, *rou_region))
result = sp.integrate(inner, (theta, *theta_region))
elif var1 == 'theta' and var2 == 'rou':
inner = sp.integrate(function, (theta, *theta_region))
result = sp.integrate(inner, (rou, *rou_region))
else:
raise ValueError('积分顺序仅支持("rou","theta")或("theta","rou")')
return result
def rectangular_triple_integration(region1, region2, region3, function, integration_order=('z','y','x')):
var1, var2, var3 = integration_order
function = sp.sympify(convert_formula(function))
x, y, z = sp.symbols('x y z')
# 动态构建积分变量元组
vars = {'x':x, 'y':y, 'z':z}
regions = {var1: region1, var2: region2, var3: region3}
# 按顺序嵌套积分
inner = sp.integrate(function, (vars[var1], *regions[var1]))
middle = sp.integrate(inner, (vars[var2], *regions[var2]))
result = sp.integrate(middle, (vars[var3], *regions[var3]))
return result
def cylindrical_triple_integration(function, z_region, rou_region, theta_region, integration_order=('z','rou','theta')):
var1, var2, var3 = integration_order
function = sp.sympify(convert_formula(function)) * sp.symbols('rou') # 柱坐标雅可比行列式rou
z, rou, theta = sp.symbols('z rou theta')
# 动态映射积分变量与区域
vars = {'z': z, 'rou': rou, 'theta': theta}
regions = {var1: z_region, var2: rou_region, var3: theta_region}
# 按顺序嵌套积分
inner = sp.integrate(function, (vars[var1], *regions[var1]))
middle = sp.integrate(inner, (vars[var2], *regions[var2]))
result = sp.integrate(middle, (vars[var3], *regions[var3]))
return result
def spherical_triple_integration(function, r_region, phi_region, theta_region, integration_order=('r','phi','theta')):
var1, var2, var3 = integration_order
function = sp.sympify(convert_formula(function)) * (sp.symbols('r')**2) * sp.sin(sp.symbols('phi')) # 球坐标雅可比行列式r²sinφ
r, phi, theta = sp.symbols('r phi theta')
# 动态映射积分变量与区域
vars = {'r': r, 'phi': phi, 'theta': theta}
regions = {var1: r_region, var2: phi_region, var3: theta_region}
# 按顺序嵌套积分
inner = sp.integrate(function, (vars[var1], *regions[var1]))
middle = sp.integrate(inner, (vars[var2], *regions[var2]))
result = sp.integrate(middle, (vars[var3], *regions[var3]))
return result
def spherical_triple_integration(rou, theta, gamma, function):
"""
求球坐标下三重积分值
:param rou: ρ的积分区域(以元组或列表形式给出)
:param theta: θ的积分区间(以元组或列表形式给出)
:param gamma: γ的积分区间(以元组或列表形式给出)
:param function: 被积函数(以柱坐标形式给出)
:return: 三重积分值
"""
rou1, rou2 = rou[0], rou[1]
theta1, theta2 = theta[0], theta[1]
gamma1, gamma2 = gamma[0], gamma[1]
function = sp.sympify(convert_formula(function))
rou, theta, gamma = sp.symbols('rou theta gamma')
function = function * rou**2
integration1 = sp.integrate(function, (rou, rou1, rou2))
integration1 = integration1* sp.sin(theta)
integration2 = sp.integrate(integration1, (theta, theta1, theta2))
result = sp.integrate(integration2, (gamma, gamma1, gamma2))
return result
class TestIntegralFunctions(unittest.TestCase):
def test_rectangular_double_integration(self):
"""测试直角坐标系下的二重积分"""
# 测试案例1: ∫∫(x^2 + y^2) dxdy其中 x∈[0,1], y∈[0,1] = 2/3
result = rectangular_double_integration(
region1=(0, 1),
region2=(0, 1),
function="x^2 + y^2"
)
self.assertEqual(float(result), 2/3)
# 测试案例2: ∫∫1 dxdy其中 x∈[0,2], y∈[0,3] = 6
result = rectangular_double_integration(
region1=(0, 3),
region2=(0, 2),
function="1"
)
self.assertEqual(result, 6)
def test_polar_double_integration(self):
"""测试极坐标系下的二重积分"""
# 测试案例1: ∫∫(r) rdrdθ其中 r∈[0,1], θ∈[0,2π] = π
result = polar_double_integration(
function="rou",
rou=(0, 1),
theta=(0, 2*math.pi)
)
self.assertEqual(result, 2*math.pi/3)
# 测试案例2: ∫∫(r^2) rdrdθ其中 r∈[0,2], θ∈[0,π] = 4π
result = polar_double_integration(
function="rou^2",
rou=(0, 2),
theta=(0, math.pi)
)
self.assertEqual(result, 4*math.pi)
def test_rectangular_triple_integration(self):
"""测试直角坐标系下的三重积分"""
# 测试案例1: ∫∫∫(x + y + z) dxdydz其中 x∈[0,1], y∈[0,1], z∈[0,1] = 3/2
result = rectangular_triple_integration(
region1=(0, 1),
region2=(0, 1),
region3=(0, 1),
function="x + y + z"
)
self.assertEqual(float(result), 3/2)
# 测试案例2: ∫∫∫1 dxdydz其中 x∈[0,1], y∈[0,2], z∈[0,3] = 6
result = rectangular_triple_integration(
region1=(0, 3),
region2=(0, 2),
region3=(0, 1),
function="1"
)
self.assertEqual(result, 6)
def test_cylindrical_triple_integration(self):
"""测试柱坐标系下的三重积分"""
# 测试案例1: ∫∫∫(r) r**2dzdrdθ其中 r∈[0,1], θ∈[0,2π], z∈[0,1] = π
result = cylindrical_triple_integration(
rou=(0, 1),
theta=(0, 2*math.pi),
region=(0, 1),
function="rou"
)
self.assertEqual(result, 2*math.pi/3)
# 测试案例2: ∫∫∫(z) rdzdrdθ其中 r∈[0,2], θ∈[0,π], z∈[0,1] = 2π
result = cylindrical_triple_integration(
rou=(0, 2),
theta=(0, math.pi),
region=(0, 1),
function="z"
)
self.assertEqual(result, math.pi)
def test_spherical_triple_integration(self):
"""测试球坐标系下的三重积分"""
# 测试案例1: ∫∫∫(r) r²sin(θ)drdθdφ其中 r∈[0,1], θ∈[0,π], φ∈[0,2π] = π
result = spherical_triple_integration(
rou=(0, 1),
theta=(0, math.pi),
gamma=(0, 2*math.pi),
function="rou"
)
self.assertEqual(result, math.pi)
# 测试案例2: ∫∫∫(1) r²sin(θ)drdθdφ其中 r∈[0,1], θ∈[0,π], φ∈[0,2π] = 4π/3
result = spherical_triple_integration(
rou=(0, 1),
theta=(0, math.pi),
gamma=(0, 2*math.pi),
function="1"
)
self.assertEqual(result, 4*math.pi/3)
def UI():
while True:
command = input('请选择将要进行的操作1.直角坐标下二重积分 2.极坐标下二重积分 3.直角坐标系下三重积分 4.柱坐标下三重积分 5.球坐标下三重积分 6.退出\n(所有积分区间请不要使用半开半闭区间的形式给出,积分顺序由内到外输入,极坐标、柱坐标、球坐标需在原函数上乘的雅戈比行列式已经自动传入,不要重复输入)')
if command=='1':
function = input('请输入被积函数:')
order = input('请输入积分顺序(格式:"y,x""x,y"默认y,x') or 'y,x'
var1, var2 = order.split(',') # 解析积分变量顺序
# 输入符号积分限(支持变量表达式如"x"、"2*y"
lower1 = sp.sympify(convert_formula(input(f'请输入{var1}的下限:')))
upper1 = sp.sympify(convert_formula(input(f'请输入{var1}的上限:')))
lower2 = sp.sympify(convert_formula(input(f'请输入{var2}的下限:')))
upper2 = sp.sympify(convert_formula(input(f'请输入{var2}的上限:')))
print('直角坐标系下二重积分值:', rectangular_double_integration(
region1=(lower1, upper1),
region2=(lower2, upper2),
function=function,
integration_order=tuple(order.split(','))
))
if command=='2':
function = input('请输入极坐标被积函数:')
order = input('请输入积分顺序(格式:"rou,theta""theta,rou"默认rou,theta') or 'rou,theta'
var1, var2 = order.split(',')
# 符号积分限输入
lower1 = sp.sympify(convert_formula(input(f'请输入{var1}的下限:')))
upper1 = sp.sympify(convert_formula(input(f'请输入{var1}的上限:')))
lower2 = sp.sympify(convert_formula(input(f'请输入{var2}的下限:')))
upper2 = sp.sympify(convert_formula(input(f'请输入{var2}的上限:')))
print('极坐标二重积分值:', polar_double_integration(
function=function,
rou_region=(lower1, upper1) if var1=='rou' else (lower2, upper2),
theta_region=(lower2, upper2) if var1=='rou' else (lower1, upper1),
integration_order=tuple(order.split(','))
))
if command=='3':
function = input('请输入被积函数:')
order = input('请输入积分顺序(格式:"z,y,x"或其他排列默认z,y,x') or 'z,y,x'
vars = order.split(',')
# 输入三个符号积分限
regions = [
(sp.sympify(convert_formula(input(f'请输入{vars[0]}的下限:'))),
sp.sympify(convert_formula(input(f'请输入{vars[0]}的上限:'))),),
(sp.sympify(convert_formula(input(f'请输入{vars[1]}的下限:'))),
sp.sympify(convert_formula(input(f'请输入{vars[1]}的上限:'))),),
(sp.sympify(convert_formula(input(f'请输入{vars[2]}的下限:'))),
sp.sympify(convert_formula(input(f'请输入{vars[2]}的上限:'))),)
]
print('直角坐标三重积分值:', rectangular_triple_integration(
function=function,
region1=regions[0],
region2=regions[1],
region3=regions[2],
integration_order=tuple(vars)
))
if command=='4':
function = input('请输入柱坐标被积函数:')
order = input('请输入积分顺序(格式:"z,rou,theta"或其他排列默认z,rou,theta') or 'z,rou,theta'
vars = order.split(',')
# 输入符号积分限(支持变量表达式)
regions = [
(sp.sympify(convert_formula(input(f'请输入{vars[0]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[0]}的上限r/phi/theta')))),
(sp.sympify(convert_formula(input(f'请输入{vars[1]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[1]}的上限r/phi/theta')))),
(sp.sympify(convert_formula(input(f'请输入{vars[2]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[2]}的上限r/phi/theta'))))
]
print('柱坐标三重积分值:', cylindrical_triple_integration(
function=function,
z_region=regions[0] if vars[0]=='z' else next(r for r in regions if vars.index(r[0].name) == 0),
rou_region=regions[1] if vars[1]=='rou' else next(r for r in regions if vars.index(r[1].name) == 1),
theta_region=regions[2] if vars[2]=='theta' else next(r for r in regions if vars.index(r[2].name) == 2),
integration_order=tuple(vars)
))
if command=='5':
function = input('请输入球坐标被积函数使用r,phi,theta')
order = input('请输入积分顺序(格式:"r,phi,theta"或其他排列默认r,phi,theta') or 'r,phi,theta'
vars = order.split(',')
# 输入符号积分限(支持变量表达式)
regions = [
(sp.sympify(convert_formula(input(f'请输入{vars[0]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[0]}的上限r/phi/theta')))),
(sp.sympify(convert_formula(input(f'请输入{vars[1]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[1]}的上限r/phi/theta')))),
(sp.sympify(convert_formula(input(f'请输入{vars[2]}的下限r/phi/theta'))),
sp.sympify(convert_formula(input(f'请输入{vars[2]}的上限r/phi/theta'))))
]
print('球坐标三重积分值:', spherical_triple_integration(
function=function,
r_region=regions[0] if vars[0]=='r' else next(r for r in regions if vars.index(r[0].name) == 0),
phi_region=regions[1] if vars[1]=='phi' else next(r for r in regions if vars.index(r[1].name) == 1),
theta_region=regions[2] if vars[2]=='theta' else next(r for r in regions if vars.index(r[2].name) == 2),
integration_order=tuple(vars)
))
if command=='6':
break
if __name__ == "__main__":
UI()
unittest.main(exit=False)

@ -1,212 +0,0 @@
import sympy
from sympy import symbols, limit, diff, Eq, solve
from convert_formula import convert_formula
def compute_limit(f, vars, points, direction=None):
"""
计算多元函数的重极限或累次极限
Args:
f (sympy.Expr): 待计算极限的多元函数表达式
vars (list[sympy.Symbol]): 函数中的变量列表[x, y]
points (list[float]): 极限点的坐标列表与vars顺序对应[1, 2]
direction (str, optional): 累次极限方向可选'x_first'先x后y'y_first'先y后x默认None表示计算重极限
Returns:
sympy.Expr: 计算得到的极限值
"""
if direction == 'x_first':
lim_x = limit(f, vars[0], points[0])
return limit(lim_x, vars[1], points[1])
elif direction == 'y_first':
lim_y = limit(f, vars[1], points[1])
return limit(lim_y, vars[0], points[0])
else:
return limit(f, *zip(vars, points))
def check_continuity(f, vars, points):
"""
检查多元函数在指定点的连续性极限值是否等于函数值
Args:
f (sympy.Expr): 待检查的多元函数表达式
vars (list[sympy.Symbol]): 函数中的变量列表
points (list[float]): 待检查点的坐标列表与vars顺序对应
Returns:
bool: 连续返回True不连续返回False
"""
f_value = f.subs(dict(zip(vars, points)))
lim = compute_limit(f, vars, points)
return Eq(lim, f_value)
def partial_derivative(f, vars_list):
"""
计算多元函数对指定变量列表的高阶偏导数按顺序求导
Args:
f (sympy.Expr): 待求导的多元函数表达式
vars_list (list[sympy.Symbol]): 求导的变量列表按求导顺序排列[x, y]表示先对x再对y求导
Returns:
sympy.Expr: 计算得到的高阶偏导数表达式
"""
return diff(f, *vars_list)
def total_differential(f, vars):
"""
计算多元函数的全微分表达式
Args:
f (sympy.Expr): 待计算全微分的多元函数
vars (list[sympy.Symbol]): 函数中的所有变量列表
Returns:
sympy.Expr: 全微分表达式如df = f_x*dx + f_y*dy
"""
diffs = [diff(f, var) for var in vars]
return sum(d * sympy.Derivative(var) for d, var in zip(diffs, vars))
def directional_derivative(f, vars, points, direction_vec):
"""
计算多元函数在指定点沿给定方向的方向导数
Args:
f (sympy.Expr): 待计算的多元函数
vars (list[sympy.Symbol]): 函数中的变量列表
points (list[float]): 计算点的坐标列表与vars顺序对应
direction_vec (list[float]): 方向向量[1, 1]表示45度方向
Returns:
float: 方向导数的数值结果
"""
grad = gradient(f, vars)
grad_val = [g.subs(dict(zip(vars, points))) for g in grad]
dir_unit = [v / sympy.sqrt(sum(d**2 for d in direction_vec)) for v in direction_vec]
return sum(g * d for g, d in zip(grad_val, dir_unit))
def gradient(f, vars):
"""
计算多元函数的梯度向量
Args:
f (sympy.Expr): 待计算的多元函数
vars (list[sympy.Symbol]): 函数中的变量列表[x, y]
Returns:
list[sympy.Expr]: 梯度向量各分量为对应变量的偏导数
"""
return [diff(f, var) for var in vars]
def find_extrema(f, vars):
"""
寻找多元函数的无条件极值点并判断极值类型
Args:
f (sympy.Expr): 待分析的多元函数
vars (list[sympy.Symbol]): 函数中的变量列表
Returns:
list[tuple[dict, str]]: 极值点信息列表每个元素为(极值点字典, 极值类型)
"""
critical_points = solve([diff(f, var) for var in vars], vars, dict=True)
hessian = sympy.hessian(f, vars)
extrema = []
for point in critical_points:
hess_val = hessian.subs(point)
eigvals = hess_val.eigenvals()
if all(v > 0 for v in eigvals):
extrema.append((point, '极小值'))
elif all(v < 0 for v in eigvals):
extrema.append((point, '极大值'))
else:
extrema.append((point, '鞍点'))
return extrema
def constrained_extrema(f, constraints, vars):
"""
使用拉格朗日乘数法求解带约束条件的极值问题
Args:
f (sympy.Expr): 目标函数待求极值的函数
constraints (list[sympy.Expr]): 约束条件列表[Eq(x**2+y**2, 1)]
vars (list[sympy.Symbol]): 函数中的变量列表
Returns:
list[dict]: 满足约束条件的极值点解包含拉格朗日乘子
"""
lambdas = symbols('lambda:' + str(len(constraints)))
lagrangian = f - sum(l * c for l, c in zip(lambdas, constraints))
equations = [diff(lagrangian, var) for var in vars] + constraints
variables = vars + list(lambdas)
solutions = solve(equations, variables, dict=True)
return solutions
def UI():
vars_dict = {'x': symbols('x'), 'y': symbols('y'), 'z': symbols('z')}
while True:
print("\n多元函数导数分析系统")
print("1. 计算重极限/累次极限")
print("2. 检查连续性")
print("3. 计算偏导数")
print("4. 计算全微分")
print("5. 计算方向导数")
print("6. 计算梯度")
print("7. 寻找无条件极值")
print("8. 求解条件极值")
print("0. 退出")
choice = input("请选择功能(0-8): ")
if choice == '0':
print("系统已退出")
break
try:
expr = convert_formula(input("请输入多元函数表达式(如x**2+y**2): "))
f = sympy.sympify(expr)
vars_list = list(f.free_symbols)
if choice in ['1','2','5','7']:
points = [float(p) for p in eval(input("请输入极限点/求值点坐标(用,分隔): "))]
if choice == '1':
direction = input("是否计算累次极限?(x_first/y_first/直接回车为重极限): ")
res = compute_limit(f, vars_list, points, direction)
print(f"计算结果: {res}")
elif choice == '2':
res = check_continuity(f, vars_list, points)
print(f"连续性判断: {res}")
elif choice == '3':
vars_input = input("请输入求偏导的变量名(用,分隔如x,y表示先对x再对y求导: ")
vars_list = [vars_dict.get(var.strip(), symbols(var.strip())) for var in vars_input.split(',')]
res = partial_derivative(f, vars_list)
print(f"偏导数结果: {res}")
elif choice == '4':
res = total_differential(f, vars_list)
print(f"全微分结果: {res}")
elif choice == '5':
dir_vec = [float(v) for v in eval(input("请输入方向向量(用,分隔): "))]
res = directional_derivative(f, vars_list, points, dir_vec)
print(f"方向导数结果: {res}")
elif choice == '6':
res = gradient(f, vars_list)
print(f"梯度结果: {res}")
elif choice == '7':
res = find_extrema(f, vars_list)
print(f"无条件极值点: {res}")
elif choice == '8':
constraints_expr = convert_formula(input("请输入约束条件表达式(用,分隔): "))
constraints = [sympy.sympify(c) for c in constraints_expr.split(',')]
res = constrained_extrema(f, constraints, vars_list)
print(f"条件极值解: {res}")
except Exception as e:
print(f"输入错误: {str(e)}")
if __name__ == '__main__':
UI()

@ -12,9 +12,8 @@ def xy_to_polar(formula):
formula = formula.replace('y', '(r*sin(theta))')
l = formula.split('=')
r, theta = symbols('r theta')
expr = sympify(l[0] + '-(' + l[1] + ')', evaluate=False)
left = trigsimp(radsimp(expand_trig(expr)))
return factor(left)
left = simplify(sympify(l[0]+'-('+l[1]+')'))
return left
def polar_to_xy(formula):
"""
@ -24,12 +23,11 @@ def polar_to_xy(formula):
"""
formula = convert_formula(formula)
formula = formula.replace('r', 'sqrt(x**2+y**2)')
formula = formula.replace('theta', 'atan2(y,x)') # 使用atan2替代arctan以处理全象限
formula = formula.replace('theta', 'arctan(y/x)')
l = formula.split('=')
x, y = symbols('x y')
expr = sympify(l[0] + '-(' + l[1] + ')', evaluate=False)
left = trigsimp(radsimp(expr.rewrite(sin))) # 重写为sin以优化三角表达式
return factor(left)
left = simplify(sympify(l[0]+'-('+l[1]+')'))
return left
def t_to_xy(xf, yf):
"""
@ -43,16 +41,12 @@ def t_to_xy(xf, yf):
xl = xf.split('=')
x, t = symbols('x t')
eq = Eq(sympify(xl[0]), sympify(xl[1]))
tl = solve(eq, t, domain=S.Reals)
if not tl:
raise ValueError("无法消去参数t")
# 选择最简单的解
t_solution = tl[0] if len(tl) == 1 else min(tl, key=lambda sol: len(str(sol)))
yf = yf.replace('t', str(t_solution))
tl = solve(eq, t)
yf = yf.replace('t', str(tl[0]))
yl = yf.split('=')
y = symbols('y')
y, t = symbols('y t')
eq2 = Eq(sympify(yl[0]), sympify(yl[1]))
return simplify(factor(eq2))
return eq2
def xy_to_t(formula):
"""
@ -64,12 +58,8 @@ def xy_to_t(formula):
l = formula.split('=')
x, y = symbols('x y')
eq = Eq(sympify(l[0]), sympify(l[1]))
l2 = solve(eq, y, domain=S.Reals)
if not l2:
raise ValueError("无法求解y")
# 选择最简单的解
y_solution = l2[0] if len(l2) == 1 else min(l2, key=lambda sol: len(str(sol)))
return Eq(y, factor(simplify(y_solution)))
l2 = solve(eq, y)
return l2
def t_to_polar(xf, yf):
"""
@ -89,45 +79,42 @@ def polar_to_t(formula):
:return: 参数方程
"""
xy = polar_to_xy(formula)
xy = str(xy) + '=0'
xy = str(xy)+'=0'
return xy_to_t(xy)
def UI():
while True:
fr = input("请选择输入方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程 q.退出: ")
if fr == "q":
break
fr = input("请选择输入方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程 q.退出")
if fr == "2":
xin = input("请输入x格式x=x(t): ")
yin = input("请输入y格式y=y(t): ")
xin = input("请输入x格式x=x(t)")
yin = input("请输入y格式y=y(t)")
elif fr == "q":
break
else:
forin = input("请输入方程: ")
to = input("请选择输出方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程: ")
forin = input("请输入方程")
to = input("请选择输出方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程")
if fr == to:
print("输入和输出的方程类型不能相同")
else:
try:
if fr == "1":
if to == "2":
print("x = t")
print("y =")
pprint(xy_to_t(forin))
elif to == "3":
pprint(Eq(xy_to_polar(forin), 0))
elif fr == "2":
if to == "1":
pprint(t_to_xy(xin, yin))
elif to == "3":
pprint(Eq(t_to_polar(xin, yin), 0))
elif fr == "3":
if to == "1":
pprint(Eq(polar_to_xy(forin), 0))
elif to == "2":
print("x = t")
print("y =")
pprint(polar_to_t(forin))
except Exception as e:
print(f"错误: {e}")
if fr == "1":
if to == "2":
print("x = x")
print("y = ")
pprint(xy_to_t(forin))
elif to == "3":
pprint(Eq(xy_to_polar(forin), 0))
elif fr == "2":
if to == "1":
pprint(t_to_xy(xin, yin))
elif to == "3":
pprint(Eq(t_to_polar(xin, yin), 0))
elif fr == "3":
if to == "1":
pprint(Eq(polar_to_xy(forin), 0))
elif to == "2":
print("x = x")
print("y = ")
pprint(polar_to_t(forin))
if __name__ == '__main__':
UI()

@ -1,4 +0,0 @@
sympy==1.14.0
matplotlib==3.10.3
numpy==2.2.6
scipy==1.16.0
Loading…
Cancel
Save