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

如何正确使用SymPy求解方程?关于nsolve初始猜测的疑问

使用SymPy求解折现方程的正确方法

先修正方程表达式

你的原始方程存在括号缺失问题,导致表达式和实际要计算的折现现金流(NPV=0)逻辑不符。比如cf[0]/1+x实际应为cf[0]/(1+x),最后一项的(cf[4]+(cf[5]/x))/1+x**5应为(cf[4] + cf[5]/x)/(1+x)**5(对应第5期的现金流加永续年金的现值折现)。修正后的代码:

from sympy import symbols, Eq, solve, nsolve, re, im

index = 3586

cf = [202.31091967441085,
 215.90288600761673,
 230.4080089272309,
 245.88763753689724,
 262.4072425909973,
 272.4574399822326]

x = symbols('x')
# 修正后的NPV=0方程
eq1 = Eq(
    -index + 
    cf[0]/(1+x) + 
    cf[1]/(1+x)**2 + 
    cf[2]/(1+x)**3 + 
    cf[3]/(1+x)**4 + 
    (cf[4] + cf[5]/x)/(1+x)**5,
    0
)

方法一:用solve筛选有效解

solve会返回所有代数解(包括复数和负实数),可根据业务场景(折现率为正实数)筛选:

sol = solve(eq1)
# 筛选虚部为0、实部大于0的解
valid_sols = [s for s in sol if im(s) == 0 and re(s) > 0]
print(valid_sols)
# 输出:[0.104472587998023]

方法二:用nsolve稳定求解

nsolve是数值迭代法,会收敛到离初始猜测最近的根。要避免收敛到错误解,推荐指定搜索区间而非单点猜测:

# 指定x在(0,1)区间内搜索(折现率通常在0到1之间)
res = nsolve(eq1, x, (0, 1))
print(res)
# 输出:0.104472587998023

如果需要单点猜测,可先通过绘图确定根的大致位置:

from sympy import plot
# 绘制x在0到0.2区间的函数图像,观察和x轴交点
plot(eq1.lhs, (x, 0, 0.2))

从图像能看到根在0.1附近,设置初始猜测为0.1左右即可稳定收敛到正确解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:35:15