python - 为什么相同算法的执行时间在 numpy 的模块中编码时会发生如此大的变化
问题描述
在我的学习过程中,我正在以两种不同的方式编写价值函数迭代问题。
- python文件中的所有代码
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
import rutinas as rt
# Tenemos que definir lo parametros
alpha = .33
delta = .07
sigma = 1.5
gamma = 0 # Vamos a considerar que los hogares no valoran el ocio
beta = .97
tfp = 1.0
# Definicion de estados estaionarios
sss = alpha*delta/(1.0/beta-1.0+delta)
lss = (1.0-alpha)/(1.0-alpha+gamma*(1-sss))
kss = (alpha*tfp/(1.0/beta-1.0+delta))**(alpha/(1.0-alpha))
yss = tfp*kss**alpha*lss**(1.0-alpha)
css = (1.0-sss)*yss
# Definimos un grid para la variable de estado de la economía
nk = 500
kmin = 1.0e-5
kmax = 4*kss
kgrid = np.linspace(kmin, kmax, nk)
# Definimos una matriz de consumos. Esto puede hacerse de dos formas:
# 1. Preasignando y llenado espacios
matrizC = np.empty((nk, nk))
matrizU = np.empty((nk, nk))
for i1 in range(0,nk):
for i2 in range(0,nk):
matrizC[i1, i2] = tfp*kgrid[i1]**alpha\
+ (1.0-delta)*kgrid[i1]\
- kgrid[i2]
# Un indicador de posiciones de consumo positivas
indC = matrizC <= 0
matrizU = matrizC**(1.0-sigma)/(1.0-sigma)
matrizU[indC] = -1.e+6
# A partir de aquí podemos inicializar el algoritmo de programacion dinamica
valorInit = np.zeros(nk)
valorObj = np.zeros((nk, nk))
# Criterio de convergencia del algoritmo
tol = 1e-6
# Inicializamos el bucle while y un error arbitrario inicial
cont = 0
error = 10
while error > tol:
for i2 in range(0, nk):
valorObj[:, i2] = matrizU[:, i2] + beta*valorInit[i2]
pos = valorObj.argmax(axis = 1)
valor = valorObj.max(axis = 1)
error = np.max(np.abs(valor-valorInit))
valorInit = valor
cont += 1
print(error)
- 在具有其他例程的模块内
- 例程中的算法是前一个文件的复制粘贴
def mnc_bellman(param):
import numpy as np
# Declaramos los argumentos del problema de programacion dinamica
# tol, kmin, kmax, tam, valorInit = args
alpha, delta, sigma, gamma, beta, tfp = param
kss = (alpha * tfp / (1.0 / beta - 1.0 + delta))**(alpha / (1.0 - alpha))
tol = 1.0e-6
kmin = 1.0e-4
kmax = 4*kss
tam = 500
valorInit = np.zeros((tam))
# Inicializamos objetos que vamos a necesitar
matrizC = np.empty((tam, tam))
valorObj = np.zeros((tam, tam))
kgrid = np.linspace(kmin, kmax, tam)
for i1 in range(0, tam):
for i2 in range(0, tam):
matrizC[i1, i2] = tfp * kgrid[i1] ** alpha \
+ (1.0 - delta) * kgrid[i1] \
- kgrid[i2]
# Un indicador de posiciones de consumo positivas
indC = matrizC <= 0
matrizU = matrizC ** (1.0 - sigma) / (1.0 - sigma)
matrizU[indC] = -1.e+6
# A partir de aqui podemos inicializar el algoritmo ITERACION de la
# funcion de VALOR
# Esta variable va a guardar cuantas veces iteramos hasta cumplir con los
# criterios de convergencia
cont = 0
# Tambien tenemos que establecer un error inicial que no se satisfaga
# trivialmente en el primer paso del bucle
error = 10
while error > tol:
for i2 in range(0, tam):
valorObj[:, i2] = matrizU[:, i2] + beta * valorInit[i2]
pos = valorObj.argmax(axis=1)
valor = valorObj.max(axis=1)
error = np.max(np.abs(valor - valorInit))
valorInit = valor
cont += 1
print(error)
# Ahora reconstruimos las reglas de decision
reglaK = kgrid[pos]
reglaC = tfp * kgrid ** alpha + (1.0 - delta) * kgrid - reglaK
return valor, reglaK, reglaC
我后来从主程序调用
import numpy as np
import numpy.matlib
#import matplotlib.pyplot as plt
#from scipy.optimize import fsolve
import rutinas as rt
# Definicion de parametros del modelo (posteriormente intentare meterlos en un
# diccionario)
alpha = .36
delta = .08
sigma = 1.5
gamma = 0.5
beta = .97
tfp = 1.0
# Definicion de estado estacionario correspondiente a los parametros del
# modelo
sss = alpha * delta / (1.0 / beta - 1.0 + delta)
lss = (1.0 - alpha) / (1.0 - alpha + gamma * (1.0 - sss))
kss = (alpha * tfp / (1.0 / beta - 1.0 + delta))**(alpha / (1.0 - alpha))
yss = tfp * kss**alpha * lss**(1.0 - alpha)
css = (1.0 - sss) * yss
# Parametros relacionados con el algoritmo de iteracion de la funcion de valor
tol = 1.0e-6
kmin = 1.0e-4
kmax = 3.0*kss
tam = 500
valorInit = np.zeros((tam))
param = [alpha, delta, sigma, gamma, beta, tfp]
valor, reglaK, reglaC = rt.mnc_bellman(param)
两个代码运行并吐出相同的输出。但是,第二种选择要慢几个数量级。
我希望有人能指出我如何解决这种差异。我正在考虑使用 Jit,但我想先了解这个问题。
谢谢
解决方案
推荐阅读
- python - 按字符串的一部分查找字符串
- c++ - 在使用 make 制作的文件上使用 Valgrind
- slider - 能够使用滑块更改这些变量吗?
- python - 使用相等变量将两个列表合并为一个
- express - Jest 集成测试 Express REST API 与 Mongoose
- android - eglCreateWindowSurface() 只能使用 Surface、SurfaceView、SurfaceTexture 或 SurfaceHolder 的实例调用
- swift - UserDefaults to Image 代码构建,但运行时崩溃
- swift - 与泛型的关联类型一致的协议会产生编译器错误
- javascript - 如何传递模式类型:对象的关键规则
- python - 简单 Python/C API 测试中的 Nullptr 错误