黎曼积分:分块求和逼近

package main

import (
    "fmt"
    "math"
)

// 黎曼和(左端点)
func riemannLeft(f func(float64) float64, a, b float64, n int) float64 {
    h := (b - a) / float64(n)
    sum := 0.0
    for i := 0; i < n; i++ {
        sum += f(a + float64(i)*h)
    }
    return sum * h
}

// 梯形法则(精度更高:O(h²))
func trapezoid(f func(float64) float64, a, b float64, n int) float64 {
    h := (b - a) / float64(n)
    sum := (f(a) + f(b)) / 2
    for i := 1; i < n; i++ {
        sum += f(a + float64(i)*h)
    }
    return sum * h
}

// 辛普森法则(精度:O(h⁴))
func simpson(f func(float64) float64, a, b float64, n int) float64 {
    if n%2 != 0 { n++ }  // n 必须是偶数
    h := (b - a) / float64(n)
    sum := f(a) + f(b)
    for i := 1; i < n; i++ {
        if i%2 == 0 {
            sum += 2 * f(a+float64(i)*h)
        } else {
            sum += 4 * f(a+float64(i)*h)
        }
    }
    return sum * h / 3
}

func main() {
    // 计算 ∫₀¹ x² dx = 1/3 ≈ 0.333333
    f := func(x float64) float64 { return x * x }
    fmt.Printf("黎曼左端: %.6f\n", riemannLeft(f, 0, 1, 1000))
    fmt.Printf("梯形法则: %.6f\n", trapezoid(f, 0, 1, 1000))
    fmt.Printf("辛普森法: %.6f\n", simpson(f, 0, 1, 100))
    fmt.Printf("精确值:   %.6f\n", 1.0/3)

    // ∫₀^π sin(x) dx = 2(经典)
    fmt.Printf("∫sin = %.6f(应为 2.0)\n", simpson(math.Sin, 0, math.Pi, 100))
}

概率分布:PDF 与 CDF

概率密度函数(PDF)的积分是累积分布函数(CDF):CDF(x) = ∫_{-∞}^{x} PDF(t) dt。正态分布没有解析的 CDF,只能数值积分。这就是为什么误差函数 erf 是很多数学库的核心函数。

package main

import (
    "fmt"
    "math"
)

// 标准正态分布的 PDF
func normalPDF(x float64) float64 {
    return math.Exp(-x*x/2) / math.Sqrt(2*math.Pi)
}

// 数值近似 CDF(标准正态)
func normalCDF(x float64) float64 {
    return (1 + math.Erf(x/math.Sqrt2)) / 2
}

func main() {
    // P(-1 < X < 1) ≈ 68.27%(经验法则)
    p := normalCDF(1) - normalCDF(-1)
    fmt.Printf("P(-1σ < X < 1σ) = %.4f%%\n", p*100)  // 68.27%

    // P(-2 < X < 2) ≈ 95.45%
    p2 := normalCDF(2) - normalCDF(-2)
    fmt.Printf("P(-2σ < X < 2σ) = %.4f%%\n", p2*100)  // 95.45%

    // 数值积分验证 PDF 总面积 = 1
    total := 0.0
    h := 0.001
    for x := -10.0; x < 10.0; x += h {
        total += normalPDF(x) * h
    }
    fmt.Printf("PDF 总面积 = %.6f(应为 1.0)\n", total)
}

蒙特卡洛积分:高维场景

梯形法、辛普森法在高维时遭遇维数灾难:d 维积分需要 n^d 个采样点。蒙特卡洛积分用随机采样,误差是 O(1/√n),与维数无关。这是机器学习、物理模拟、期权定价里高维积分的标准方法。

推荐做法
  • 低维精确积分用辛普森法(4 阶精度)
  • 高维或复杂区域用蒙特卡洛积分
  • 用微积分基本定理验证数值结果:F(b)-F(a)
不推荐
  • 用黎曼左端点法——梯形法精度更高,代码复杂度相同
  • 对奇异函数(有间断点)直接数值积分——需要先处理奇异点
常见误区
  • 辛普森法要求 n 是偶数,否则公式不成立

判断标准:能解释 PDF 和 CDF 的关系,并用数值积分验证正态分布 68-95-99.7 法则 → 掌握本章。

积分是数学对「无限细分再求和」这件事的尊重——它把极限变成了精确的工具。

— 本课笔记