#重积分:包括直角坐标、极坐标下二重积分的计算、直角坐标、柱坐标、球坐标下三重积分的计算等 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)