Go Gonum Hermite 求积为什么包含权函数约定
如果你在 Go Gonum 里看到 quad.Hermite{} 的示例,却疑惑为什么调用时必须给出负无穷到正无穷的区间,关键不在参数写法,而在这条规则已经把高斯型权函数写进了数学约定。Hermite 近似的是 ∫[-∞,+∞] e^(-x²) f(x) dx,其中 f(x) 是你传给 quad.Fixed 的剩余函数。
Hermite 不是普通的“全实数区间积分器”。它负责节点、权重和e^(-x²)权函数的组合;代码里只应传入权函数之外的部分,并把上下限写成math.Inf(-1)与math.Inf(1)。
官方地址:https://pkg.go.dev/gonum.org/v1/gonum/integrate/quad
本文按一个常见排障现场展开:先确认 Hermite 到底计算什么,再给出可直接套用的 Go 写法,最后说明标准正态期望怎样做变量变换,以及结果不对时应该先查哪三项。
先把 Hermite 的“权”看成契约
Gonum 的 quad.Fixed 把固定节点求积抽象成“节点 xᵢ、权重 wᵢ 和函数值 f(xᵢ) 的加权和”。对于 Hermite 规则,官方文档把目标写成:
∫[-∞,+∞] e^(-x²) f(x) dx ≈ Σ wᵢ f(xᵢ)
因此权重并不是一组与区间无关的普通采样系数。它们是为平方指数权函数准备的,节点也分布在整个实数轴上。把它拿去理解有限区间上的无权积分,或者在 f 里再乘一次 e^(-x²),都会改变你实际近似的对象。

上下限为什么必须是负无穷和正无穷
Hermite.FixedLocations 会检查传入的边界:min 必须是负无穷,max 必须是正无穷。这个检查不是形式主义,它保证调用方使用的是 Hermite 规则对应的整个实数轴。如果写成 0 到 1,即使函数本身只在这段区间有意义,也不应继续使用 Hermite;应改用适合有限区间的规则,例如 quad.Legendre{}。
package main
import (
"fmt"
"math"
"gonum.org/v1/gonum/integrate/quad"
)
func main() {
// Hermite 只负责 e^(-x²) 之外的函数部分;这里计算 x² + 1。
f := func(x float64) float64 {
return x*x + 1
}
// Hermite 的区间契约是整个实数轴,样本数必须为正。
value := quad.Fixed(f, math.Inf(-1), math.Inf(1), 16, quad.Hermite{}, 0)
fmt.Printf("integral = %.8f\n", value)
}
这个调用对应的数学对象是 ∫e^(-x²)(x²+1)dx,而不是 ∫(x²+1)dx。最后一个参数是并发评估数;传入 0 表示串行计算,适合先把求积语义讲清楚。
函数里不要再次乘一遍权函数
最容易出现的误差是把“目标积分的完整被积函数”直接交给 Hermite。假设目标本来就是 ∫e^(-x²)q(x)dx,正确写法是传 q。如果把 e^(-x²)q(x) 作为 f,Hermite 的权重还会再贡献一次指数因子,实际求到的是 ∫e^(-2x²)q(x)dx。
// 正确:把权函数之外的 q(x) 交给 Hermite。
q := func(x float64) float64 {
return x*x + 2
}
value := quad.Fixed(q, math.Inf(-1), math.Inf(1), 32, quad.Hermite{}, 0)
// 错误示意:这会把 e^(-x²) 乘进 Hermite 已经约定的权重,导致权函数重复。
wrong := func(x float64) float64 {
return math.Exp(-x*x) * q(x)
}
_ = value
_ = wrong
这里的判断可以记成一句话:先把目标积分写成 e^(-x²) × 剩余函数,再把“剩余函数”作为 Go 闭包传入。不要因为示例中的闭包叫 f,就把完整被积函数机械地塞进去。
标准正态期望要先做一次变量变换
Hermite 的权函数是 e^(-x²),标准正态密度却是 1/√(2π)e^(-z²/2)。令 z=√2x,就得到:
E[g(Z)] = 1/√π ∫[-∞,+∞] e^(-x²) g(√2x) dx
所以 Go 代码里应当把 g 改写成 g(√2x),调用 Hermite 后再除以 √π。这个缩放因子属于变量变换,不属于 Hermite 权重本身。

