我有一个简单的非线性优化项目。我想找到未来现金流和终值的贴现率,以便总和等于指定的 NPV。以下是我尝试过的一些实验。
两家公司的固定现金流均为10,净现值不同。贴现率结果应分别为 1.074 (7.4%( 和 1.052 (5.2%(。Excel Solver 很快找到了根源,而 Scipy 返回了 NoConvergence。
import numpy as np
from scipy.optimize import newton_krylov
from scipy.optimize.nonlin import NoConvergence
cf_fy1 = [10]*2
cf_fy2 = [10]*2
cf_fy3 = [10]*2
cf_fy4 = [10]*2
cf_fy5 = [10]*2
cf_fy6 = [10]*2
npv = [200, 400]
def mydr(dr):
terminal_value = np.divide(cf_fy6, np.subtract(dr, 1.03))
ev = np.sum([np.divide(cf_fy1, np.power(dr, 1)),
np.divide(cf_fy2, np.power(dr, 2)),
np.divide(cf_fy3, np.power(dr, 3)),
np.divide(cf_fy4, np.power(dr, 4)),
np.divide(cf_fy5, np.power(dr, 5)),
np.divide(terminal_value, np.power(dr, 5))], axis=0)
z = np.subtract(ev, npv)
return abs(z)
try:
sol = newton_krylov(mydr, [1.1] * len(npv))
converged = True
except NoConvergence as e:
sol = e.args[0]
converged = False
提前感谢大家!
根据文档,牛顿-克雷洛夫方法(仅?(适合解决大规模问题。牛顿-克雷洛夫方法与您的初始点不收敛。由于这是一个非常简单的问题,我将改用通用的根方法:
In [13]: from scipy.optimize import root
In [14]: root(mydr, x0 = [1.1, 1.1])
Out[14]:
fjac: array([[-9.99999700e-01, 7.74730469e-04],
[-7.74730469e-04, -9.99999700e-01]])
fun: array([9.03350275e-06, 1.53610404e-06])
message: 'The solution converged.'
nfev: 40
qtf: array([-9.03230997e-06, -1.54310211e-06])
r: array([ -4128.02172068, -37514.05364792, 19083.3896212 ])
status: 1
success: True
x: array([1.07391362, 1.05176871])
如果需要,您可以通过method
选项设置使用的求解器(请注意不同的初始点(:
In [15]: root(mydr, x0 = [1.05, 1.05], method="krylov")
Out[15]:
fun: array([3.97903932e-13, 1.68824954e-11])
message: 'A solution was found at the specified tolerance.'
nit: 7
status: 1
success: True
x: array([1.07391362, 1.05176871])