integration API
integration 包使用 Gauss–Kronrod 求积法计算 Func_Math 在有限区间 上的定积分。它提供基本的 Gauss–Kronrod 求积公式、通过细分区间工作的自适应积分器,以及通过提高求积公式阶数工作的非自适应积分器。
Gauss–Kronrod 求积公式
kronrod_r15, kronrod_r21, kronrod_r31, kronrod_r41, kronrod_r51, kronrod_r61
每个函数在 上对 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):
| 值 | 含义 |
|---|---|
result | f 的积分的 Kronrod 近似值。 |
result_abs | 对 应用同一求积公式的结果。 |
result_asc | 对 应用同一求积公式的结果,其中 是 f 在区间上的平均值;它衡量 f 的变化程度。 |
error | Kronrod 近似与内嵌 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) 将 缩放为 ,且返回值不小于 ,其中 是 Double 的机器精度。这是 QUADPACK 的误差启发式方法。
积分器
adap_quad_gk
adap_quad_gk 在 上自适应地对 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)。当估计的绝对误差不超过 时计算成功结束,其中 为当前的积分估计值。limit 是子区间的最大数量。
成功时结果为 Ok((integral, error, OK)),否则为 Err(code):
| 代码 | 原因 |
|---|---|
E_BAD_TOL | epsabs 不为正,且 epsrel 小于机器精度或 。 |
E_ROUND | 舍入误差使得无法达到所要求的容差。 |
E_SINGULARITY | 某个子区间已小到无法再二分,这表明被积函数可能存在奇点或剧烈振荡。 |
E_MAX_ITER | 在达到容差之前已用完 limit 个子区间。 |
non_adap_quad_gk
non_adap_quad_gk 使用阶数递增的 Gauss–Kronrod 求积公式在 上对 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,因此可以将结果码与构造器进行比较。