integration API

integration 包使用 Gauss–Kronrod 求积法计算 Func_Math 在有限区间 [a,b][a, b] 上的定积分。它提供基本的 Gauss–Kronrod 求积公式、通过细分区间工作的自适应积分器,以及通过提高求积公式阶数工作的非自适应积分器。

Gauss–Kronrod 求积公式

kronrod_r15, kronrod_r21, kronrod_r31, kronrod_r41, kronrod_r51, kronrod_r61

每个函数在 [a,b][a, b] 上对 f 应用一个 Gauss–Kronrod 求积公式;名称中的数字是 Kronrod 节点数。

fn kronrod_r15((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)
fn kronrod_r21((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)
fn kronrod_r31((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)
fn kronrod_r41((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)
fn kronrod_r51((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)
fn kronrod_r61((Double) -> Double, Double, Double) -> (Double, Double, Double, Double)

结果是元组 (result, result_abs, result_asc, error):

值含义
resultf 的积分的 Kronrod 近似值。
result_abs对 ∣f∣\lvert f \rvert 应用同一求积公式的结果。
result_asc对 ∣f−fˉ∣\lvert f - \bar f \rvert 应用同一求积公式的结果,其中 fˉ\bar f 是 f 在区间上的平均值;它衡量 f 的变化程度。
errorKronrod 近似与内嵌 Gauss 近似之差,经 rescale_error 重新缩放。

每个求积公式的类型都是 basic 包中的 Quad_GK,因此可以传给 adap_quad_gk。

rescale_error

rescale_error 将两个求积近似值之间的原始差值转换为保守的误差估计。

fn rescale_error(Double, Double, Double) -> Double

当两者均非零时,rescale_error(err, result_abs, result_asc) 将 ∣err∣\lvert err \rvert 缩放为 result_asc⋅min⁡(1,(200∣err∣/result_asc)3/2)result\_asc \cdot \min(1, (200 \lvert err \rvert / result\_asc)^{3/2}),且返回值不小于 50 ε⋅result_abs50\,\varepsilon \cdot result\_abs,其中 ε\varepsilon 是 Double 的机器精度。这是 QUADPACK 的误差启发式方法。

积分器

adap_quad_gk

adap_quad_gk 在 [a,b][a, b] 上自适应地对 f 积分:它不断二分误差最大的子区间,直到总误差满足容差。

fn adap_quad_gk((Double) -> Double, ((Double) -> Double, Double, Double) -> (Double, Double, Double, Double), Double, Double, Double, Double, Int) -> Result[(Double, Double, ErrCode), ErrCode]

adap_quad_gk(f, q, a, b, epsabs, epsrel, limit) 对每个子区间应用求积公式 q(例如 kronrod_r21)。当估计的绝对误差不超过 max⁡(epsabs,epsrel⋅∣I∣)\max(epsabs, epsrel \cdot \lvert I \rvert) 时计算成功结束,其中 II 为当前的积分估计值。limit 是子区间的最大数量。

成功时结果为 Ok((integral, error, OK)),否则为 Err(code):

代码原因
E_BAD_TOLepsabs 不为正,且 epsrel 小于机器精度或 0.5⋅10−280.5 \cdot 10^{-28}。
E_ROUND舍入误差使得无法达到所要求的容差。
E_SINGULARITY某个子区间已小到无法再二分,这表明被积函数可能存在奇点或剧烈振荡。
E_MAX_ITER在达到容差之前已用完 limit 个子区间。

non_adap_quad_gk

non_adap_quad_gk 使用阶数递增的 Gauss–Kronrod 求积公式在 [a,b][a, b] 上对 f 积分,不细分区间。

fn non_adap_quad_gk((Double) -> Double, Double, Double, Double, Double) -> Result[(Double, Double, Int), ErrCode]

non_adap_quad_gk(f, a, b, epsabs, epsrel) 依次尝试 21 点、43 点和 87 点求积公式,一旦估计误差小于 epsabs 或小于 epsrel 乘以结果的绝对值便立即返回。结果为 Ok((integral, error, neval)),其中 neval 是所用的函数求值次数(21、43 或 87)。容差非法时(与 adap_quad_gk 相同)结果为 Err(E_BAD_TOL);即使 87 点公式也达不到容差时结果为 Err(E_FAILED)。

// Integrate x^2 from 0 to 1 (exact answer: 1/3)
let f = fn(x) { x * x }
match non_adap_quad_gk(f, 0.0, 1.0, 0.0000000001, 0.0000000001) {
  Ok((result, error, neval)) =>
    println("Integral: \{result}, Error: \{error}, Evaluations: \{neval}")
  Err(code) => println("Integration failed with error: \{code}")
}

错误码

ErrCode

ErrCode 报告积分的结果状态。

pub(all) enum ErrCode {
  OK
  E_ROUND
  E_SINGULARITY
  E_MAX_ITER
  E_FAILED
  E_BAD_TOL
} derive(Eq)
构造器含义
OK积分成功。
E_ROUND出现意外的舍入误差。
E_SINGULARITY被积函数可能存在奇点或剧烈振荡。
E_MAX_ITER已达到最大细分次数。
E_FAILED一般性失败。
E_BAD_TOL容差参数非法。

ErrCode 实现了 Eq,因此可以将结果码与构造器进行比较。