如何解决“电源中遇到无效值”错误?

时间:2019-07-02 00:44:41

标签: python-3.x numpy jupyter-notebook

我正在编写一个函数来求值并返回非线性方程组,并给出雅可比函数。然后,我计划在while循环中调用该函数,以使用newton方法来求解方程组。

我使用了numpy软件包并阅读了其文档,试图限制迭代次数,更改了数组中的dtype并在线搜索以查看是否有人遇到类似的问题。

该函数的目的是在有限的时间T中求解新古典增长模型(宏观经济学中的问题)。方程组包括T euler方程,T约束和一个最终条件。因此,结果应为包含等式值的长度为2T + 1的数组,以及一个(2T + 1)x(2T + 1)雅可比矩阵。

当我尝试为小数组(长度为1和3的数组)运行该函数时,它可以完美运行。一旦尝试长度为5或更大的数组,我就会开始遇到RuntimeWarnings。

import numpy as np
def solver(args, params):
    b,s,a,d = params[0], params[1], params[2], params[3]
    guess = np.copy(args)

    #Euler
    euler = guess[:len(guess)//2]**(-sigma) - beta*guess[1:len(guess)//2+1]**(-sigma)*(1-delta+alpha*guess[len(guess)//2+1:]**(alpha-1))

    #Budget Constraint
    kzero_to_T = np.concatenate(([k0], guess[len(guess)//2+1:]))
    bc_t = guess[:len(guess)//2] + guess[len(guess)//2+1:] - kzero_to_T[:-1]**alpha - (1-delta)*kzero_to_T[:-1]
    bc_f = guess[len(guess)//2] -kzero_to_T[-1]**alpha - kzero_to_T[-1]*(1-delta)
    bc = np.hstack((bc_t, bc_f))
    Evals = np.concatenate((euler, bc))

    # top half of the jacobian
    jac_dot_5 = np.zeros((len(args)//2, len(args)))
    for t in range(len(args)//2):
        for i in range(len(args)):
            if t == i and len(args)//2+(i+1)<=len(args):
                jac_dot_5[t][t] = -sigma*args[t]**(-sigma-1)
                jac_dot_5[t][t+1] = sigma*beta*args[t+1]*(1-delta+alpha*args[len(args)//2+(t+1)]**(alpha-1))
                jac_dot_5[t][len(args)//2+(t+1)] = beta*args[t+1]**(-sigma)*alpha*(alpha-1)*args[len(args)//2+(t+1)]

    # bottom half of the jacobian   
    jac_dot_1 = np.zeros((len(args)//2, len(args)))

    for u in range(len(args)//2):
        for v in range(len(args)):
            if u==v and u>=1 and (len(args)//2 + u+1 < len(args)):
                jac_dot_1[u][u] =  1
                jac_dot_1[u][len(args)//2+(u)] = 1
                jac_dot_1[u][len(args)//2+(u+1)] = -alpha*args[len(args)//2 + (u+1)]**(alpha-1) -(1-delta)
    jac_dot_1[0][0] = 1
    jac_dot_1[0][len(args)//2 +1] = 1

    # last row of the jacobian
    final_bc = np.zeros((1,len(args)))
    final_bc[0][len(args)//2] = 1
    final_bc[0][-1] = -alpha*args[-1]**(alpha-1) -(1-delta)

    jac2Tn1 = np.concatenate((jac_dot_5, jac_dot_1, final_bc), axis=0) 

    point = coll.namedtuple('point', ['Output', 'Jacobian', 'Euler', 'BC'])
    result = point(Output = Evals, Jacobian = jac2Tn1, Euler=euler, BC=bc )

    return result

用于实现该算法的代码:

p = (beta, sigma, alpha, delta)
for i in range(20):
    k0 = np.linspace(2.49, 9.96, 20)[i]
    vars0 = np.array([1,1,1,1,1], dtype=float)
    vars1 = np.array([20,20,20,20,20], dtype=float)
    Iter2= 0

    while abs(solver(vars1,p).Output).max()>1e-8 and Iter2<300:
        Iter2+=1
        inv_jac1 = np.linalg.inv(solver(vars0,p).Jacobian)
        vars1 = vars0 - inv_jac1@solver(vars0,p).Output
        vars0=vars1
        if Iter2 == 100:
            break

我希望输出为vars1,其中包含更新后的值。实际输出为array([nan, nan, nan, nan, nan])。编写函数的方式,它应该能够为任意猜测的长度为2T + 1的输入提供输出,其中T是时间段数。

在执行循环期间,我收到三个错误消息:

C:\Users\Peter\Anaconda3\lib\site-packages\ipykernel_launcher.py:19: RuntimeWarning: invalid value encountered in power

C:\Users\Peter\Anaconda3\lib\site-packages\ipykernel_launcher.py:23: RuntimeWarning: invalid value encountered in power

C:\Users\Peter\Anaconda3\lib\site-packages\ipykernel_launcher.py:41: RuntimeWarning: invalid value encountered in double_scalars

我试图从头开始编写我的问题,但我不能再缩短它了—我既需要方程的求值,也需要用雅各布来实现算法。从我的测试看来,方程式结果(solver(vars0,p).Output项)有时变成nan,,但我不确定为什么会发生,根据条件{{ 1}},然后跳出循环。

0 个答案:

没有答案