R语言积分代码仅当输入长度为15时运行正常的原因排查
问题解答:integrate与grad函数的长度匹配问题
原始代码与问题现象
初始代码
itc_1 <- function(t, x) { subout_1 <- dlnorm(t, 2.72 - x, 0.52) return(subout_1) } itc_2 <- function(t, x) { subout_2 <- 1 - plnorm(t, 2.72 - x, 0.52) return(subout_2) } itc_3 <- function(x, t) { subout_3 <- grad(itc_2, x = x, t = t) return(subout_3) } itc_4 <- function(t, x) { subout_4 <- -itc_3(x, t) * itc_2(t, x) return(subout_4) } integrate(f = itc_4, lower = 0, upper = Inf, x = seq(-2, 2, length.out = 15))
这段代码会输出错误:integral is probably divergent,但这不是关注重点。
修改x长度后的错误
将最后一行代码改为:
integrate(f = itc_4, lower = 0, upper = Inf, x = seq(-2, 2, length.out = 14))
会抛出错误:
Error in grad.default(itc_2, x = x, t = t) : grad assumes a scalar valued function.
调试发现itc_2某次输出长度为15,但未主动指定对象长度,需解释该现象原因。
原因解释
核心矛盾来自integrate的默认行为和grad的输入要求:
integrate的向量化调用:integrate为提升计算效率,会自动向被积函数itc_4传入多个t值(而非单个),默认传入的t数量通常为15左右——这就是itc_2输出长度为15的直接原因。R的循环补齐规则:
当传入的x长度为15时,itc_2(t, x)触发循环补齐:15个t和15个x一一对应计算,输出长度保持15。此时grad接收的输入x长度与itc_2输出长度匹配,能绕过grad的标量校验逻辑,勉强完成计算(最终积分发散是另一回事)。长度不匹配触发
grad报错:
当x长度为14时,循环补齐会让15个t重复匹配14个x,导致itc_2(t, x)输出长度为15,但grad尝试对长度14的x求导时,函数输出长度(15)和输入长度(14)不匹配,触发grad的核心校验逻辑,直接抛出报错信息。
总结:
integrate自动生成的t数量(约15)决定了itc_2的输出长度;x长度与t数量一致时,循环补齐让输入输出长度匹配,grad能运行;x长度与t数量不一致时,长度不匹配触发grad报错。
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

