You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia使用Optim包的Nelder Mead算法时出现DomainError报错问题

问题根源

你代码的DomainError来自效用函数中c_d的非整数次幂运算,你仅对consumption < 0的情况做了返回兜底,但没有处理c_d < 0的情况:

  • 你使用的NelderMead是无约束优化算法,迭代过程中会自动探索参数空间的所有区域,包括x[2](也就是传入的c_d)为负的区间
  • 当c_d < 0时,c_d^(1-0.88) = c_d^0.12属于负数的非整数次幂运算,在实数域无定义,直接触发DomainError,不会走到你后续的逻辑分支
    另外你当前用的zgrid数值更小,导致算法更容易探索到c_d为负的区间来最小化损失,所以才会在更换zgrid后复现报错。

修复方案

有两种常见的修复方式,你可以按需选择:

方案1:改用带边界约束的优化算法

直接限制优化变量c_a、c_d的下界为0,从根源上避免出现负数参数,代码修改如下:

using Optim

V = fill(1.0, (18,14,5))
agrid  = range(-2, stop=20, length=18)
dgrid  = range(0.01, stop=24, length=14)
zgrid  = [0.7739832502827438; 0.8797631785217791; 1.0; 1.1366695315439874; 1.2920176239404275]

function adj_utility(V,s_a,s_d,s_z,i_z,c_a,c_d)
    consumption = s_z + 1.0125*s_a + (1-0.018)*s_d - c_a - c_d - 0.05*(1-0.018)*s_d
    if consumption >= 0
        return (1/(1-2)) * ((   (consumption^0.88) * (c_d^(1-0.88))   )^(1-2))
    else
        return -99999999
    end
end

# 优化部分修改为带边界约束的版本
i_a = 1
i_d = 3
i_z = 1
utility_adj(x) = -adj_utility(V,agrid[i_a],dgrid[i_d],zgrid[i_z],i_z,x[1],x[2])
# 定义变量下界、上界,c_a和c_d都不能小于0
lower = [0.0, 0.0]
upper = [Inf, Inf]
# 用Fminbox包裹NelderMead实现带约束优化
result1 = optimize(utility_adj, lower, upper, [1.0, 1.0], Fminbox(NelderMead()))

方案2:补全判断逻辑,覆盖所有非法参数情况

在效用函数开头增加c_d >= 0的判断,只要任意参数非法直接返回兜底值:

function adj_utility(V,s_a,s_d,s_z,i_z,c_a,c_d)
    # 先判断所有参数是否合法
    if c_d < 0
        return -99999999
    end
    consumption = s_z + 1.0125*s_a + (1-0.018)*s_d - c_a - c_d - 0.05*(1-0.018)*s_d
    if consumption >= 0
        return (1/(1-2)) * ((   (consumption^0.88) * (c_d^(1-0.88))   )^(1-2))
    else
        return -99999999
    end
end

这种方式不需要修改优化算法,但无约束优化可能会多探索一些无效区域,收敛速度略慢于带约束的方案。

内容的提问来源于stack exchange,提问作者Chang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:36:08