如何在SymPy中合并同函数且区间衔接的未求值积分?
合并SymPy中同函数衔接区间的未求值积分
SymPy默认的.doit()、.expand()、.simplify()方法无法自动合并同函数、同变量且区间衔接的未求值积分求和项,比如无法直接将Integral(f(x), (x,a,b)) + Integral(f(x), (x,b,c))转换为Integral(f(x), (x,a,c))。可以通过自定义函数实现这一逻辑:
实现代码
from sympy import * x, a, b, c, d = symbols('x a b c d') f = Function('f') def combine_integrals(expr): # 将表达式拆分为单个加法项 terms = Add.make_args(expr) # 按「被积函数+积分变量」分组,同时保留非积分项 integral_groups = {} for term in terms: if isinstance(term, Integral): func = term.integrand var = term.variables[0] key = (func, var) if key not in integral_groups: integral_groups[key] = [] # 提取当前积分的上下限 lower, upper = term.limits[0][1], term.limits[0][2] integral_groups[key].append((lower, upper)) else: integral_groups.setdefault('non_integral', []).append(term) combined_terms = [] # 处理每组积分项 for key in integral_groups: if key == 'non_integral': combined_terms.extend(integral_groups[key]) continue func, var = key intervals = integral_groups[key] # 按区间下限排序,确保衔接顺序正确 intervals.sort(key=lambda x: x[0]) # 合并衔接的区间 merged_intervals = [] for interval in intervals: if not merged_intervals: merged_intervals.append(list(interval)) else: last_low, last_high = merged_intervals[-1] curr_low, curr_high = interval # 检查是否满足衔接条件:前一个积分的上限等于当前积分的下限 if last_high == curr_low: merged_intervals[-1][1] = curr_high else: merged_intervals.append(list(interval)) # 生成合并后的积分对象 for low, high in merged_intervals: combined_terms.append(Integral(func, (var, low, high))) return Add(*combined_terms) # 测试基础案例 int_sum = Integral(f(x), (x, a, b)) + Integral(f(x), (x, b, c)) print(combine_integrals(int_sum)) # 输出:Integral(f(x), (x, a, c)) # 测试多段衔接区间 int_multi = Integral(f(x), (x, a, b)) + Integral(f(x), (x, b, c)) + Integral(f(x), (x, c, d)) print(combine_integrals(int_multi)) # 输出:Integral(f(x), (x, a, d))
逻辑说明
- 分组归类:将所有积分项按「被积函数+积分变量」分组,确保只合并完全同类型的积分;
- 排序区间:对每组内的积分区间按下限排序,保证衔接顺序正确;
- 合并衔接区间:遍历排序后的区间,将前一个上限等于后一个下限的区间合并为一个大区间;
- 重组表达式:将合并后的积分和非积分项重新组合为最终表达式。
内容的提问来源于stack exchange,提问作者DeafIdiotGod
相关产品推荐
相关产品推荐