package main
import (
"fmt"
"math"
"gonum.org/v1/gonum/integrate/quad"
)
func main() {
// g 描述标准正态变量 Z 上真正关心的函数。
g := func(z float64) float64 {
return z*z + 2
}
// 变量变换 z = sqrt(2) * x,把 g 放到 Hermite 的剩余函数位置。
transformed := func(x float64) float64 {
return g(math.Sqrt2 * x)
}
// Hermite 先给出带 e^(-x²) 权的积分,再除以 sqrt(pi) 得到期望。
integral := quad.Fixed(transformed, math.Inf(-1), math.Inf(1), 32, quad.Hermite{}, 0)
expectation := integral / math.Sqrt(math.Pi)
fmt.Printf("E[g(Z)] = %.8f\n", expectation)
}
结果不符合预期时先看这张表
| 现象 | 优先检查 | 对应判断 |
|---|---|---|
| 调用直接 panic | 上下限是否为 -Inf、+Inf,样本数是否大于 0 | Hermite 的区间和样本数契约未满足 |
| 结果比预期小很多 | 是否在闭包里重复乘了 e^(-x²) | 权函数可能被重复计算 |
| 标准正态期望整体偏一个常数比例 | 是否做了 z=√2x,并除以 √π | 变量变换的缩放因子遗漏 |
| 样本数增加后仍不稳定 | 函数是否在节点附近平滑、是否真的适合全实数区间 | 规则选择或被积函数形态可能不匹配 |
样本数 n 只改变 Hermite 节点和权重的数量,并不会把规则变成有限区间积分器。对于边界有限、没有平方指数权函数的目标,先重新选择规则,再谈增加采样点。
最后的判断方式
遇到“为什么 Hermite 求积包含权函数”的疑问,可以按三层判断:第一层看目标积分能否写成 e^(-x²)f(x);第二层看区间是否确实是整个实数轴;第三层看是否把变量变换的常数因子留在了 Hermite 调用之外。三层都匹配时,quad.Fixed 的调用就只是在执行 Gonum 文档定义的节点加权和。
Hermite 可以直接算有限区间吗?
不应这样用。Hermite 的实现要求边界为负无穷和正无穷;有限区间应选择与目标区间及权函数匹配的规则。
Hermite 权重是不是普通采样权重?
不是。它们和 e^(-x²) 的权函数约定绑定,用来近似带该权函数的全实数积分。
为什么正态期望还要除以平方根 pi?
因为 z=√2x 把标准正态密度转换成 1/√π · e^(-x²);除以 √π 是密度归一化后的常数因子。
Go Gonum quad 怎样计算有限区间上的定点数值积分
- 上一篇
- Go Gonum quad 怎样计算有限区间上的定点数值积分
- 下一篇
- Go Gonum interp 怎样拟合分段线性插值器
-
- Golang · Go问答 | 30分钟前 |
- Go go-pretty 的分页大小与实际数据行数有什么区别
- 434浏览 收藏
-
- Golang · Go问答 | 36分钟前 |
- Go uniseg 分段函数的 state 为什么需要传回下一次调用
- 414浏览 收藏
-
- Golang · Go问答 | 40分钟前 |
- Go go-i18n 多个语言偏好参数怎样决定匹配结果
- 266浏览 收藏
-
- Golang · Go问答 | 45分钟前 |
- Go jsonschema 的 format 为什么不总是强制断言
- 188浏览 收藏
-
- Golang · Go问答 | 56分钟前 |
- Go Kong 的 passthrough 参数为什么保留后续原始输入
- 284浏览 收藏
-
- Golang · Go问答 | 59分钟前 | go · 排错 · Go Dijkstra 负权重边 Gonum BellmanFord
- Go Gonum Dijkstra 为什么不能处理负权重边
- 222浏览 收藏
-
- Golang · Go问答 | 1小时前 | 数据校验 · Go教程 · Go 插值 Gonum interp 横坐标 严格递增 PiecewiseLinear NaturalCubic
- Go Gonum 插值的横坐标为什么必须严格递增
- 173浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go Gonum 分布的 Prob 与 CDF 有什么区别
- 457浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 797次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 789次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 877次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 847次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 678次使用
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- Go generate 未执行指令的注释与目录检查
- 2026-10-28 501浏览
-
- Go RWMutex 写锁等待过久的竞争分析
- 2026-10-28 501浏览
-
- Go os.File.ReadAt 为什么到文件末尾仍返回部分数据
- 2026-10-26 501浏览

