PageRenderTime 69ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/pymaclab/dsge/parsers/_dsgeparser.py

https://github.com/TomAugspurger/pymaclab
Python | 2265 lines | 2226 code | 11 blank | 28 comment | 37 complexity | 867fda6981f05a46d42eff0254ad3cdd MD5 | raw file
Possible License(s): Apache-2.0
  1. '''
  2. .. module:: _dsgeparser
  3. :platform: Linux
  4. :synopsis: This is the (private) module responsible for carefully extracting meaningful information from the DSGE model templated
  5. files. In here we make much use of Regex patterns as we are extracting information from the mod file lines.
  6. .. moduleauthor:: Eric M. Scheffel <eric.scheffel@nottingham.edu.cn>
  7. '''
  8. import re
  9. from copy import deepcopy
  10. import numpy.matlib as mat
  11. import numpy as np
  12. import sys
  13. import os
  14. # This used to import sympycore, but should now also work with sympy
  15. import sympycore as SP
  16. #TODO: why have these as nested functions?
  17. def populate_model_stage_one(self, secs):
  18. """
  19. 1st stage population of DSGE model. Does not need Steady State.
  20. """
  21. # Establish the timing convention of variables in the model file
  22. self = def_timing(self,**self._vtiming)
  23. # This is a special dictionary which can be handed over to the template engines (i.e. Jinja2)
  24. if 'template_paramdic' not in dir(self): self.template_paramdic = {}
  25. # Get all information from the varvec section
  26. if all([False if 'None' in x else True for x in secs['varvec'][0]]):
  27. # match something like [1] z(t):eps_z(t):techshock{exo}[log,hp]
  28. vtexp = re.compile('^.*?\[.*?\]\s*(?P<vari>.+?)\s*:\s*(?P<varn>.+?)\s*\{(?P<vtype>[^\[]+)}\s*(?P<mod>\[.*?\]){0,1}')
  29. # match something like [15] x2(t):wrec2{con}[log,hp] OR [1] z(t):eps_z(t):techshock{exo}[log,hp]
  30. viiexp = re.compile('^.*?\[.*?\]\s*(?P<vari>.+?)\s*:\s*(?P<viid>.+?)\s*:\s*(?P<varn>.+?)\s*\{(?P<vtype>[^\[]+)}\s*(?P<mod>\[.*?\]){0,1}')
  31. voexp = re.compile('^.*?\[.*?\]\s*(?P<vari>@.+?):(?P<varn>[^\[]+)\s*(?P<mod>\[.*?\]){0,1}')
  32. vardic = {}
  33. audic = {}
  34. vardic['endo'] = {}
  35. audic['endo'] = {}
  36. vardic['exo'] = {}
  37. audic['exo'] = {}
  38. vardic['con'] = {}
  39. audic['con'] = {}
  40. vardic['other'] = {}
  41. vardic['endo']['var'] = []
  42. vardic['endo']['mod'] = []
  43. vardic['exo']['var'] = []
  44. vardic['exo']['mod'] = []
  45. vardic['con']['var'] = []
  46. vardic['con']['mod'] = []
  47. vardic['other']['var'] = []
  48. vardic['other']['mod'] = []
  49. audic['endo']['var'] = []
  50. audic['endo']['mod'] = []
  51. audic['con']['var'] = []
  52. audic['con']['mod'] = []
  53. audic['exo']['var'] = []
  54. audic['exo']['mod'] = []
  55. for x in secs['varvec'][0]:
  56. if viiexp.search(x):
  57. ma = viiexp.search(x)
  58. vari = ma.group('vari').strip()
  59. viid = ma.group('viid').strip()
  60. varn = ma.group('varn').strip()
  61. vtype = ma.group('vtype').strip()
  62. mods = ma.group('mod')
  63. vardic[vtype]['var'].append([vari,varn,viid])
  64. if mods != None:
  65. mods = mods.strip()
  66. if ',' in mods:
  67. vardic[vtype]['mod'].append(mods[1:-1].strip().split(','))
  68. else:
  69. vardic[vtype]['mod'].append([mods[1:-1].strip(),])
  70. else:
  71. vardic[vtype]['mod'].append([])
  72. elif vtexp.search(x):
  73. ma = vtexp.search(x)
  74. vari = ma.group('vari').strip()
  75. varn = ma.group('varn').strip()
  76. vtype = ma.group('vtype').strip()
  77. mods = ma.group('mod')
  78. vardic[vtype]['var'].append([vari,varn])
  79. if mods != None:
  80. mods = mods.strip()
  81. if ',' in mods:
  82. vardic[vtype]['mod'].append(mods[1:-1].strip().split(','))
  83. else:
  84. vardic[vtype]['mod'].append([mods[1:-1].strip(),])
  85. else:
  86. vardic[vtype]['mod'].append([])
  87. elif voexp.search(x):
  88. ma = voexp.search(x)
  89. # Slice off the @
  90. vari = ma.group('vari')[1:].strip()
  91. varn = ma.group('varn').strip()
  92. mods = ma.group('mod')
  93. vardic['other']['var'].append([vari,varn])
  94. if mods != None:
  95. mods = mods.strip()
  96. if ',' in mods:
  97. vardic['other']['mod'].append(mods[1:-1].strip().split(','))
  98. else:
  99. vardic['other']['mod'].append([mods[1:-1].strip(),])
  100. else:
  101. vardic['other']['mod'].append([])
  102. self.nendo = len(vardic['endo']['var'])
  103. self.nexo = len(vardic['exo']['var'])
  104. self.ncon = len(vardic['con']['var'])
  105. self.nother = len(vardic['other']['var'])
  106. self.nstat = self.nendo+self.nexo
  107. self.nall = self.nstat+self.ncon
  108. self.vardic = vardic
  109. self.audic = audic
  110. # Save for template instantiation
  111. self.template_paramdic['vardic'] = deepcopy(vardic)
  112. else:
  113. self.template_paramdic['vardic'] = False
  114. # Extract the model name and description
  115. if all([False if 'None' in x else True for x in secs['info'][0]]):
  116. for x in secs['info'][0]:
  117. if 'Name' in x:
  118. self.mod_name = x.split('=')[1].replace(';','').strip()
  119. # Save for template instantiation
  120. self.template_paramdic['mod_name'] = deepcopy(self.mod_name)
  121. if 'Desc' in x:
  122. self.mod_desc = x.split('=')[1].replace(';','').strip()
  123. # Save for template instantiation
  124. self.template_paramdic['mod_desc'] = deepcopy(self.mod_desc)
  125. if not self.template_paramdic.has_key('mod_name'):
  126. self.template_paramdic['mod_name'] = False
  127. if not self.template_paramdic.has_key('mod_desc'):
  128. self.template_paramdic['mod_desc'] = False
  129. # Extract parameters into dictionary
  130. if all([False if 'None' in x else True for x in secs['params'][0]]):
  131. param = {}
  132. # need to do this so users don't have to worry about integer division
  133. # but preserves integer division for sympycore stuff
  134. safe_div = """
  135. from __future__ import division
  136. """
  137. for x in secs['params'][0]:
  138. if ']' in x: x = x.split(']')[1].lstrip()
  139. list_tmp = x.split(';')
  140. list_tmp = list_tmp[0].split('=')[:]
  141. str_tmp1 = list_tmp[0].strip()
  142. str_tmp2 = list_tmp[1].strip()
  143. #NOTE: this *should* be safe, but users should know what's
  144. # in the .mod file
  145. exec(safe_div + "param['"+str_tmp1+"']=" + str_tmp2, {}, locals())
  146. locals()[str_tmp1] = param[str_tmp1]
  147. self.paramdic = param
  148. # Save for template instantiation
  149. self.template_paramdic['paramdic'] = deepcopy(param)
  150. else:
  151. self.template_paramdic['paramdic'] = False
  152. # Collect information on manual (closed-form) steady state
  153. if all([False if 'None' in x else True for x in secs['closedformss'][0]]):
  154. # Join multiline steady state definitions
  155. mansys = secs['closedformss'][0]
  156. list_tmp1 = []
  157. i1=0
  158. counter=0
  159. for x in mansys:
  160. if '...' in x:
  161. counter = counter + 1
  162. elif '...' not in x:
  163. if counter == 0:
  164. # Just in case people have used [1] markers...
  165. if ']' in x: x = x.split(']')[1].lstrip().rstrip()
  166. list_tmp1.append(x)
  167. elif counter > 0:
  168. str_tmp = ''
  169. for y in mansys[i1-counter:i1+1]:
  170. str_tmp = str_tmp + y.replace('...','')
  171. # Just in case people have used [1] markers...
  172. if ']' in str_tmp: str_tmp = str_tmp.split(']')[1].lstrip().rstrip()
  173. list_tmp1.append(str_tmp)
  174. counter = 0
  175. i1=i1+1
  176. self.manss_sys = list_tmp1
  177. # Save for template instantiation
  178. self.template_paramdic['manss_sys'] = deepcopy(list_tmp1)
  179. else:
  180. self.template_paramdic['manss_sys'] = False
  181. # Collect info on numerical steady state
  182. if all([False if 'None' in x else True for x in secs['manualss'][0]]):
  183. _mreg_alt = '^\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
  184. _mreg = '\[\d+\]\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
  185. _mreg2 = '\[\d+\]\s*[a-zA-Z]*(?!=\+|-|\*|/])\s*=\s*[0-9]*\.[0-9]*'
  186. _mregfocs = 'USE_FOCS=\[.*?\]'
  187. mregfocs = re.compile(_mregfocs)
  188. use_focs = False
  189. for lino in secs['manualss'][0]:
  190. if mregfocs.search(lino):
  191. # Save as the list of equations the be used
  192. use_focs = eval(lino.split('=')[1].replace(';','').strip())
  193. self._internal_focs_used = True
  194. mreg = re.compile(_mreg_alt+'|'+_mreg+'|'+_mreg2)
  195. indx = []
  196. ssidic={}
  197. ssili = []
  198. list_tmp = []
  199. anyssi_found = False
  200. i1=0
  201. counter=0
  202. for x in secs['manualss'][0]:
  203. if mreg.search(x):
  204. raw_str = x.replace(';','')
  205. anyssi_found = True
  206. ma = mreg.search(raw_str)
  207. if ']' in ma.group(): str1 = ma.group().replace(';','').split('=')[0].split(']')[1].strip()
  208. else: str1 = ma.group().replace(';','').split('=')[0].lstrip().rstrip()
  209. str2 = ma.group().split('=')[1].strip()
  210. # Save the result as a string here, later in mk_mssidic_subs() method we do substitutions and evaluate then
  211. locals().update(self.paramdic)
  212. # This captures the case where we have only variables from parameters, but no substitutions
  213. if '@' not in str2:
  214. ssidic[str1] = str(eval(str2))
  215. locals()[str1] = eval(str2)
  216. else:
  217. ssidic[str1] = str2
  218. ssili.append([str1,str2])
  219. indx.append(i1)
  220. elif not mreg.search(x) and '...' in x:
  221. counter = counter + 1
  222. elif not mreg.search(x) and '...' not in x:
  223. if counter == 0:
  224. if ']' in x: list_tmp.append(x.replace(';','').split(']')[1].split('=')[0].strip())
  225. else: list_tmp.append(x.replace(';','').split('=')[0].strip())
  226. elif counter > 0:
  227. str_tmp = ''
  228. for y in secs['manualss'][0][i1-counter:i1+1]:
  229. str_tmp = str_tmp + y.replace('...','').strip()
  230. if ']' in str_tmp: list_tmp.append(str_tmp.split(']')[1].split('=')[0].replace(';','').strip())
  231. else: list_tmp.append(str_tmp.split('=')[0].replace(';','').strip())
  232. counter = 0
  233. i1=i1+1
  234. if anyssi_found:
  235. self.ssidic = deepcopy(ssidic)
  236. self.ssili = deepcopy(ssili)
  237. # Save for template instantiation
  238. self.template_paramdic['ssidic'] = deepcopy(ssidic)
  239. else:
  240. #Make empty to be filled by other procedure
  241. self.ssidic = {}
  242. self.ssili = []
  243. # Save for template instantiation
  244. self.template_paramdic['ssidic'] = False
  245. if not use_focs:
  246. self.ssys_list = deepcopy(list_tmp)
  247. # Save for template instantiation
  248. self.template_paramdic['ssys_list'] = deepcopy(list_tmp)
  249. self.template_paramdic['use_focs'] = False
  250. elif use_focs and anyssi_found:
  251. self._use_focs = deepcopy(use_focs)
  252. self._ssidic = deepcopy(ssidic)
  253. self.ssili = deepcopy(ssili)
  254. # Save for template instantiation
  255. self.template_paramdic['ssys_list'] = False
  256. self.template_paramdic['use_focs'] = deepcopy(use_focs)
  257. elif use_focs and not anyssi_found:
  258. self._use_focs = deepcopy(use_focs)
  259. # Save for template instantiation
  260. self.template_paramdic['ssys_list'] = False
  261. self.template_paramdic['use_focs'] = deepcopy(use_focs)
  262. else:
  263. # Save for template instantiation
  264. self.template_paramdic['ssidic'] = False
  265. self.template_paramdic['ssys_list'] = False
  266. self.template_paramdic['use_focs'] = False
  267. return self
  268. ############# BELOW HERE IS ALL FOR 2ND STAGE ###########
  269. def def_timing(self,exo=[-1,0],endo=[-1,0],con=[0,1]):
  270. '''
  271. A small method which can be used in order to set the timings in stone.
  272. This will then be used in other parts of the code, also in macrolab package
  273. '''
  274. self.vtiming = {}
  275. self.vtiming['endo'] = deepcopy(endo)
  276. self.vtiming['exo'] = deepcopy(exo)
  277. self.vtiming['con'] = deepcopy(con)
  278. return self
  279. def mkaug2(self,insys=None,othersys=None):
  280. # Timing definitions
  281. endotime = self.vtiming['endo']
  282. exotime = self.vtiming['exo']
  283. contime = self.vtiming['con']
  284. endosp = []
  285. for x in self.vardic['endo']['var']:
  286. endosp = endosp + [[x,deepcopy(endotime)]]
  287. exosp = []
  288. for x in self.vardic['exo']['var']:
  289. exosp = exosp + [[x,deepcopy(exotime)]]
  290. consp = []
  291. for x in self.vardic['con']['var']:
  292. consp = consp + [[x,deepcopy(contime)]]
  293. alldic = {}
  294. alldic.update(self.paramdic)
  295. alldic.update(self.sstate)
  296. spvdic = {}
  297. spvdic['endo'] = endosp
  298. spvdic['exo'] = exosp
  299. spvdic['con'] = consp
  300. spvdic2 = deepcopy(spvdic)
  301. spvdic3 = deepcopy(spvdic2)
  302. spvdic3['endo'] = {}
  303. spvdic3['con'] = {}
  304. spvdic3['exo'] = {}
  305. endoli = [x[0].split('(')[0].strip() for x in self.vardic['endo']['var']]
  306. exoli = [x[0].split('(')[0].strip() for x in self.vardic['exo']['var']]
  307. conli = [x[0].split('(')[0].strip() for x in self.vardic['con']['var']]
  308. patup = ('{-100,100}|None','all','{-100,100}')
  309. count = 0
  310. list_tmp1 = deepcopy(insys)
  311. for i1,line in enumerate(list_tmp1):
  312. iterob = self.vreg(patup,line,True,'max')
  313. if iterob:
  314. iterob = list(iterob)
  315. else:
  316. continue
  317. iterob.reverse()
  318. for vma in iterob:
  319. vtype = vma[1][0]
  320. vartime = vma[2][2]
  321. vari = vma[2][1]
  322. pos = vma[3][0]
  323. poe = vma[3][1]
  324. # In the following section we will replace time-shifted variables with their auxiliary counterparts
  325. # in the EXISTING equations of the FOCs, but no new definitions of auxiliary variables are being added
  326. # Depending on options passed, we may work on the FOCs or the items in NLSUBS_LIST
  327. if vtype == 'endo':
  328. indx = endoli.index(vari)
  329. if not spvdic3['endo'].has_key(vari):
  330. spvdic3['endo'][vari] = []
  331. if spvdic3['endo'][vari] == []:
  332. spvdic3['endo'][vari].append(int(vartime))
  333. spvdic3['endo'][vari].append(int(vartime))
  334. elif int(vartime) < spvdic3['endo'][vari][0]: spvdic3['endo'][vari][0] = int(vartime)
  335. elif int(vartime) > spvdic3['endo'][vari][1]: spvdic3['endo'][vari][1] = int(vartime)
  336. elif vtype == 'con':
  337. indx = conli.index(vari)
  338. if not spvdic3['con'].has_key(vari):
  339. spvdic3['con'][vari] = []
  340. if spvdic3['con'][vari] == []:
  341. spvdic3['con'][vari].append(int(vartime))
  342. spvdic3['con'][vari].append(int(vartime))
  343. elif int(vartime) < spvdic3['con'][vari][0]: spvdic3['con'][vari][0] = int(vartime)
  344. elif int(vartime) > spvdic3['con'][vari][1]: spvdic3['con'][vari][1] = int(vartime)
  345. elif vtype == 'exo':
  346. indx = exoli.index(vari)
  347. if not spvdic3['exo'].has_key(vari):
  348. spvdic3['exo'][vari] = []
  349. if spvdic3['exo'][vari] == []:
  350. spvdic3['exo'][vari].append(int(vartime))
  351. spvdic3['exo'][vari].append(int(vartime))
  352. elif int(vartime) < spvdic3['exo'][vari][0]: spvdic3['exo'][vari][0] = int(vartime)
  353. elif int(vartime) > spvdic3['exo'][vari][1]: spvdic3['exo'][vari][1] = int(vartime)
  354. else:
  355. continue
  356. # Check for endo
  357. if vtype == 'endo' and int(vartime) > spvdic['endo'][indx][1][1]:
  358. spvdic2['endo'][indx][1][1] = int(vartime)
  359. tind = (5-len(str(abs(endotime[1]-int(vartime)))))*'0'+str(abs(endotime[1]-int(vartime)))
  360. newvar = vari+'_F'+tind+'(t)'
  361. newname = vari+'_F'+str(abs(endotime[1]-int(vartime)))
  362. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
  363. for i2 in range(abs(int(vartime)-spvdic['endo'][indx][1][1])):
  364. tind = (5-len(str(abs(i2+1))))*'0'+str(abs(i2+1))
  365. newvar = vari+'_F'+tind+'(t)'
  366. newname = vari+'_F'+str(abs(i2+1))
  367. if [newvar,newname] not in self.vardic['con']['var']:
  368. self.vardic['con']['var'].append([newvar,newname])
  369. self.vardic['con']['mod'].append(self.vardic['endo']['mod'][indx])
  370. self.audic['con']['var'].append([newvar,newname])
  371. self.audic['con']['mod'].append(self.vardic['endo']['mod'][indx])
  372. if self.sstate.has_key(vari+'_bar'):
  373. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  374. else:
  375. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  376. continue
  377. elif vtype == 'endo' and int(vartime) < spvdic['endo'][indx][1][0]:
  378. spvdic2['endo'][indx][1][0] = int(vartime)
  379. tind = (5-len(str(abs(endotime[0]-int(vartime)))))*'0'+str(abs(endotime[0]-int(vartime)))
  380. newvar = vari+'_B'+tind+'(t)'
  381. newname = vari+'_B'+str(abs(endotime[0]-int(vartime)))
  382. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
  383. for i2 in range(1,abs(int(vartime)-spvdic['endo'][indx][1][0])+1):
  384. tind = (5-len(str(abs(i2))))*'0'+str(abs(i2))
  385. newvar = vari+'_B'+tind+'(t)'
  386. newname = vari+'_B'+str(abs(i2))
  387. if [newvar,newname] not in self.vardic['endo']['var']:
  388. self.vardic['endo']['var'].append([newvar,newname])
  389. self.vardic['endo']['mod'].append(self.vardic['endo']['mod'][indx])
  390. self.audic['endo']['var'].append([newvar,newname])
  391. self.audic['endo']['mod'].append(self.vardic['endo']['mod'][indx])
  392. if self.sstate.has_key(vari+'_bar'):
  393. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  394. else:
  395. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  396. continue
  397. # Check for exo
  398. if vtype == 'exo' and int(vartime) > spvdic['exo'][indx][1][1]:
  399. spvdic2['exo'][indx][1][1] = int(vartime)
  400. tind = (5-len(str(abs(exotime[1]-int(vartime)))))*'0'+str(abs(exotime[1]-int(vartime)))
  401. newvar = vari+'_F'+tind+'(t)'
  402. newname = vari+'_F'+str(abs(exotime[1]-int(vartime)))
  403. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
  404. for i2 in range(abs(int(vartime)-spvdic['exo'][indx][1][1])):
  405. tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
  406. newvar = vari+'_F'+tind+'(t)'
  407. newname = vari+'_F'+str(abs(i2+1))
  408. if [newvar,newname] not in self.vardic['con']['var']:
  409. self.vardic['con']['var'].append([newvar,newname])
  410. self.vardic['con']['mod'].append(self.vardic['exo']['mod'][indx])
  411. self.audic['con']['var'].append([newvar,newname])
  412. self.audic['con']['mod'].append(self.vardic['exo']['mod'][indx])
  413. if self.sstate.has_key(vari+'_bar'):
  414. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  415. else:
  416. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  417. continue
  418. elif vtype == 'exo' and int(vartime) < spvdic['exo'][indx][1][0]:
  419. spvdic2['exo'][indx][1][0] = int(vartime)
  420. tind = (5-len(str(abs(exotime[0]-int(vartime)))))*'0'+str(abs(exotime[0]-int(vartime)))
  421. newvar = vari+'_B'+tind+'(t)'
  422. newname = vari+'_B'+str(abs(exotime[0]-int(vartime)))
  423. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
  424. for i2 in range(abs(int(vartime)-spvdic['exo'][indx][1][0])):
  425. tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
  426. newvar = vari+'_B'+tind+'(t)'
  427. newname = vari+'_B'+str(abs(i2+1))
  428. if [newvar,newname] not in self.vardic['endo']['var']:
  429. self.vardic['endo']['var'].append([newvar,newname])
  430. self.vardic['endo']['mod'].append(self.vardic['exo']['mod'][indx])
  431. self.audic['endo']['var'].append([newvar,newname])
  432. self.audic['endo']['mod'].append(self.vardic['exo']['mod'][indx])
  433. if self.sstate.has_key(vari+'_bar'):
  434. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  435. else:
  436. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  437. continue
  438. # Check for con
  439. if vtype == 'con' and int(vartime) > spvdic['con'][indx][1][1]:
  440. spvdic2['con'][indx][1][1] = int(vartime)
  441. tind = (5-len(str(abs(contime[1]-int(vartime)))))*'0'+str(abs(contime[1]-int(vartime)))
  442. newvar = vari+'_F'+tind+'(t)'
  443. newname = vari+'_F'+str(abs(contime[1]-int(vartime)))
  444. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
  445. for i2 in range(abs(int(vartime)-spvdic['con'][indx][1][1])):
  446. tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
  447. newvar = vari+'_F'+tind+'(t)'
  448. newname = vari+'_F'+str(abs(i2+1))
  449. if [newvar,newname] not in self.vardic['con']['var']:
  450. self.vardic['con']['var'].append([newvar,newname])
  451. self.vardic['con']['mod'].append(self.vardic['con']['mod'][indx])
  452. self.audic['con']['var'].append([newvar,newname])
  453. self.audic['con']['mod'].append(self.vardic['con']['mod'][indx])
  454. if self.sstate.has_key(vari+'_bar'):
  455. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  456. else:
  457. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  458. continue
  459. elif vtype == 'con' and int(vartime) < spvdic['con'][indx][1][0] and spvdic3['con'][vari][0] < contime[0]:
  460. spvdic2['con'][indx][1][0] = int(vartime)
  461. tind = (5-len(str(abs(contime[0]-int(vartime)))))*'0'+str(abs(contime[0]-int(vartime)))
  462. newvar = vari+'_B'+tind+'(t)'
  463. newname = vari+'_B'+str(abs(contime[0]-int(vartime)))
  464. list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
  465. for i2 in range(abs(int(vartime)-spvdic['con'][indx][1][0])):
  466. tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
  467. newvar = vari+'_B'+tind+'(t)'
  468. newname = vari+'_B'+str(abs(i2+1))
  469. if [newvar,newname] not in self.vardic['endo']['var']:
  470. self.vardic['endo']['var'].append([newvar,newname])
  471. self.vardic['endo']['mod'].append(self.vardic['con']['mod'][indx])
  472. self.audic['endo']['var'].append([newvar,newname])
  473. self.audic['endo']['mod'].append(self.vardic['con']['mod'][indx])
  474. if self.sstate.has_key(vari+'_bar'):
  475. self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
  476. else:
  477. self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
  478. continue
  479. # Save the timings which were found in the FOC equations, or update exisiting one
  480. if 'vtimings_found' not in dir(self):
  481. self.vtimings_found = deepcopy(spvdic3)
  482. self.vtimings_differ = deepcopy(self.vtimings_found)
  483. else:
  484. for keyo in spvdic3.keys():
  485. for keyo2 in spvdic3[keyo].keys():
  486. if spvdic3[keyo][keyo2][0] < self.vtimings_found[keyo][keyo2][0]:
  487. self.vtimings_found[keyo][keyo2][0] = spvdic3[keyo][keyo2][0]
  488. if spvdic3[keyo][keyo2][1] > self.vtimings_found[keyo][keyo2][1]:
  489. self.vtimings_found[keyo][keyo2][1] = spvdic3[keyo][keyo2][1]
  490. # Also add a second dictionary which shows the difference between what was found and the reference timing
  491. for keyo in self.vtimings_found.keys():
  492. for keyo2 in self.vtimings_found[keyo].keys():
  493. if keyo == 'endo': self.vtimings_differ[keyo][keyo2] =\
  494. list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(endotime)])
  495. elif keyo == 'exo': self.vtimings_differ[keyo][keyo2] =\
  496. list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(exotime)])
  497. elif keyo == 'con': self.vtimings_differ[keyo][keyo2] =\
  498. list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(contime)])
  499. #################################################################################################
  500. ##
  501. ## In this section we will compute the declarations which have to be added to the nonlinear system
  502. ## in order to incorporate and include in derivations the auxiliare variables used throughout
  503. ##
  504. #################################################################################################
  505. list_added = []
  506. # Now change the system to include possible augmented variables
  507. endo_r = filter(lambda x: x[1] != endotime, spvdic2['endo'])
  508. if endo_r:
  509. endo_r = [[x[0],[abs(x[1][0]-endotime[0]),abs(x[1][1]-endotime[1])]] for x in endo_r ]
  510. # Create lags and forwards equations
  511. for vari in endo_r:
  512. varin = vari[0][0].split('(')[0]
  513. if vari[1][0] != 0:
  514. lagor = range(abs(spvdic3['endo'][varin][0]-endotime[0]))
  515. for lag in lagor:
  516. # Define some indices to be used
  517. tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
  518. tind = (5-len(str(lead)))*'0'+str(lead)
  519. tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
  520. tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
  521. # Define the beginning definition, needs to link up with the last variable define in endotime[1]
  522. if lag == lagor[0]:
  523. lag_endo_diff = spvdic3['endo'][varin][0]-endotime[0]
  524. if lag_endo_diff < 0:
  525. list_added.append(varin+'(t-'+str(abs(lag_endo_diff))+')'+' - '+varin+'_B00001(t-1)')
  526. if lag_endo_diff+1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
  527. elif lag_endo_diff+1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
  528. elif lag_endo_diff+1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
  529. elif lag_endo_diff == 0:
  530. list_added.append(varin+'(t)'+' - '+varin+'_B00001(t-1)')
  531. if lag_endo_diff-1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
  532. elif lag_endo_diff-1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
  533. elif lag_endo_diff-1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
  534. elif lag_endo_diff > 0:
  535. list_added.append(varin+'(t+'+str(lag_endo_diff)+')'+' - '+varin+'_B00001(t-1)')
  536. if lag_endo_diff-1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
  537. elif lag_endo_diff-1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
  538. elif lag_endo_diff-1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
  539. if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
  540. list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
  541. # For in between
  542. if lag != lagor[0] and lag != lagor[-1]:
  543. expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
  544. if expro not in list_added:
  545. list_added.append(expro)
  546. # Define the end tail definition
  547. if lag == lagor[-1] and len(lagor) != 1:
  548. if varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)' not in list_added:
  549. list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)')
  550. if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
  551. list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
  552. leador = range(abs(spvdic3['endo'][varin][1]-endotime[1]))
  553. if vari[1][1] != 0:
  554. for lead in leador:
  555. # Define some indices to be used
  556. tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
  557. tind = (5-len(str(lead)))*'0'+str(lead)
  558. tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
  559. tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
  560. # Define the beginning definition, needs to link up with the last variable define in endotime[1]
  561. if lead == leador[0]:
  562. if endotime[1] < 0:
  563. list_added.append(varin+'(t'+str(endotime[1])+')'+' - '+varin+'_F00001(t-1)')
  564. elif endotime[1] == 0:
  565. list_added.append(varin+'(t)'+' - '+varin+'_F00001(t-1)')
  566. elif endotime[1] > 0:
  567. list_added.append(varin+'(t+'+str(endotime[1])+')'+' - '+varin+'_F00001(t-1)')
  568. if endotime[1]+1 < 0:
  569. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t-'+str(abs(endotime[1]+1))+')')
  570. elif endotime[1]+1 == 0:
  571. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t)')
  572. elif endotime[1]+1 > 0:
  573. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t+'+str(abs(endotime[1]+1))+')')
  574. # For in between
  575. if lead != leador[0] and lead != leador[-1]:
  576. if varin+'_F'+tind+'(t)'+' - '+varin+'_F'+tind1+'(t-1)' not in list_added:
  577. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'_F'+tind1+'(t-1)')
  578. # Define the end tail definition
  579. if lead == leador[-1] and len(leador) != 1:
  580. if spvdic3['endo'][varin][1] > 0:
  581. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t+'+str(spvdic3['endo'][varin][1])+')')
  582. elif spvdic3['endo'][varin][1] == 0:
  583. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t)')
  584. elif spvdic3['endo'][varin][1] < 0:
  585. list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['endo'][varin][1]))+')')
  586. exo_r = filter(lambda x: x[1] != exotime, spvdic2['exo'])
  587. if exo_r:
  588. exo_r = [[x[0],[abs(x[1][0])-abs(exotime[0]),x[1][1]-abs(exotime[1])]] for x in exo_r ]
  589. # Create lags and forwards equations
  590. for vari in exo_r:
  591. varin = vari[0][0].split('(')[0]
  592. if vari[1][0] != 0:
  593. abstdiffer = abs(spvdic3['exo'][varin][0]-exotime[0])
  594. lagor = range(abstdiffer)
  595. for lag in lagor:
  596. # Define some indices to be used
  597. tindm1 = (5-len(str(lag-1)))*'0'+str(lag-1)
  598. tind = (5-len(str(lag)))*'0'+str(lag)
  599. tind1 = (5-len(str(lag+1)))*'0'+str(lag+1)
  600. tind2 = (5-len(str(lag+2)))*'0'+str(lag+2)
  601. # Define the beginning definition, needs to link up with the last variable define in exotime[1]
  602. if lag == lagor[0]:
  603. lag_exo_diff = spvdic3['exo'][varin][0]-exotime[0]
  604. timor = spvdic3['exo'][varin][0]+exotime[0]
  605. if lag_exo_diff < 0:
  606. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  607. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  608. elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  609. elif lag_exo_diff == 0:
  610. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  611. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  612. elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  613. elif lag_exo_diff > 0:
  614. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  615. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  616. elif timor < 0: list_added.append(+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  617. # For in between
  618. if lag != lagor[0] and lag != lagor[-1] and len(lagor) != 1:
  619. expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
  620. if expro not in list_added:
  621. list_added.append(expro)
  622. # Define the end tail definition
  623. if lag == lagor[-1] and len(lagor) != 1:
  624. if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
  625. list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
  626. abstdiffer = abs(spvdic3['exo'][varin][1]-exotime[1])
  627. leador = range(abstdiffer)
  628. if vari[1][1] != 0:
  629. for lead in leador:
  630. # Define some indices to be used
  631. tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
  632. tind = (5-len(str(lead)))*'0'+str(lead)
  633. tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
  634. tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
  635. # Define the beginning definition, needs to link up with the last variable define in endotime[1]
  636. if lead == leador[0]:
  637. if exotime[1]+1 < 0:
  638. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(exotime[1]+1))+')')
  639. elif exotime[1]+1 == 0:
  640. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
  641. elif exotime[1]+1 > 0:
  642. list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(abs(exotime[1]+1))+')')
  643. # For in between
  644. if lead != leador[0] and lead != leador[-1]:
  645. if varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)' not in list_added:
  646. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)')
  647. # Define the end tail definition
  648. if lead == leador[-1] and len(leador) != 1:
  649. if spvdic3['exo'][varin][1] > 0:
  650. list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(spvdic3['exo'][varin][1])+')')
  651. elif spvdic3['exo'][varin][1] == 0:
  652. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
  653. elif spvdic3['exo'][varin][1] < 0:
  654. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['exo'][varin][1]))+')')
  655. con_r = filter(lambda x: x[1] != contime, spvdic2['con'])
  656. if con_r:
  657. con_r = [[x[0],[abs(x[1][0])-abs(contime[0]),x[1][1]-abs(contime[1])]] for x in con_r ]
  658. # Create lags and forwards equations
  659. for vari in con_r:
  660. varin = vari[0][0].split('(')[0]
  661. if vari[1][0] != 0:
  662. abstdiffer = abs(spvdic3['con'][varin][0]-contime[0])
  663. lagor = range(abstdiffer)
  664. for lag in lagor:
  665. # Define some indices to be used
  666. tindm1 = (5-len(str(lag-1)))*'0'+str(lag-1)
  667. tind = (5-len(str(lag)))*'0'+str(lag)
  668. tind1 = (5-len(str(lag+1)))*'0'+str(lag+1)
  669. tind2 = (5-len(str(lag+2)))*'0'+str(lag+2)
  670. # Define the beginning definition, needs to link up with the last variable define in contime[1]
  671. if lag == lagor[0]:
  672. lag_con_diff = spvdic3['con'][varin][0]-contime[0]
  673. timor = spvdic3['con'][varin][0]+contime[0]+1
  674. if lag_con_diff < 0:
  675. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  676. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  677. elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  678. elif lag_con_diff == 0:
  679. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  680. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  681. elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  682. elif lag_con_diff > 0:
  683. if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
  684. elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
  685. elif timor < 0: list_added.append(+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
  686. # For in between
  687. if lag != lagor[0] and lag != lagor[-1] and len(lagor) != 1:
  688. expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
  689. if expro not in list_added:
  690. list_added.append(expro)
  691. # Define the end tail definition
  692. if lag == lagor[-1] and len(lagor) != 1:
  693. if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
  694. list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
  695. abstdiffer = abs(spvdic3['con'][varin][1]-contime[1])
  696. leador = range(abstdiffer)
  697. if vari[1][1] != 0:
  698. for lead in leador:
  699. # Define some indices to be used
  700. tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
  701. tind = (5-len(str(lead)))*'0'+str(lead)
  702. tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
  703. tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
  704. # Define the beginning definition, needs to link up with the last variable define in endotime[1]
  705. if lead == leador[0]:
  706. if contime[1]+1 < 0:
  707. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(contime[1]+1))+')')
  708. elif contime[1]+1 == 0:
  709. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
  710. elif contime[1]+1 > 0:
  711. list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(abs(contime[1]+1))+')')
  712. # For in between
  713. if lead != leador[0] and lead != leador[-1]:
  714. if varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)' not in list_added:
  715. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)')
  716. # Define the end tail definition
  717. if lead == leador[-1] and len(leador) != 1:
  718. if spvdic3['con'][varin][1] > 0:
  719. list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(spvdic3['con'][varin][1])+')')
  720. elif spvdic3['con'][varin][1] == 0:
  721. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
  722. elif spvdic3['con'][varin][1] < 0:
  723. list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['con'][varin][1]))+')')
  724. # If only on system was passed in then we just return the modified equations with the added equations attached at bottom
  725. # If two systems were passed, then we return the substituted out system of equations (in nlsubs_list) and the declarations added
  726. # to the bottom of the usual FOC system of equations, BUT ONLY if they are not already included
  727. if othersys == None:
  728. for lino in list_added:
  729. if lino not in list_tmp1: list_tmp1.append(lino)
  730. return self, deepcopy(list_tmp1)
  731. elif othersys != None:
  732. for lino in list_added:
  733. if lino not in othersys:
  734. othersys.append(lino)
  735. return self, (list_tmp1,othersys)
  736. def mk_subs_dic(self, secs):
  737. # Make the substitution system by joining lines and stripping
  738. list_tmp2 = []
  739. # This list is used to catch the @ALL instructions and store them
  740. list_tmp3 = []
  741. list_tmp3_ind = []
  742. # A list which collects all elements, to be handed to the template_paramdic for template parsing
  743. list_tmp4 = []
  744. i1=0
  745. linecounter=0
  746. for x in secs['vsfocs'][0]:
  747. if x.endswith(("...","\\")):
  748. linecounter += 1
  749. else:
  750. if linecounter == 0:
  751. ################# Catch @ALL expressions and store################
  752. if "@ALL" in x:
  753. intor = []
  754. intor1 = x.split('@ALL')[1].replace(';','')
  755. intor.append('@ALL')
  756. intor.append(intor1)
  757. list_tmp4.append(intor)
  758. raw_str = x.split(';')[0].split('@ALL')[1].split('{')[1].split('}')[0]
  759. list_tmp3.append(raw_str.split(','))
  760. list_tmp3_ind.append(i1)
  761. continue
  762. ##################################################################
  763. line = x.replace(';','').split(']')[1].strip()
  764. elif linecounter > 0: # have a multiline equation
  765. str_tmp = ''
  766. for y in secs['vsfocs'][0][i1-linecounter:i1+1]:
  767. str_tmp += y.replace('...','').replace(';','').replace('//','').strip()
  768. ################# Catch @ALL expressions and store################
  769. if "@ALL" in str_tmp:
  770. intor = []
  771. intor1 = x.split('@ALL')[1].replace(';','')
  772. intor.append('@ALL')
  773. intor.append(intor1)
  774. list_tmp4.append(intor)
  775. raw_str = str_tmp.split('@ALL')[1].split('{')[1].split('}')[0]
  776. list_tmp3.append(raw_str.split(','))
  777. list_tmp3_ind.append(i1)
  778. continue
  779. ##################################################################
  780. if ']' in str_tmp:
  781. line = str_tmp.split(']')[1].strip()
  782. else:
  783. line = str_tmp.strip()
  784. linecounter = 0
  785. i1 += 1
  786. splitline = line.split('=')
  787. # Only consider the first split of = found, this is used because of subs_ind
  788. if len(splitline) > 2:
  789. tmpstr = ''
  790. for elem in splitline[1:]:
  791. tmpstr = tmpstr+'='+elem
  792. tmpstr = tmpstr[1:]
  793. splitline = [splitline[0],tmpstr]
  794. list_tmp4.append([splitline[0].strip(), splitline[1].strip()])
  795. list_tmp2.append([splitline[0].strip(), splitline[1].strip()])
  796. self.allsubs_raw1 = deepcopy(list_tmp3)
  797. self.allsubs_index = deepcopy(list_tmp3_ind)
  798. self.nlsubs_raw1 = deepcopy(list_tmp2)
  799. self.nlsubsdic = dict(list_tmp2)
  800. if list_tmp4 != []: self.template_paramdic['subs_list'] = deepcopy(list_tmp4)
  801. else: self.template_paramdic['subs_list'] = False
  802. return self
  803. def subs_in_subs_all(self):
  804. list_tmp3 = deepcopy(self.allsubs_raw1)
  805. list_tmp2 = deepcopy(self.nlsubs_raw1)
  806. # Replace substitutions inside substitutions, for both time-subscripted and steady state vars!
  807. mreg = re.compile('@DISCOUNT|@(E\(t.*?\)\|){0,1}.*?\(t.*?\)|@(E\(t.*?\)\|){0,1}.*?_bar')
  808. variables = [x[0] for x in list_tmp2] # do this once
  809. for i,x in enumerate(list_tmp3):
  810. expr = list_tmp3[i][0]
  811. while mreg.search(expr):
  812. ma = mreg.search(expr)
  813. indx = variables.index(ma.group())
  814. expr = list_tmp2[indx][1]
  815. list_tmp3[i][0] = expr
  816. self.allsubs_raw2 = deepcopy(list_tmp3)
  817. return self
  818. def mk_all(self):
  819. list_tmp1 = deepcopy(self.allsubs_raw2)
  820. list_tmp2 = deepcopy(self.allsubs_raw1)
  821. list_tmp3 = deepcopy(self.nlsubs_raw1)
  822. subsli = [x[0] for x in list_tmp3]
  823. repldic_li = []
  824. do_ss = False
  825. for i1,elem in enumerate(list_tmp1):
  826. repldic = {}
  827. if 'SS' in elem: do_ss = True
  828. stem = list_tmp2[i1][0].split('(')[0]
  829. stem_time = '('+list_tmp2[i1][0].split('(')[1]
  830. # Do the simplest SS conversion
  831. if stem+'_bar' not in subsli: repldic[stem+'_bar'] = 'SS{'+stem+stem_time+'}'
  832. if '-' in elem[1]:
  833. chron = range(int(elem[1].split('-')[0].split('[')[1]),int(elem[1].split('-')[1].split(']')[0])+1)
  834. else:
  835. chron = elem[2].split('[')[1].split(']')[0].split(',')
  836. chron = [int(x) for x in chron]
  837. # Do current-period differentiation and SS jobs first
  838. patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
  839. varli = self.vreg(patup,list_tmp1[i1][0],True,'max')
  840. for chrono in chron:
  841. if chrono == 0:
  842. for varo in varli:
  843. if varo[1][0] == 'con' and int(varo[2][2]) == 0:
  844. if stem+varo[2][1]+stem_time not in subsli:
  845. repldic[stem+varo[2][1]+stem_time] = 'DIFF{'+stem+stem_time+','+varo[0]+'}'
  846. if stem+varo[2][1]+'_bar' not in subsli:
  847. repldic[stem+varo[2][1]+'_bar'] = 'SS{'+stem+varo[2][1]+stem_time+'}'
  848. elif varo[1][0] == 'endo' and int(varo[2][2]) == -1:
  849. if stem+varo[2][1]+stem_time not in subsli:
  850. repldic[stem+varo[2][1]+stem_time] = 'DIFF{'+stem+stem_time+','+varo[0]+'}'
  851. if stem+varo[2][1]+'_bar' not in subsli:
  852. repldic[stem+varo[2][1]+'_bar'] = 'SS{'+stem+varo[2][1]+stem_time+'}'
  853. else:
  854. if stem_time == '(t)':
  855. stem_time_new = '(t+'+str(chrono)+')'
  856. elif '+' in stem_time:
  857. old_t = int(stem_time.split('+')[1].split(')')[0])
  858. stem_time_new = '(t+'+str(old_t+chrono)+')'
  859. elif '-' in stem_time:
  860. old_t = int('-'+stem_time.split('-')[1].split(')')[0])
  861. stem_time_new = '(t+'+str(old_t+chrono)+')'
  862. for varo in varli:
  863. if chrono > 0:
  864. if varo[1][0] == 'con' and int(varo[2][2]) == 0:
  865. if stem+stem_time_new not in subsli:
  866. repldic[stem+stem_time_new] = 'FF_'+str(chrono)+'{'+stem+stem_time+'}'
  867. if stem+varo[2][1]+stem_time_new not in subsli:
  868. repldic[stem+varo[2][1]+stem_time_new] = 'DIFF{'+stem+stem_time_new+','+'FF_'+str(chrono)+'{'+varo[0]+'}'+'}'
  869. elif varo[1][0] == 'endo' and int(varo[2][2]) == -1:
  870. if stem+stem_time_new not in subsli:
  871. repldic[stem+stem_time_new] = 'FF_'+str(chrono)+'{'+stem+stem_time+'}'
  872. if stem+varo[2][1]+stem_time_new not in subsli:
  873. repldic[stem+varo[2][1]+stem_time_new] = 'DIFF{'+stem+stem_time_new+','+'FF_'+str(chrono)+'{'+varo[0]+'}'+'}'
  874. elif chrono < 0:
  875. if varo[1][0] == 'con' and int(varo[2][2]) == 0:
  876. if stem+stem_time_new not in subsli:
  877. repldic[stem+stem_time_new] = 'BB_'+str(abs(chrono))+'{'+stem+stem_time+'}'
  878. if stem+varo[2][1]+stem_time_new not in subsli:
  879. repldic[stem+varo[2][1]+stem_time_new] = 'DIFF{'+stem+stem_time_new+','+'BB_'+str((chrono))+'{'+varo[0]+'}'+'}'
  880. elif varo[1][0] == 'endo' and int(varo[2][2]) == -1:
  881. if stem+stem_time_new not in subsli:
  882. repldic[stem+stem_time_new] = 'BB_'+str(abs(chrono))+'{'+stem+stem_time+'}'
  883. if stem+varo[2][1]+stem_time_new not in subsli:
  884. repldic[stem+varo[2][1]+stem_time_new] = 'DIFF{'+stem+stem_time_new+','+'BB_'+str(abs(chrono))+'{'+varo[0]+'}'+'}'
  885. repldic_li.append(repldic)
  886. repldic_li.reverse()
  887. indexli = deepcopy(self.allsubs_index)
  888. indexli.reverse()
  889. for i1,indexo in enumerate(indexli):
  890. self.nlsubs_raw1 = self.nlsubs_raw1[:indexo]+[list(x) for x in repldic_li[i1].items()]+self.nlsubs_raw1[indexo:]
  891. del self.allsubs_index
  892. return self
  893. def subs_in_subs(self):
  894. list_tmp2 = deepcopy(self.nlsubs_raw1)
  895. list_tmp3 = deepcopy(self.allsubs_raw1)
  896. # Replace substitutions inside substitutions, for both time-subscripted and steady state vars!
  897. mreg = re.compile('@DISCOUNT|@(E\(t.*?\)\|){0,1}.*?\(t.*?\)|@(E\(t.*?\)\|){0,1}.*?_bar')
  898. variables = [x[0] for x in list_tmp2] # do this once
  899. self.subs_vars = deepcopy(variables)
  900. for i,x in enumerate(list_tmp2):
  901. rhs_eq = list_tmp2[i][1]
  902. while mreg.search(rhs_eq):
  903. ma = mreg.search(rhs_eq)
  904. pos, poe = ma.span()
  905. indx = variables.index(ma.group())
  906. # Important: When substituting in, put the term between brackets!
  907. rhs_eq = rhs_eq[:pos]+'('+list_tmp2[indx][1]+')'+rhs_eq[poe:]
  908. # Don't do below anymore as the term above has been inserted between brackets, so okay that way
  909. '''
  910. # Finally get rid of possible `+-` or `-+` occurences
  911. while '+-' in rhs_eq or '-+' in rhs_eq or '++' in rhs_eq:
  912. rhs_eq = rhs_eq.replace('+-','-')
  913. rhs_eq = rhs_eq.replace('-+','-')
  914. rhs_eq = rhs_eq.replace('++','+')
  915. '''
  916. list_tmp2[i][1] = rhs_eq
  917. self.nlsubs_raw2 = deepcopy(list_tmp2)
  918. return self
  919. def ff_chron_str(self,str1='',ff_int=1,vtype='all'):
  920. '''
  921. This forwards all variables in an algebraic string expression by ff_int,
  922. but it leaves the timing of the expectations operator untouched.
  923. '''
  924. _mregv1b = '(?<!E)\(t(?P<oper>[\+|-]{0,1})(?P<counto>\d{0,2})\)'
  925. _mregv1c = '(?<=E)\(t(?P<oper>[\+|-]{0,1})(?P<counto>\d{0,2})\)(?=\|)'
  926. mregv1b = re.compile(_mregv1b)
  927. mregv1c = re.compile(_mregv1c)
  928. patup = ('{-10,10}|None','endo|con|exo|iid|other','{-10,10}')
  929. reg_li = self.vreg(patup,str1,True,'max')
  930. if type(reg_li) == type(False):
  931. print "ERROR at: ",str1
  932. sys.exit()
  933. var_li = list(reg_li)
  934. var_li.reverse()
  935. for varo in var_li:
  936. if vtype != 'all' and varo[1][0] != vtype:
  937. continue
  938. elif vtype != 'all' and varo[1][0] != vtype:
  939. continue
  940. elif vtype != 'all' and varo[1][0] != vtype:
  941. continue
  942. elif vtype != 'all' and varo[1][0] != vtype:
  943. continue
  944. varn = varo[0]
  945. ma = mregv1b.search(varn)
  946. starts = ma.start()
  947. ends = ma.end()
  948. matot = ma.group()
  949. oper = ma.group('oper')
  950. counto = ma.group('counto')
  951. varpos = varo[3]
  952. if oper == '':
  953. oper = '+'
  954. counto = int(ff_int)
  955. elif oper == '+':
  956. counto = int(counto)+ff_int
  957. counto = str(counto)
  958. elif oper == '-':
  959. counto = -int(counto)+ff_int
  960. counto = str(counto)
  961. if counto == '0':
  962. oper = ''
  963. counto = ''
  964. elif counto[0] == '-':
  965. oper == '-'
  966. counto = counto[1]
  967. else:
  968. oper = '+'
  969. counto = str(counto)
  970. # Split off expectations operator if present
  971. if '|' in varn:
  972. expos = varn.split('|')[0]
  973. rems = varn.split('|')[1]
  974. else:
  975. expos = ''
  976. rems = varn
  977. if expos == '':
  978. varn_new = rems.split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  979. else:
  980. varn_new = expos+'|'+rems.split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  981. # Add an expectations term if needed, but only if it is not already inside the original variable
  982. if oper == '+' and int(counto) > 0:
  983. if not mregv1c.search(varn_new): varn_new = 'E(t)|'+varn_new
  984. str1 = str1[:varpos[0]]+varn_new+str1[varpos[1]:]
  985. return str1
  986. def bb_chron_str(self,str1='',bb_int=1,vtype='all'):
  987. '''
  988. This backwards (lags) all variables in an algebraic string expression by bb_int,
  989. but it leaves the timing of the expectations operator untouched.
  990. '''
  991. _mregv1b = '(?<!E)\(t(?P<oper>[\+|-]{0,1})(?P<counto>\d{0,2})\)'
  992. mregv1b = re.compile(_mregv1b)
  993. patup = ('{-10,10}|None','endo|con|exo|iid|other','{-10,10}')
  994. var_li = list(self.vreg(patup,str1,True,'max'))
  995. var_li.reverse()
  996. for varo in var_li:
  997. if vtype != 'all' and varo[1][0] != vtype:
  998. continue
  999. elif vtype != 'all' and varo[1][0] != vtype:
  1000. continue
  1001. elif vtype != 'all' and varo[1][0] != vtype:
  1002. continue
  1003. elif vtype != 'all' and varo[1][0] != vtype:
  1004. continue
  1005. varn = varo[0]
  1006. ma = mregv1b.search(varn)
  1007. starts = ma.start()
  1008. ends = ma.end()
  1009. matot = ma.group()
  1010. oper = ma.group('oper')
  1011. counto = ma.group('counto')
  1012. varpos = varo[3]
  1013. if oper == '':
  1014. oper = '-'
  1015. counto = int(bb_int)
  1016. elif oper == '+':
  1017. counto = int(counto)-bb_int
  1018. counto = str(counto)
  1019. if counto == '0':
  1020. oper = ''
  1021. counto = ''
  1022. elif counto[0] == '-':
  1023. oper == '-'
  1024. counto = counto[1]
  1025. else:
  1026. oper = '+'
  1027. counto = str(counto)
  1028. elif oper == '-':
  1029. counto = -int(counto)-bb_int
  1030. counto = str(counto)[1]
  1031. if 'E(t)|' not in varn:
  1032. varn_new = varn.split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  1033. elif 'E(t)|' in varn and counto == '':
  1034. varn_new = varn.split('E(t)|')[1].split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  1035. elif 'E(t)|' in varn and int(counto) > 0:
  1036. varn_new = 'E(t)|'+varn.split('E(t)|')[1].split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  1037. elif 'E(t)|' in varn and int(counto) <= 0:
  1038. varn_new = varn.split('E(t)|')[1].split('(')[0].replace('-','').replace('+','')+'(t'+str(oper)+str(counto)+')'
  1039. # Compare this line with ff_chron_str, here I do not add any expectations term
  1040. str1 = str1[:varpos[0]]+varn_new+str1[varpos[1]:]
  1041. return str1
  1042. def ss_chron_str(self,str1=''):
  1043. '''
  1044. This turns all variables in an algebraic string expression into steady state equivalents.
  1045. '''
  1046. patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
  1047. try:
  1048. var_li = list(self.vreg(patup,str1,True,'max'))
  1049. except:
  1050. print "Model parsing error, problem with processing this text string:\n"+"'"+str1+"'."
  1051. sys.exit()
  1052. var_li.reverse()
  1053. for varo in var_li:
  1054. varn = varo[0]
  1055. varpos = varo[3]
  1056. if '|' in varn:
  1057. varn_new = varn.split('|')[1].split('(')[0]+'_bar'
  1058. else:
  1059. varn_new = varn.split('(')[0]+'_bar'
  1060. str1 = str1[:varpos[0]]+varn_new+str1[varpos[1]:]
  1061. return str1
  1062. def chg_vtimings(self,eqli,vdico):
  1063. vtiming = self._vtiming
  1064. for keyo in vdico.keys():
  1065. if vdico[keyo] != vtiming[keyo]:
  1066. diffli = list(np.array(vdico[keyo]) - np.array(vtiming[keyo]))
  1067. if diffli[0] < 0:
  1068. for i1,lino in enumerate(eqli):
  1069. if keyo == 'exo':
  1070. eqli[i1] = bb_chron_str(self,str1=eqli[i1],bb_int=abs(diffli[0]),vtype=keyo)
  1071. eqli[i1] = bb_chron_str(self,str1=eqli[i1],bb_int=abs(diffli[0]),vtype='iid')
  1072. else:
  1073. eqli[i1] = bb_chron_str(self,str1=eqli[i1],bb_int=abs(diffli[0]),vtype=keyo)
  1074. elif diffli[0] > 0:
  1075. for i1,lino in enumerate(eqli):
  1076. if keyo == 'exo':
  1077. eqli[i1] = ff_chron_str(self,str1=eqli[i1],ff_int=abs(diffli[0]),vtype=keyo)
  1078. eqli[i1] = ff_chron_str(self,str1=eqli[i1],ff_int=abs(diffli[0]),vtype='iid')
  1079. else:
  1080. eqli[i1] = ff_chron_str(self,str1=eqli[i1],ff_int=abs(diffli[0]),vtype=keyo)
  1081. return eqli
  1082. def mk_steady(self):
  1083. list_tmp2 = deepcopy(self.nlsubs_raw2)
  1084. _mreg = 'SS\{.*?\}'
  1085. mreg = re.compile(_mreg)
  1086. for i1,elem in enumerate(list_tmp2):
  1087. # If there is an unreplaced DIFF inside the SS, then skip for now...
  1088. if list_tmp2[i1][1][:2] == 'SS' and 'DIFF' in list_tmp2[i1][1][2:] : continue
  1089. while mreg.search(list_tmp2[i1][1]):
  1090. ma = mreg.search(list_tmp2[i1][1])
  1091. matn = ma.group()
  1092. starts = ma.start()
  1093. ends = ma.end()
  1094. str_tmp = matn
  1095. str_tmp = str_tmp.split('{')[1].split('}')[0]
  1096. str_tmp = ss_chron_str(self,str1=str_tmp)
  1097. list_tmp2[i1][1] = list_tmp2[i1][1][:starts]+str_tmp+list_tmp2[i1][1][ends:]
  1098. self.nlsubs_raw2 = deepcopy(list_tmp2)
  1099. return self
  1100. def mk_steady2(self):
  1101. list_tmp2 = deepcopy(self.foceqs2)
  1102. patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
  1103. vreg = self.vreg
  1104. for i1,elem in enumerate(list_tmp2):
  1105. varli = list(vreg(patup,list_tmp2[i1],True,'max'))
  1106. varli.reverse()
  1107. for varo in varli:
  1108. vpos = varo[3]
  1109. list_tmp2[i1] = list_tmp2[i1][:vpos[0]]+varo[2][1]+'_bar'+list_tmp2[i1][vpos[1]:]
  1110. self.foceqss = deepcopy(list_tmp2)
  1111. return self
  1112. def mk_timeshift(self):
  1113. list_tmp2 = deepcopy(self.nlsubs_raw2)
  1114. _mreg = '(?<=\*)FF[_](?P<fint>\d{1,2})\{.*?\}'
  1115. _mreg2 = '(?<=\*)BB[_](?P<bint>\d{1,2})\{.*?\}'
  1116. _mreg_b = '(?<!\*)FF[_](?P<fint>\d{1,2})\{.*?\}'
  1117. _mreg2_b = '(?<!\*)BB[_](?P<bint>\d{1,2})\{.*?\}'
  1118. _mreg3 = '\s*DIFF{.*?,.*?}\s*'
  1119. mreg = re.compile(_mreg)
  1120. mreg2 = re.compile(_mreg2)
  1121. mregb= re.compile(_mreg_b)
  1122. mreg2b = re.compile(_mreg2_b)
  1123. mreg3 = re.compile(_mreg3)
  1124. for i1,elem in enumerate(list_tmp2):
  1125. # First search for forward shifting terms
  1126. while mreg.search(list_tmp2[i1][1]):
  1127. ma = mreg.search(list_tmp2[i1][1])
  1128. matn = ma.group()
  1129. # Skip if the is a part which needs to be differentiated
  1130. if mreg3.search(matn): break
  1131. starts = ma.start()
  1132. ends = ma.end()
  1133. fint = int(ma.group('fint'))
  1134. str_tmp = matn
  1135. str_tmp = str_tmp.split('{')[1].split('}')[0]
  1136. str_tmp = ff_chron_str(self,str1=str_tmp,ff_int=fint)
  1137. list_tmp2[i1][1] = list_tmp2[i1][1][:starts]+str_tmp+list_tmp2[i1][1][ends:]
  1138. # First search for forward shifting terms
  1139. while mregb.search(list_tmp2[i1][1]):
  1140. ma = mregb.search(list_tmp2[i1][1])
  1141. matn = ma.group()
  1142. # Skip if the is a part which needs to be differentiated
  1143. if mreg3.search(matn): break
  1144. starts = ma.start()
  1145. ends = ma.end()
  1146. fint = int(ma.group('fint'))
  1147. str_tmp = matn
  1148. str_tmp = str_tmp.split('{')[1].split('}')[0]
  1149. str_tmp = ff_chron_str(self,str1=str_tmp,ff_int=fint)
  1150. list_tmp2[i1][1] = list_tmp2[i1][1][:starts]+str_tmp+list_tmp2[i1][1][ends:]
  1151. # Now search for backward shifting terms
  1152. while mreg2.search(list_tmp2[i1][1]):
  1153. ma = mreg2.search(list_tmp2[i1][1])
  1154. matn = ma.group()
  1155. # Skip if the is a part which needs to be differentiated
  1156. if mreg3.search(matn): break
  1157. starts = ma.start()
  1158. ends = ma.end()
  1159. bint = int(ma.group('bint'))
  1160. str_tmp = matn
  1161. str_tmp = str_tmp.split('{')[1].split('}')[0]
  1162. str_tmp = bb_chron_str(self,str1=str_tmp,bb_int=bint)
  1163. list_tmp2[i1][1] = list_tmp2[i1][1][:starts]+str_tmp+list_tmp2[i1][1][ends:]
  1164. # Now search for backward shifting terms
  1165. while mreg2b.search(list_tmp2[i1][1]):
  1166. ma = mreg2b.search(list_tmp2[i1][1])
  1167. matn = ma.group()
  1168. # Skip if the is a part which needs to be differentiated
  1169. if mreg3.search(matn): break
  1170. starts = ma.start()
  1171. ends = ma.end()
  1172. bint = int(ma.group('bint'))
  1173. str_tmp = matn
  1174. str_tmp = str_tmp.split('{')[1].split('}')[0]
  1175. str_tmp = bb_chron_str(self,str1=str_tmp,bb_int=bint)
  1176. list_tmp2[i1][1] = list_tmp2[i1][1][:starts]+str_tmp+list_tmp2[i1][1][ends:]
  1177. self.nlsubs_raw2 = deepcopy(list_tmp2)
  1178. return self
  1179. def ext_differ_out(self):
  1180. '''
  1181. This function will check differentiation instructions and augment the original one
  1182. for timeshifts and the discount factor
  1183. '''
  1184. list_tmp2 = deepcopy(self.nlsubs_raw2)
  1185. # Also allow for differentiation in substitution list
  1186. _mreg = '\s*DIFF{.*?,.*?}\s*'
  1187. mreg = re.compile(_mreg)
  1188. _mregv1 = '\w+\d*_bar'
  1189. patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
  1190. for kk1,elem in enumerate(list_tmp2):
  1191. # Skip any line in which the steady state needs to be take before DIFF
  1192. if list_tmp2[kk1][1][:4] == 'DIFF' and 'SS{' in list_tmp2[kk1][1]: continue
  1193. # Also skip cases such as @r_bar = DIFF{z_bar*k_bar**(rho)*l_bar**(1-rho),k_bar}
  1194. if list_tmp2[kk1][1][:4] == 'DIFF' and not self.vreg(patup,list_tmp2[kk1][1],True,'max') and\
  1195. "_bar" in list_tmp2[kk1][1].split(',')[1]: continue
  1196. if mreg.search(list_tmp2[kk1][1]):
  1197. maoutli = mreg.finditer(list_tmp2[kk1][1])
  1198. maoutli = [elem for elem in maoutli]
  1199. maoutli.reverse()
  1200. for maout in maoutli:
  1201. expout = maout.group()
  1202. starts_out = maout.start()
  1203. ends_out = maout.end()
  1204. evalstr = expout.replace('DIFF','')
  1205. evalstr = evalstr.replace('{','')
  1206. evalstr = evalstr.replace('}','')
  1207. differo = evalstr.split(',')[1]
  1208. evalstr = evalstr.split(',')[0]
  1209. # When the variable differo is steady state then we can skip this test
  1210. if '_bar' in differo: continue
  1211. # Should be only one variable, so take the first element
  1212. diff_li = list(self.vreg(patup,differo,True,'max'))[0]
  1213. var_li = list(self.vreg(patup,evalstr,True,'max'))
  1214. # Expectations timing and differos stem name
  1215. diff_conf = diff_li[2][:2]
  1216. # The differos time subscript
  1217. diff_conf2 = int(diff_li[2][-1])
  1218. # Check for case that we need to augment the expression to be differentiated
  1219. modcase = False
  1220. chrondiff = []
  1221. for elem in var_li:
  1222. if elem[2][:2] == diff_conf and int(elem[2][-1]) != diff_conf2:
  1223. chrondiff.append((-1)*(diff_conf2+int(elem[2][-1])))
  1224. modcase = True
  1225. if modcase:
  1226. if '@DISCOUNT' not in dict(self.nlsubs_raw2).keys():
  1227. print "ERROR: For this model you need to define the discount rate explicitly!"
  1228. print "You can do this by inserting the special reserved @DISCOUNT variable into the substitution section"
  1229. sys.exit()
  1230. else:
  1231. disco = dict(self.nlsubs_raw2)['@DISCOUNT']
  1232. maxfor = max(chrondiff)
  1233. minfor = min(chrondiff)
  1234. finalexp = 'DIFF{'+evalstr
  1235. for kk2 in range(minfor,maxfor+1):
  1236. if kk2 == 0: continue
  1237. elif kk2 > 0: finalexp += '+'+disco+'**'+'('+str(kk2)+')'+'*FF_'+str(kk2)+'{'+evalstr+'}'
  1238. elif kk2 < 0: finalexp += '+'+disco+'**'+'('+str(-kk2)+')'+'*BB_'+str(kk2)+'{'+evalstr+'}'
  1239. finalexp += ','+differo+'}'
  1240. list_tmp2[kk1][1] = list_tmp2[kk1][1][:starts_out]+finalexp+list_tmp2[kk1][1][ends_out+1:]
  1241. self.nlsubs_raw2 = deepcopy(list_tmp2)
  1242. return self
  1243. def differ_out(self):
  1244. # Copy in raw nlsubs which has substitutions inside
  1245. # substitutions already replaced by previous function call
  1246. list_tmp2 = deepcopy(self.nlsubs_raw2)
  1247. # Also allow for differentiation in substitution list
  1248. _mreg = '\s*DIFF{.*?,.*?}\s*'
  1249. mreg = re.compile(_mreg)
  1250. _mregv1 = '\w+\d*_bar'
  1251. _mregv1b = '(?<!E)\(t[\+|-]{0,1}\d{0,2}\)'
  1252. mregv1b = re.compile(_mregv1b)
  1253. _mregv1b2 = '(?<!E)__ll__t[\+|-]{0,1}\d{0,2}__rr__'
  1254. mregv1b2 = re.compile(_mregv1b)
  1255. _mregv1bb = '\(t[\+|-]\d{1,2}\)'
  1256. mregv1bb = re.compile(_mregv1bb)
  1257. _mregv1bb2 = '__l__t[\+|-]\d{1,2}__r__'
  1258. mregv1bb2 = re.compile(_mregv1bb2)
  1259. _mregv1c = '\([p+|m+]\)'
  1260. mregv1c = re.compile(_mregv1c)
  1261. _mregv1d = 'E\(t[\+|-]{0,1}\d{0,2}\)\|'
  1262. mregv1d = re.compile(_mregv1d)
  1263. _mregv1e = 'E\[t[\+|-]{0,1}\d{0,2}]\|'
  1264. mregv1e = re.compile(_mregv1e)
  1265. _mreglog = 'LOG\(.*?\)'
  1266. _mregexp = 'EXP\(.*?\)'
  1267. mregle_ng = re.compile(_mregexp+'|'+_mreglog)
  1268. _mreglog2 = 'LOG\[.*?]'
  1269. _mregexp2 = 'EXP\[.*?]'
  1270. mregle2_ng = re.compile(_mregexp2+'|'+_mreglog2)
  1271. _mreglog = 'LOG\(.*\)'
  1272. _mregexp = 'EXP\(.*\)'
  1273. mregle_gg = re.compile(_mregexp+'|'+_mreglog)
  1274. _mreglog2 = 'LOG\[.*]'
  1275. _mregexp2 = 'EXP\[.*]'
  1276. mregle2_gg = re.compile(_mregexp2+'|'+_mreglog2)
  1277. _mregsh = '(?<!DI)FF[_]\d{1,2}|BB[_]\d{1,2}'
  1278. mregsh = re.compile(_mregsh)
  1279. patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
  1280. # Collect some necessary info for steady state substitutions
  1281. var_bar = []
  1282. for elem in ['con','endo','exo','other']:
  1283. tmp_li = [x[0].split('(')[0]+'_bar' for x in self.vardic[elem]['var']]
  1284. for elem2 in tmp_li:
  1285. var_bar.append(elem2)
  1286. for kk1,elem in enumerate(list_tmp2):
  1287. # Skip any line in which
  1288. if list_tmp2[kk1][1][:4] == 'DIFF' and 'SS{' in list_tmp2[kk1][1]: continue
  1289. while mreg.search(list_tmp2[kk1][1]):
  1290. maout = mreg.search(list_tmp2[kk1][1])
  1291. expout = maout.group()
  1292. starts_out = maout.end()
  1293. ends_out = maout.start()
  1294. evalstr = expout.replace('DIFF','')
  1295. evalstr = evalstr.replace('{','')
  1296. evalstr = evalstr.replace('}','')
  1297. differo = evalstr.split(',')[1]
  1298. # Skip if differo still has uncomputed timeshifter
  1299. if mregsh.search(differo): break
  1300. # Also skip if evalstr has uncomputed timeshifter
  1301. if mregsh.search(evalstr): break
  1302. evalstr = evalstr.split(',')[0]
  1303. time_vars = False
  1304. var_li = self.vreg(patup,evalstr,True,'max')
  1305. if var_li: time_vars = True
  1306. #########################################################
  1307. # Do for steady state expressions, as is very easy, CASE1
  1308. #########################################################
  1309. if '_bar' in evalstr and not time_vars and '_bar' in differo:
  1310. # Now substitute out exp and log in terms of sympycore expressions
  1311. elog = re.compile('LOG\(')
  1312. while elog.search(evalstr):
  1313. ma = elog.search(evalstr)
  1314. pos = ma.span()[0]
  1315. poe = ma.span()[1]
  1316. evalstr = evalstr[:pos]+'SP.log('+evalstr[poe:]
  1317. eexp = re.compile('EXP\(')
  1318. while eexp.search(evalstr):
  1319. ma = eexp.search(evalstr)
  1320. pos = ma.span()[0]
  1321. poe = ma.span()[1]
  1322. evalstr = evalstr[:pos]+'SP.exp('+evalstr[poe:]
  1323. # Now populate scope with sympy symbols
  1324. tmp_dic={}
  1325. for elem in var_bar:
  1326. tmp_dic[elem] = SP.Symbol(elem)
  1327. locals().update(tmp_dic)
  1328. tmp_dic = {}
  1329. for elem in self.paramdic.keys():
  1330. tmp_dic[elem] = SP.Symbol(elem)
  1331. locals().update(tmp_dic)
  1332. # Also expose any variables from the ssidic, just in case
  1333. tmp_dic = {}
  1334. for elem in self.ssidic.keys():
  1335. tmp_dic[elem] = SP.Symbol(elem)
  1336. locals().update(tmp_dic)
  1337. # Also expose the differo variable
  1338. locals()[differo] = SP.Symbol(differo)
  1339. # Population of scope done, now do calculation and continue in loop
  1340. expr_bar = eval(evalstr)
  1341. resstr = expr_bar.diff(locals()[str(differo)])
  1342. list_tmp2[kk1][1] = str(resstr)
  1343. continue
  1344. ##############################################################################
  1345. # Do for steady state expressions, as is very easy, CASE2, needs working varli
  1346. ##############################################################################
  1347. ############## Generate varli only here, as it was not needed above (it was, but only for testing) ###############
  1348. try:
  1349. var_li = list(self.vreg(patup,evalstr,True,'max'))
  1350. if var_li: time_vars = True
  1351. except:
  1352. print "Model parsing error, problem with processing this text string:\n"+"'"+list_tmp2[kk1][0]+" = "+list_tmp2[kk1][1]+"'."
  1353. sys.exit()
  1354. ###################################################################################################################
  1355. if '_bar' not in evalstr and not time_vars and '_bar' in differo:
  1356. # First replace all chronological variables in evalstr with _bar equivalents
  1357. varbar_li = deepcopy(var_li)
  1358. varbar_li.reverse()
  1359. for varo in varbar_li:
  1360. vpos = varo[3]
  1361. evalstr = evalstr[:vpos[0]]+varo[2][1]+'_bar'+evalstr[vpos[1]:]
  1362. # Now substitute out exp and log in terms of sympycore expressions
  1363. elog = re.compile('LOG\(')
  1364. while elog.search(evalstr):
  1365. ma = elog.search(evalstr)
  1366. pos = ma.span()[0]
  1367. poe = ma.span()[1]
  1368. evalstr = evalstr[:pos]+'SP.log('+evalstr[poe:]
  1369. eexp = re.compile('EXP\(')
  1370. while eexp.search(evalstr):
  1371. ma = eexp.search(evalstr)
  1372. pos = ma.span()[0]
  1373. poe = ma.span()[1]
  1374. evalstr = evalstr[:pos]+'SP.exp('+evalstr[poe:]
  1375. # Now populate scope with sympy symbols
  1376. tmp_dic={}
  1377. for elem in var_bar:
  1378. tmp_dic[elem] = SP.Symbol(elem)
  1379. locals().update(tmp_dic)
  1380. tmp_dic = {}
  1381. for elem in self.paramdic.keys():
  1382. tmp_dic[elem] = SP.Symbol(elem)
  1383. locals().update(tmp_dic)
  1384. # Also expose any variables from the ssidic, just in case
  1385. tmp_dic = {}
  1386. for elem in self.ssidic.keys():
  1387. tmp_dic[elem] = SP.Symbol(elem)
  1388. locals().update(tmp_dic)
  1389. # Also expose the differo variable
  1390. locals()[differo] = SP.Symbol(differo)
  1391. # Population of scope done, now do calculation and continue in loop
  1392. expr_bar = eval(evalstr)
  1393. resstr = expr_bar.diff(locals()[str(differo)])
  1394. list_tmp2[kk1][1] = str(resstr)
  1395. continue
  1396. ###################################################
  1397. # Steady State branch ends here
  1398. ###################################################
  1399. var_li2 = deepcopy(var_li)
  1400. var_li2.reverse()
  1401. ss_li = [x[2][1]+'_bar' for x in var_li2]
  1402. # Replace t+1 or t-1 with something without the operators, in evalstr
  1403. for jj1,elem in enumerate(var_li2):
  1404. tmp_li = list(elem)
  1405. # Replace expectations operators with something else inside evalstr
  1406. if mregv1d.search(tmp_li[0]):
  1407. ma = mregv1d.search(tmp_li[0])
  1408. vname = ma.group()
  1409. ends = ma.end()
  1410. starts = ma.start()
  1411. vname = vname.replace('(','__ll__')
  1412. vname = vname.replace(')','__rr__')
  1413. vname = vname.replace('|','DELIM__')
  1414. tmp_li[0] = tmp_li[0][:starts]+vname+tmp_li[0][ends:]
  1415. evalstr = evalstr[:elem[3][0]]+tmp_li[0].\
  1416. replace('(','__l__').\
  1417. replace(')','__r__').\
  1418. replace('|','DELIM__')+\
  1419. evalstr[elem[3][1]:]
  1420. # Replace expectations operators with something else inside varli
  1421. for i1,varo in enumerate(var_li):
  1422. if mregv1d.search(varo[0]):
  1423. str1 = varo[0].split('|')[1]
  1424. str2 = varo[0].split('|')[0]
  1425. str2 = str2.replace('(','__ll__')
  1426. str2 = str2.replace(')','__rr__')
  1427. var_li[i1] = list(varo)
  1428. var_li[i1][0] = str2+'DELIM__'+str1
  1429. # Replace the LOGs and EXPs with square brackets
  1430. while mregle_ng.search(evalstr):
  1431. ma = mregle_ng.search(evalstr)
  1432. starts = ma.start()
  1433. ends = ma.end()
  1434. evalstr = evalstr[:ends-1] + ']' + evalstr[ends:]
  1435. evalstr = evalstr[:starts+3] + '[' + evalstr[starts+4:]
  1436. # Replace t+1 or t-1 with something without the operators, inside var_li
  1437. for i1,varo in enumerate(var_li):
  1438. var_li[i1] = list(varo)
  1439. ma = mregv1bb.search(varo[0])
  1440. if ma:
  1441. ends = ma.end()
  1442. starts = ma.start()
  1443. if '+' in varo[0]:
  1444. str1 = varo[0].split('(')[0]
  1445. counto = varo[0].split('+')[1][0]
  1446. var_li[i1][0] = str1+'__l__'+int(counto)*'p' + '__r__'
  1447. if '-' in varo[0]:
  1448. str1 = varo[0].split('(')[0]
  1449. counto = varo[0].split('-')[1][0]
  1450. var_li[i1][0] = str1+'__l__'+int(counto)*'m' + '__r__'
  1451. while mregv1bb2.search(evalstr):
  1452. ma = mregv1bb2.search(evalstr)
  1453. varn = ma.group()
  1454. ends = ma.end()
  1455. starts = ma.start()
  1456. if '+' in varn:
  1457. str1 = varn.split('__l__')[0]
  1458. counto = varn.split('+')[1][0]
  1459. varn_new = str1+'__l__'+int(counto)*'p' + '__r__'
  1460. evalstr = evalstr[:starts]+varn_new+evalstr[ends:]
  1461. if '-' in varn:
  1462. str1 = varn.split('__l__')[0]
  1463. counto = varn.split('-')[1][0]
  1464. varn_new = str1+'__l__'+int(counto)*'m' + '__r__'
  1465. evalstr = evalstr[:starts]+varn_new+evalstr[ends:]
  1466. # Replace left and right round brackets for variables and expose to sympycore
  1467. for i1,varo in enumerate(var_li):
  1468. str_tmp2 = var_li[i1][0]
  1469. str_tmp2 = str_tmp2.replace('(','__l__')
  1470. str_tmp2 = str_tmp2.replace(')','__r__')
  1471. locals()[str_tmp2] = SP.Symbol(str_tmp2)
  1472. for varo in self.paramdic.keys(): locals()[varo] = SP.Symbol(varo)
  1473. # Replace left and right round brackets for the differo variable and expose to sympycore
  1474. str_tmp3 = deepcopy(differo)
  1475. # First, also check for (t+x),(t-x) or (t) in differo and replace with something readable by sympycore
  1476. while mregv1b.search(str_tmp3):
  1477. ma = mregv1b.search(str_tmp3)
  1478. ends = ma.end()
  1479. starts = ma.start()
  1480. if '+' in str_tmp3:
  1481. counto = str_tmp3.split('+')[-1][0]
  1482. post = str_tmp3[starts:]
  1483. pre = str_tmp3[:starts]
  1484. # Also replace brackets
  1485. if ')' in pre: pre = pre.replace(')','__rr__')
  1486. if '(' in pre: pre = pre.replace('(','__ll__')
  1487. if ')' in post: post = post.replace(')','__r__')
  1488. if '(' in post: post = post.replace('(','__l__')
  1489. str_tmp3 = pre+'__l__'+int(counto)*'p' + '__r__'
  1490. elif '-' in str_tmp3:
  1491. counto = str_tmp3.split('-')[-1][0]
  1492. post = str_tmp3[starts:]
  1493. pre = str_tmp3[:starts]
  1494. # Also replace brackets
  1495. if ')' in pre: pre = pre.replace(')','__rr__')
  1496. if '(' in pre: pre = pre.replace('(','__ll__')
  1497. if ')' in post: post = post.replace(')','__r__')
  1498. if '(' in post: post = post.replace('(','__l__')
  1499. str_tmp3 = pre+'__l__'+int(counto)*'m' + '__r__'
  1500. else:
  1501. post = str_tmp3[starts:]
  1502. pre = str_tmp3[:starts]
  1503. # Also replace brackets
  1504. if ')' in pre: pre = pre.replace(')','__rr__')
  1505. if '(' in pre: pre = pre.replace('(','__ll__')
  1506. if ')' in post: post = post.replace(')','__r__')
  1507. if '(' in post: post = post.replace('(','__l__')
  1508. str_tmp3 = pre+'__l__'+'t' + '__r__'
  1509. differo_new = deepcopy(str_tmp3)
  1510. # Also replace the delimiter when expectations are present in differo
  1511. while '|' in differo_new: differo_new = differo_new.replace('|','DELIM__')
  1512. locals()[differo_new] = SP.Symbol(differo_new)
  1513. # Replace left and right brackets for the entire expression before calling diff
  1514. var_li.reverse()
  1515. for varo in var_li:
  1516. varn_orig = varo[0]
  1517. varn = varo[0].replace(')','__r__')
  1518. varn = varn.replace('(','__l__')
  1519. evalstr = evalstr.replace(varn_orig, varn)
  1520. # Replace the LOGs and EXPs with round brackets again
  1521. while mregle2_ng.search(evalstr):
  1522. ma = mregle2_ng.search(evalstr)
  1523. starts = ma.start()
  1524. ends = ma.end()
  1525. evalstr = evalstr[:ends-1] + ')' + evalstr[ends:]
  1526. evalstr = evalstr[:starts+3] + '(' + evalstr[starts+4:]
  1527. # Now substitute out exp and log in terms of sympycore expressions
  1528. elog = re.compile('LOG\(')
  1529. while elog.search(evalstr):
  1530. ma = elog.search(evalstr)
  1531. pos = ma.span()[0]
  1532. poe = ma.span()[1]
  1533. evalstr = evalstr[:pos]+'SP.log('+evalstr[poe:]
  1534. eexp = re.compile('EXP\(')
  1535. while eexp.search(evalstr):
  1536. ma = eexp.search(evalstr)
  1537. pos = ma.span()[0]
  1538. poe = ma.span()[1]
  1539. evalstr = evalstr[:pos]+'SP.exp('+evalstr[poe:]
  1540. # Now evaluate and differentiate
  1541. # Before evaluating expose the self.paramdic and self.ssidic to locals
  1542. tmp_dic = {}
  1543. for elem in self.paramdic.keys():
  1544. tmp_dic[elem] = SP.Symbol(elem)
  1545. locals().update(tmp_dic)
  1546. # Also expose any variables from the ssidic, just in case
  1547. if 'ssidic' in dir(self):
  1548. tmp_dic = {}
  1549. for elem in self.ssidic.keys():
  1550. tmp_dic[elem] = SP.Symbol(elem)
  1551. locals().update(tmp_dic)
  1552. # Also expose any variables from the ss_li, just in case
  1553. tmp_dic = {}
  1554. for elem in ss_li:
  1555. tmp_dic[elem] = SP.Symbol(elem)
  1556. locals().update(tmp_dic)
  1557. expr = eval(evalstr)
  1558. try:
  1559. expr = eval(evalstr)
  1560. except:
  1561. print "Parse ERROR: Could not evaluate/differentiate expression: "
  1562. print list_tmp2[kk1][0]+" = "+list_tmp2[kk1][1]
  1563. sys.exit()
  1564. resstr = expr.diff(locals()[str(differo_new)])
  1565. resstr = str(resstr)
  1566. # Now switch back to normal notation with brackets
  1567. while '__l__' in resstr:
  1568. resstr = resstr.replace('__l__','(')
  1569. while '__r__' in resstr:
  1570. resstr = resstr.replace('__r__',')')
  1571. while '__ll__' in resstr:
  1572. resstr = resstr.replace('__ll__','(')
  1573. while '__rr__' in resstr:
  1574. resstr = resstr.replace('__rr__',')')
  1575. # Also replace the DELIM with |
  1576. while 'DELIM__' in resstr: resstr = resstr.replace('DELIM__','|')
  1577. # Now also switch back to normal t+1/t-x notation
  1578. while mregv1c.search(resstr):
  1579. ma = mregv1c.search(resstr)
  1580. ends = ma.end()
  1581. starts = ma.start()
  1582. str3 = ma.group()
  1583. lengo = len(str3[1:-1])
  1584. if 'p' in str3: resstr = resstr[:starts]+'(t+'+str(lengo)+')'+resstr[ends:]
  1585. elif 'm' in str3: resstr = resstr[:starts]+'(t-'+str(lengo)+')'+resstr[ends:]
  1586. # Replace with the differentiate term, but also take brackets around it just in case
  1587. list_tmp2[kk1][1] = list_tmp2[kk1][1].replace(expout,'('+resstr+')')
  1588. self.nlsubs_raw2 = deepcopy(list_tmp2)
  1589. self.nlsubs = deepcopy(dict(list_tmp2))
  1590. self.nlsubs_list = deepcopy(list_tmp2)
  1591. return self
  1592. def premknonlinsys(self,secs):
  1593. '''
  1594. This takes the raw lines of the FOCs and does some joining, splitting and stripping
  1595. '''
  1596. # Make the non-linear system by joining lines and stripping
  1597. list_tmp1 = []
  1598. i1 = 0
  1599. linecounter = 0
  1600. for x in secs['focs'][0]:
  1601. if x.endswith(('...','\\')):
  1602. linecounter += 1
  1603. else:
  1604. if linecounter == 0:
  1605. if ']' in x: line = x.replace(';','').split(']')[1].strip()
  1606. else: line = x.replace(';','').strip()
  1607. line = line.split('=')[0].strip()
  1608. list_tmp1.append(line)
  1609. elif linecounter > 0:
  1610. str_tmp = ''
  1611. for y in secs['focs'][0][i1-linecounter:i1+1]:
  1612. if ']' in y: str_tmp += y.split(']')[1].replace('...','').replace('\\','').replace(';','').strip()
  1613. else: str_tmp += y.replace('...','').replace('\\','').replace(';','').strip()
  1614. if ']' in x: line = str_tmp.split(']')[1].strip()
  1615. else: line = str_tmp.strip()
  1616. linecounter = 0
  1617. line = line.split('=')[0].strip()
  1618. list_tmp1.append(line)
  1619. i1 += 1
  1620. self.foceqs = deepcopy(list_tmp1)
  1621. return self
  1622. def premknonlinsys2(self, secs):
  1623. list_tmp1 = deepcopy(self.foceqs)
  1624. variables = deepcopy(self.subs_vars)
  1625. subs_found = []
  1626. i1 = 0
  1627. for x in list_tmp1:
  1628. # substitute out in main nonlinear equation system
  1629. list_tmp2 = deepcopy(self.nlsubs_list)
  1630. mreg = re.compile('@(E\(t.*?\)\|){0,1}.*?\(t.*?\)')
  1631. for i,x in enumerate(list_tmp1):
  1632. rhs_eq = list_tmp1[i]
  1633. while mreg.search(rhs_eq):
  1634. ma = mreg.search(rhs_eq)
  1635. subv = ma.group()
  1636. if subv not in subs_found: subs_found.append(subv)
  1637. pos, poe = ma.span()
  1638. indx = variables.index(subv)
  1639. rhs_eq = rhs_eq[:pos]+'('+list_tmp2[indx][1]+')'+\
  1640. rhs_eq[poe:]
  1641. list_tmp1[i] = rhs_eq
  1642. i1+=1
  1643. self.foceqs2 = deepcopy(list_tmp1)
  1644. self.subs_found = deepcopy(subs_found)
  1645. # Remove the elements from nlsubs_list which were not found in the nlsys_list!
  1646. # This is important because pymaclab also generates equations (and auxiliary variables)
  1647. # for the expressions declared in the nonlinear substitution system
  1648. self.nlsubs_list = [x for x in self.nlsubs_list if x[0] in self.subs_found]
  1649. for i1,elem in enumerate(self.vardic['other']['var']):
  1650. if '@'+elem[0] not in self.subs_found:
  1651. self.vardic['other']['var'].pop(i1)
  1652. self.vardic['other']['mod'].pop(i1)
  1653. return self
  1654. def mknonlinsys(self, secs):
  1655. """
  1656. Create Non-Linear FOC System
  1657. """
  1658. # Here we introduce time-shifted auxiliary variables into the system of FOCs if needed
  1659. # and also add them to the vardic and audic, also new variables get added to bottom of nlsys_list
  1660. # The returned list is just the new augmented nlsys_list with the auxiliary variables in the system
  1661. list_tmp1 = deepcopy(self.foceqs2)
  1662. self, list_tmp1 = mkaug2(self,insys=list_tmp1,othersys=None)
  1663. if all([False if 'None' in x else True for x in secs['vsfocs'][0]]):
  1664. ## The point of this section below this conditional test is to replace variables
  1665. ## inside nlsubs_list with their time-shifted (auxiliary) equivalent
  1666. ## When doing so we may need to add newly found auxiliary variables to the bottom of nlsys_list
  1667. variables = deepcopy(self.subs_vars)
  1668. # Here we do the substitutions inside the variable substitution list, outup contains two lists
  1669. list_tmp3 = [x[1] for x in deepcopy(self.nlsubs_list)]
  1670. self, outtup = mkaug2(self,insys=list_tmp3,othersys=list_tmp1)
  1671. # Then the equation expressions (declarations) with substituted time elements get inserted back in
  1672. list_tmp3 = outtup[0] # This is the system of substitutions
  1673. list_tmp2 = deepcopy(self.nlsubs_list) # This is the old system of substitutions, needs updating
  1674. list_tmp1 = outtup[1] # This is the FOC system
  1675. for i1,x in enumerate(list_tmp3):
  1676. list_tmp2[i1][1] = list_tmp3[i1]
  1677. # Below all other objects get updated in order to take information into account
  1678. # which was computed in the above
  1679. self.nlsubs = dict(list_tmp2)
  1680. nlsubs2 = {}
  1681. for x in [x[0] for x in self.vardic['other']['var']]:
  1682. nlsubs2[x] = self.nlsubs['@'+x]
  1683. self.nlsubs2 = nlsubs2
  1684. # Create ordered nlsubsys
  1685. if self.vardic['other']['var']:
  1686. nlsubsys = []
  1687. varother = self.vardic['other']['var']
  1688. for vari in [x[0] for x in varother]:
  1689. nlsubsys.append(nlsubs2[vari])
  1690. self.nlsubsys = nlsubsys
  1691. # Count the number of distinct forward expectations
  1692. # AND the no of equations that contain them
  1693. ffli = []
  1694. count = 0
  1695. patup = ('0','endo|con|exo','{1,10}')
  1696. for line in list_tmp1[:-self.nexo]:
  1697. outli = self.vreg(patup,line,True,'min')
  1698. if outli:
  1699. count = count + 1
  1700. for elem in [x[0] for x in outli]:
  1701. if elem not in ffli:
  1702. ffli.append(elem)
  1703. self.ffen = count
  1704. self.ffli = ffli
  1705. self.fflin = len(ffli)
  1706. # Now create simplified vdic with possibly new augmented vars
  1707. vdic = dict([[x,self.vardic[x]['var']] for x in self.vardic.keys()])
  1708. self.vdic = vdic
  1709. # Finally, recomputed nendo, ncon, etc.
  1710. self.nendo = len(self.vardic['endo']['var'])
  1711. self.nexo = len(self.vardic['exo']['var'])
  1712. self.ncon = len(self.vardic['con']['var'])
  1713. self.nother = len(self.vardic['other']['var'])
  1714. self.nstat = self.nendo+self.nexo
  1715. self.nall = self.nstat+self.ncon
  1716. self.nlsys_list = deepcopy(list_tmp1)
  1717. return self
  1718. def mkloglinsys2(self, inlist):
  1719. """
  1720. This function simply takes the left-hand side
  1721. of each equation and takes it over to the
  1722. right-hand side with a minus sign in front.
  1723. Now we have equations of the form g(x)=0.
  1724. Also takes care of fact that the term may
  1725. already be negative. Also takes into account
  1726. that some equations have already been written
  1727. as g(x)=0!
  1728. """
  1729. _revar='(E\(t-{0,1}\+{0,1}\d*\)\|){0,1}[a-z]*(\(t-{0,1}\+{0,1}\d*\)){1,1}'
  1730. re_var = re.compile(_revar)
  1731. list_tmp1 = deepcopy(inlist)
  1732. str_tmp2 = ''
  1733. i1 = 0
  1734. while i1 < len(list_tmp1):
  1735. if list_tmp1[i1].split('=')[0].strip().strip(';') == '0':
  1736. list_tmp1[i1] = list_tmp1[i1].split('=')[1].strip().strip(';')
  1737. i1 = i1 + 1
  1738. continue
  1739. elif list_tmp1[i1].split('=')[1].strip().strip(';') == '0':
  1740. list_tmp1[i1] = list_tmp1[i1].split('=')[0].strip().strip(';')
  1741. i1 = i1 + 1
  1742. continue
  1743. list_tmp1[i1] = list_tmp1[i1].strip(';')[:]
  1744. str_tmp2 = list_tmp1[i1].split('=')[0].strip()
  1745. list_tmp1[i1] = list_tmp1[i1].split('=')[1].strip()
  1746. while re_var.search(str_tmp2):
  1747. ma1 = re_var.search(str_tmp2)
  1748. pos1 = ma1.span()[0]
  1749. poe1 = ma1.span()[1]
  1750. # for coeff*var and coeff not begins with '-', but '+'
  1751. if pos1 > 1 and str_tmp2[0] != '-' and str_tmp2[0] == '+':
  1752. coeff = '-'+str_tmp2[1:pos1]
  1753. vari = ma1.group(0)
  1754. str_tmp2=str_tmp2[poe1:]
  1755. if str_tmp2 == '':
  1756. str_tmp2 = '@'
  1757. # for coeff*var and coeff not begins with '+', but '-'
  1758. elif pos1 > 1 and str_tmp2[0] != '+' and str_tmp2[0] == '-':
  1759. coeff = '+'+str_tmp2[1:pos1]
  1760. vari = ma1.group(0)
  1761. str_tmp2=str_tmp2[poe1:]
  1762. if str_tmp2 == '':
  1763. str_tmp2 = '@'
  1764. # for coeff*var and coeff not begins with '+' and not begins with '-'
  1765. elif pos1 > 1 and str_tmp2[0] != '+' and str_tmp2[0] != '-':
  1766. coeff = '-'+str_tmp2[:pos1]
  1767. vari = ma1.group(0)
  1768. str_tmp2=str_tmp2[poe1:]
  1769. if str_tmp2 == '':
  1770. str_tmp2 = '@'
  1771. # for coeff == '-'
  1772. elif pos1 == 1 and str_tmp2[0] == '-':
  1773. coeff = '+'
  1774. vari = ma1.group(0)
  1775. str_tmp2=str_tmp2[poe1:]
  1776. # for coeff == '+'
  1777. elif pos1 == 1 and str_tmp2[0] == '+':
  1778. coeff = '-'
  1779. vari = ma1.group(0)
  1780. str_tmp2=str_tmp2[poe1:]
  1781. # for var*coeff
  1782. elif pos1 == 0 and len(re_var.findall(str_tmp2)) > 1\
  1783. and str_tmp2[poe1] != '-' and str_tmp2[poe1] != '+':
  1784. ma2 = re_var.search(str_tmp2[poe1:])
  1785. pos2 = ma2.span()[0]+poe1
  1786. coeff = '-'+str_tmp2[poe1:pos2]
  1787. vari = ma1.group(0)
  1788. str_tmp2=str_tmp2[pos2:]
  1789. # for last bit
  1790. elif pos1 == 0 and len(re_var.findall(str_tmp2)) == 1:
  1791. coeff = '-'+str_tmp2[1:][poe1-1:]
  1792. vari = ma1.group(0)
  1793. str_tmp2=''
  1794. # for coeff == ''
  1795. elif pos1 == 0 and len(re_var.findall(str_tmp2)) > 1 and str_tmp2[poe1] == '-':
  1796. coeff = '-'
  1797. vari = ma1.group(0)
  1798. str_tmp2=str_tmp2[poe1:]
  1799. # for coeff == ''
  1800. elif pos1 == 0 and len(re_var.findall(str_tmp2)) > 1 and str_tmp2[poe1] == '+':
  1801. coeff = '-'
  1802. vari = ma1.group(0)
  1803. str_tmp2=str_tmp2[poe1:]
  1804. # for last bit
  1805. elif pos1 == 0 and len(re_var.findall(str_tmp2)) == 1:
  1806. coeff = '-'
  1807. vari = ma1.group(0)
  1808. str_tmp2=''
  1809. if coeff[-1] != '*' and coeff != '-':
  1810. coeff = coeff+'*'
  1811. list_tmp1[i1] = list_tmp1[i1]+coeff+vari
  1812. str_tmp2 = ''
  1813. i1 = i1 + 1
  1814. self.nlsys_list = deepcopy(list_tmp1)
  1815. return list_tmp1
  1816. def subs_in_loglinsys(self):
  1817. list_tmp1 = deepcopy(self.llsys_list)
  1818. subsdic = deepcopy(self.nlsubs)
  1819. for i1,eqo in enumerate(list_tmp1):
  1820. while "@" in list_tmp1[i1]:
  1821. for keyo in subsdic.keys():
  1822. if keyo in list_tmp1[i1]: list_tmp1[i1] = list_tmp1[i1].replace(keyo,subsdic[keyo])
  1823. return list_tmp1
  1824. # Creates the log-linear system
  1825. def mkloglinsys1(secs):
  1826. list_tmp = []
  1827. i1=0
  1828. counter=0
  1829. for x in secs['modeq'][0]:
  1830. if '...' in x:
  1831. counter = counter + 1
  1832. elif '...' not in x:
  1833. if counter == 0:
  1834. list_tmp.append(x.replace(';','').split(']')[1].strip())
  1835. elif counter > 0:
  1836. str_tmp = ''
  1837. for y in secs['modeq'][0][i1-counter:i1+1]:
  1838. str_tmp = str_tmp + y.replace('...','').replace(';','').strip()
  1839. list_tmp.append(str_tmp.split(']')[1].strip())
  1840. counter = 0
  1841. i1=i1+1
  1842. return list_tmp
  1843. # Create a Variance-Covariance matrix
  1844. def mksigmat(self, secs):
  1845. str_tmp1 = []
  1846. str_tmp1 = secs['vcvm'][0][0].split('[')[1].rstrip()
  1847. if str_tmp1[-2:] == '];':
  1848. str_tmp1=str_tmp1[:-2]
  1849. if len(secs['vcvm']) > 1:
  1850. for x in secs['vcvm'][0][1:]:
  1851. if x[-2:] != '];':
  1852. str_tmp1=str_tmp1+x.lstrip().rstrip()[:]
  1853. elif x[-2:] == '];':
  1854. str_tmp1=str_tmp1+x.lstrip().rstrip()[:-2]
  1855. locals().update(self.paramdic)
  1856. locals().update(self.sstate)
  1857. list_tmp1 = str_tmp1.split(';')
  1858. len1 = len(list_tmp1[0].split())
  1859. mat1=mat.zeros((len1,len1))
  1860. i1=0
  1861. for x in list_tmp1:
  1862. i2=0
  1863. # Just another trap, only to be sure...
  1864. if ']' in x: x = x.replace(']','')
  1865. if '[' in x: x = x.replace('[','')
  1866. for y in x.split():
  1867. mat1[i1,i2] = float(eval(y))
  1868. i2=i2+1
  1869. i1=i1+1
  1870. return mat1
  1871. def mkeqtype(self):
  1872. lsys = self.llsys_list
  1873. tup1 = ('{-1,1}|None','iid|exo','{-1,1}')
  1874. tup2 = ('{-1,1}|None','all','{-1,1}')
  1875. tup3 = ('{-1,1}','all','{-1,1}')
  1876. err_indx = []
  1877. det_indx = []
  1878. exp_indx = []
  1879. for x,y in zip(lsys,range(len(lsys))):
  1880. if self.vreg(('{-1,1}','all','{-1,1}'),x,False,'max'):
  1881. exp_indx.append(y)
  1882. elif self.vreg((None,'exo|iid','{-1,1}'),x,False,'max'):
  1883. if len(self.vreg((None,'exo|iid','{-1,1}'),x,True,'max'))==\
  1884. len(self.vreg(('{-1,1}|None','all','{-1,1}'),x,True,'max')):
  1885. err_indx.append(y)
  1886. else:
  1887. det_indx.append(y)
  1888. else:
  1889. det_indx.append(y)
  1890. self.eqindx = {}
  1891. self.eqindx['err'] = err_indx
  1892. self.eqindx['det'] = det_indx
  1893. self.eqindx['exp'] = exp_indx
  1894. return self
  1895. # Make symbolic system and numeric as well
  1896. def mksymsys(self):
  1897. _mreg = 'E{1,1}[^(]'
  1898. mreg = re.compile(_mreg)
  1899. func = []
  1900. subli = []
  1901. patup = ('{-10,10}|None','all','{-10,10}')
  1902. for x in self.sstate.keys()+self.paramdic.keys():
  1903. locals()[x] = eval("SP.Symbol('"+x+"')")
  1904. for y in self.llsys_list:
  1905. str_tmp = y[:]
  1906. while 'EXP(' in str_tmp:
  1907. str_tmp = str_tmp.replace('EXP(','SP.exp(')
  1908. while 'LOG(' in str_tmp:
  1909. str_tmp = str_tmp.replace('LOG(','SP.log(')
  1910. vali = [x[0] for x in self.vreg(patup,y,True,'min')]
  1911. vali2 = [[x,'sub'+str(u)] for x,u in zip(vali,range(0,len(vali),1))]
  1912. vali3 = [(x[0],x[3]) for x in self.vreg(patup,str_tmp,True,'max')]
  1913. vali3.reverse()
  1914. valdic = dict(vali2)
  1915. for x in vali3:
  1916. str_tmp = str_tmp[:x[1][0]] + valdic[x[0]] + str_tmp[x[1][1]:]
  1917. subli.append(valdic)
  1918. for x in valdic.values():
  1919. locals()[x] = eval("SP.Symbol('"+x+"')")
  1920. func.append(eval(str_tmp))
  1921. diffli = []
  1922. i1 = 0
  1923. for x in func:
  1924. diffdic = {}
  1925. for y in subli[i1].items():
  1926. diffdic[y[0]] = eval('SP.diff(func[i1],'+y[1]+')')
  1927. diffli.append(diffdic)
  1928. i1=i1+1
  1929. self.diffli1 = diffli
  1930. diffli2 = []
  1931. locals().update(self.sstate)
  1932. locals().update(self.paramdic)
  1933. for x in self.diffli1:
  1934. tmpdic={}
  1935. for y in x.keys():
  1936. # tmpdic[y] = eval(x[y].tostr())
  1937. str_tmp2 = str(x[y])
  1938. while mreg.search(str_tmp2):
  1939. maout = [por for por in mreg.finditer(str_tmp2)]
  1940. maout.reverse()
  1941. for mato in maout:
  1942. starts = mato.span()[0]
  1943. ends = mato.span()[1]
  1944. expo = mato.group()
  1945. str_tmp2 = str_tmp2[:starts]+'np.exp(1)'+str_tmp2[ends-1:]
  1946. tmpdic[y] = eval(str_tmp2)
  1947. diffli2.append(tmpdic)
  1948. self.diffli2 = diffli2
  1949. return self
  1950. #This function is needed in population stage 1, at the end
  1951. def mk_msstate_subs(self):
  1952. """
  1953. This function takes the manually defined numerical sstate conditions and then replaces
  1954. any @terms with the corresponding substitutions
  1955. """
  1956. _mreg = '@[a-zA-Z]*_bar'
  1957. mreg = re.compile(_mreg)
  1958. tmp_list = deepcopy(self.ssys_list)
  1959. sub_dic = deepcopy(self.nlsubs)
  1960. for i1,x in enumerate(tmp_list):
  1961. while mreg.search(tmp_list[i1]):
  1962. ma = mreg.search(tmp_list[i1])
  1963. str_tmp = ma.group()
  1964. tmp_list[i1] = tmp_list[i1].replace(str_tmp,'('+sub_dic[str_tmp]+')')
  1965. self.ssys_list = deepcopy(tmp_list)
  1966. return self
  1967. def mk_mssidic_subs(self):
  1968. """
  1969. This function takes the manually defined numerical sstate's ssidic and then replaces
  1970. any @terms with the corresponding substitutions and evaluates as it goes along
  1971. """
  1972. _mreg = '@[a-zA-Z]*\d*_bar'
  1973. mreg = re.compile(_mreg)
  1974. tmp_list = deepcopy(self.ssili)
  1975. sub_dic = deepcopy(self.nlsubs)
  1976. for i1,x in enumerate(tmp_list):
  1977. while mreg.search(tmp_list[i1][1]):
  1978. ma = mreg.search(tmp_list[i1][1])
  1979. str_tmp = ma.group()
  1980. tmp_list[i1][1] = tmp_list[i1][1].replace(str_tmp,'('+sub_dic[str_tmp]+')')
  1981. locals().update(self.paramdic)
  1982. tmp_dic = {}
  1983. tmp_dic[tmp_list[i1][0]] = eval(tmp_list[i1][1])
  1984. locals().update(tmp_dic)
  1985. # Update ssidic
  1986. self.ssidic.update(tmp_dic)
  1987. self.ssili = deepcopy(tmp_list)
  1988. return self
  1989. #This function is needed in population stage 1, at the end
  1990. def mk_cfstate_subs(self):
  1991. """
  1992. This function takes the closed form defined numerical sstate conditions and then replaces
  1993. any @terms with the corresponding substitutions
  1994. """
  1995. _mreg = '@[a-zA-Z]*_bar'
  1996. mreg = re.compile(_mreg)
  1997. tmp_list = deepcopy(self.manss_sys)
  1998. sub_dic = deepcopy(self.nlsubs)
  1999. for i1,x in enumerate(tmp_list):
  2000. while mreg.search(tmp_list[i1]):
  2001. ma = mreg.search(tmp_list[i1])
  2002. str_tmp = ma.group()
  2003. tmp_list[i1] = tmp_list[i1].replace(str_tmp,'('+sub_dic[str_tmp]+')')
  2004. self.manss_sys = deepcopy(tmp_list)
  2005. return self
  2006. def subs_indic(self):
  2007. '''
  2008. This function replaces indicator function occurrences inside the substitution system
  2009. '''
  2010. list_tmp1 = deepcopy(self.nlsubs_raw1)
  2011. _mreg = '\S{0,1}\s*@I{(?P<cond>.*?)}{(?P<expr>.*?)}'
  2012. mreg = re.compile(_mreg)
  2013. for i1,lino in enumerate(list_tmp1):
  2014. while mreg.search(list_tmp1[i1][1]):
  2015. ma = mreg.search(list_tmp1[i1][1])
  2016. pos, poe = ma.span()
  2017. condi = ma.group('cond')
  2018. expr = ma.group('expr')
  2019. # Expose parameters
  2020. locals().update(self.paramdic)
  2021. if eval(condi):
  2022. list_tmp1[i1][1] = list_tmp1[i1][1][:pos] + expr + list_tmp1[i1][1][poe:]
  2023. else:
  2024. list_tmp1[i1][1] = list_tmp1[i1][1][:pos] + list_tmp1[i1][1][poe:]
  2025. self.nlsubs_raw1 = deepcopy(list_tmp1)
  2026. return self
  2027. # Extra population stage factored out, which is needed before steady state calculations
  2028. def populate_model_stage_one_a(self, secs):
  2029. # Check and calculate the substitution list and dictionary
  2030. if any([False if 'None' in x else True for x in secs['vsfocs'][0]]):
  2031. # Create the raw nlsubs list 1
  2032. self = mk_subs_dic(self, secs)
  2033. # Extra population stage factored out, which is needed before steady state calculations
  2034. def populate_model_stage_one_b(self, secs):
  2035. # Check and calculate the substitution list and dictionary
  2036. if any([False if 'None' in x else True for x in secs['vsfocs'][0]]):
  2037. # Deal with indicator functions inside substitutions
  2038. self = subs_indic(self)
  2039. # Substitute out in @ALL list for expressions, then do expressions
  2040. self = subs_in_subs_all(self)
  2041. self = mk_all(self)
  2042. # Create the raw nlsubs list 2 by replacing substitutions inside substitutions
  2043. self = subs_in_subs(self)
  2044. # Apply steady state transformation where needed
  2045. self = mk_steady(self)
  2046. # Extend the differ out before doing the differ out
  2047. self = ext_differ_out(self)
  2048. # Apply timeshifts where needed
  2049. self = mk_timeshift(self)
  2050. # Make a first differentiation pass for DIFFs inside timeshifters
  2051. self = differ_out(self)
  2052. # Apply timeshifts where needed
  2053. self = mk_timeshift(self)
  2054. # Apply steady state transformation where needed
  2055. self = mk_steady(self)
  2056. # Extend the differ out before doing the differ out
  2057. self = ext_differ_out(self)
  2058. # Make second differentiation pass for remaining DIFFs
  2059. self = differ_out(self)
  2060. # Apply timeshifts where needed
  2061. self = mk_timeshift(self)
  2062. return self
  2063. def populate_model_stage_one_bb(self, secs):
  2064. # Do substitutions inside the numerical steady state list
  2065. # Check and do substitutions
  2066. if all([False if 'None' in x else True for x in secs['vsfocs'][0]]) and\
  2067. all([False if 'None' in x else True for x in secs['manualss'][0]]):
  2068. # Do this only if USE_FOCS has not been used, otherwise ssys_list would be missing
  2069. if '_internal_focs_used' not in dir(self): self = mk_msstate_subs(self)
  2070. # Do substitutions inside the numerical steady state list, but the ssidic
  2071. # Check and do substitutions
  2072. if all([False if 'None' in x else True for x in secs['vsfocs'][0]]) and\
  2073. all([False if 'None' in x else True for x in secs['manualss'][0]]):
  2074. self = mk_mssidic_subs(self)
  2075. # Also save a copy of substituted and evaluated ssili with starting values
  2076. self.template_paramdic['ssili'] = deepcopy(self.ssidic.items())
  2077. # Do substitutions inside the closed form steady state list
  2078. # Check and do substitutions
  2079. if all([False if 'None' in x else True for x in secs['vsfocs'][0]]) and\
  2080. all([False if 'None' in x else True for x in secs['closedformss'][0]]):
  2081. self = mk_cfstate_subs(self)
  2082. # Prepare the nonlinear FOC system but only stripping the raw format
  2083. if all([False if 'None' in x else True for x in secs['focs'][0]]):
  2084. self = premknonlinsys(self,secs)
  2085. # Save for template instantiation
  2086. self.template_paramdic['focs_list'] = self.foceqs
  2087. if all([False if 'None' in x else True for x in secs['vsfocs'][0]]):
  2088. # This takes the stripped system and does @ replacements
  2089. self = premknonlinsys2(self,secs)
  2090. else:
  2091. self.foceqs2 = deepcopy(self.foceqs)
  2092. # Also create a steady state version
  2093. self = mk_steady2(self)
  2094. # Also save a copy of the focs with replaced substitutions, but change timing to Dynare !
  2095. foceqs2 = chg_vtimings(self,deepcopy(self.foceqs2),{'con':[0,1],'endo':[-1,0],'exo':[-1,0]})
  2096. self.template_paramdic['focs_list2'] = deepcopy(self.foceqs2)
  2097. self.template_paramdic['focs_dynare'] = deepcopy(foceqs2)
  2098. else:
  2099. # Save for template instantiation
  2100. self.template_paramdic['focs_list'] = False
  2101. return self
  2102. def populate_model_stage_two(self, secs):
  2103. """
  2104. 2nd stage population of DSGE model. Needs Steady State.
  2105. """
  2106. # Creates nonlinear foc system
  2107. if all([False if 'None' in x else True for x in secs['focs'][0]]):
  2108. self = mknonlinsys(self, secs)
  2109. # Creates loglinear system
  2110. if all([False if 'None' in x else True for x in secs['modeq'][0]]):
  2111. llsys_list = mkloglinsys1(secs)
  2112. self.llsys_list = mkloglinsys2(self,llsys_list)
  2113. self.llsys_list = subs_in_loglinsys(self)
  2114. # Save for template instantiation
  2115. self.template_paramdic['llsys_list'] = deepcopy(self.llsys_list)
  2116. self = mksymsys(self) # creates symbolic and numerical system
  2117. self = mkeqtype(self) # creates variance/covariance
  2118. else:
  2119. # Save for template instantiation
  2120. self.template_paramdic['llsys_list'] = False
  2121. # Creates variance/covariance
  2122. if all([False if 'None' in x else True for x in secs['vcvm'][0]]) and\
  2123. 'sstate' in dir(self):
  2124. self.sigma = mksigmat(self, secs)
  2125. # Save for template instantiation
  2126. self.template_paramdic['sigma'] = deepcopy(self.sigma)
  2127. else:
  2128. # Save for template instantiation
  2129. self.template_paramdic['sigma'] = False
  2130. return self