Je pratique avec SciPy et j'ai rencontré une erreur en essayant d'utiliser fmin_slsqp. J'ai mis en place un problème dans lequel je veux maximiser une fonction objective, U, compte tenu d'un ensemble de contraintes. J'ai deux variables de contrôle, x [0, t] et x [1, t] et, comme vous pouvez le voir, elles sont indexées par t (périodes). La fonction objectif est:python fmin_slsqp - erreur avec contraintes
def obj_fct(x, alpha,beta,Al):
U = 0
x[1,0] = x0
for t in trange:
U = U - beta**t * ((Al[t]*L)**(1-alpha) * x[1,t]**alpha - x[0,t])
return U
Les contraintes sont définies sur ces deux variables et l'un d'eux relie les variables d'une période (t) à un autre (t-1).
def constr(x,alpha,beta,Al):
return np.array([
x[0,t],
x[1,0] - x0,
x[1,t] - x[0,t] - (1-delta)*x[1,t-1]
])
Enfin, voici l'utilisation de fmin_slsqp:
sol = fmin_slsqp(obj_fct, x_init, f_eqcons=constr, args=(alpha,beta,Al))
En laissant de côté le fait qu'il existe de meilleures façons de résoudre ces problèmes dynamiques, ma question est sur la syntaxe. Lors de l'exécution de ce code simple, j'obtiens l'erreur suivante:
Traceback (most recent call last):
File "xxx", line 34, in <module>
sol = fmin_slsqp(obj_fct, x_init, f_eqcons=constr, args=(alpha,beta,Al))
File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 207, in fmin_slsqp
constraints=cons, **opts)
File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 311, in _minimize_slsqp
meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']]))
File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 311, in <listcomp>
meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']]))
File "xxx", line 30, in constr
x[0,t],
IndexError: too many indices for array
[Finished in 0.3s with exit code 1]
Qu'est-ce que je fais mal?
La première partie du code, attribuer des valeurs aux paramètres, est:
from scipy.optimize import fmin_slsqp
import numpy as np
T = 30
beta = 0.96
L = 1
x0 = 1
gl = 0.02
alpha = 0.3
delta = 0.05
x_init = np.array([1,0.1])
A_l0 = 1000
Al = np.zeros((T+1,1))
Al[1] = A_l0
trange = np.arange(1,T+1,1, dtype='Int8') # does not include period zero
for t in trange: Al[t] = A_l0*(1 + gl)**(t-1)
x_init est incorrectement spécifié. Il devrait être: x_init = np.ones ((2, T + 1)) x_init [:, 0] = [1,0,1] –