scipy.integrate.trapz 和不连续函数

scipy.integrate.trapz and discontinuous functions

函数 scipy.integrate.trapz 使用 1 阶 Newton-Cotes 公式,如 scipy 文档中所述。但是,在这个公式的推导中,通常假设

但是,我尝试通过调用

来近似由 f(x) = 0 if x < 1 else 2 定义的函数 f:[0,2] --> [0,2] 的积分
scipy.integrate.trapz([0, 0, 2, 2], [0, 1, 1, 2])

并获得了正确的结果 (2.0)。在上层调用中,

Can this "hack" be safely used in the way presented in the example?

(对于每个不连续点x,在点列表中插入两次x,并将被积函数的左右极限插入值列表中的相应位置。 )

trapz 中重复 x 值的效果与在该值处拆分积分区间,并将 trapz 分别应用于每个部分的效果相同:

from scipy.integrate import trapz
trapz([0, 0, 2, 2], [0, 1, 1, 2])
trapz([0, 0], [0, 1]) + trapz([2, 2], [1, 2])

两个结果是一样的。事实上,整合像你这样的分段函数的最好方法是在不连续处分割积分区间,因为这样你就整合了两个连续函数。你的做法是正确的。

理论知识

从某种意义上说,您的 "hack" 不是必需的。梯形法则收敛到任何黎曼可积函数的正确积分值,涵盖所有分段连续函数等。一本教科书只给出连续函数的证明是教科书作者的选择,希望有一个更简单的证明。可以证明一个更一般的定理。

也就是说,对于实践中出现的任何函数,梯形法则的输出将接近其积分,前提是 x 值形成积分区间的足够精细的划分。例如,如果您采用足够多的点,均匀间隔的点将始终有效。

然而,在实践中人们关心收敛速度,当函数具有不连续性时收敛速度明显变差。从这个实际的角度来看,包括每个不连续点两次,以 y 值作为左右限制,对梯形规则的准确性有显着提高。