/pymaclab/dsge/parsers/_dsgeparser.py
Python | 2265 lines | 2226 code | 11 blank | 28 comment | 37 complexity | 867fda6981f05a46d42eff0254ad3cdd MD5 | raw file
Possible License(s): Apache-2.0
Large files files are truncated, but you can click here to view the full file
- '''
- .. module:: _dsgeparser
- :platform: Linux
- :synopsis: This is the (private) module responsible for carefully extracting meaningful information from the DSGE model templated
- files. In here we make much use of Regex patterns as we are extracting information from the mod file lines.
- .. moduleauthor:: Eric M. Scheffel <eric.scheffel@nottingham.edu.cn>
- '''
- import re
- from copy import deepcopy
- import numpy.matlib as mat
- import numpy as np
- import sys
- import os
- # This used to import sympycore, but should now also work with sympy
- import sympycore as SP
- #TODO: why have these as nested functions?
- def populate_model_stage_one(self, secs):
- """
- 1st stage population of DSGE model. Does not need Steady State.
- """
-
- # Establish the timing convention of variables in the model file
- self = def_timing(self,**self._vtiming)
-
- # This is a special dictionary which can be handed over to the template engines (i.e. Jinja2)
- if 'template_paramdic' not in dir(self): self.template_paramdic = {}
- # Get all information from the varvec section
- if all([False if 'None' in x else True for x in secs['varvec'][0]]):
- # match something like [1] z(t):eps_z(t):techshock{exo}[log,hp]
- vtexp = re.compile('^.*?\[.*?\]\s*(?P<vari>.+?)\s*:\s*(?P<varn>.+?)\s*\{(?P<vtype>[^\[]+)}\s*(?P<mod>\[.*?\]){0,1}')
- # match something like [15] x2(t):wrec2{con}[log,hp] OR [1] z(t):eps_z(t):techshock{exo}[log,hp]
- viiexp = re.compile('^.*?\[.*?\]\s*(?P<vari>.+?)\s*:\s*(?P<viid>.+?)\s*:\s*(?P<varn>.+?)\s*\{(?P<vtype>[^\[]+)}\s*(?P<mod>\[.*?\]){0,1}')
- voexp = re.compile('^.*?\[.*?\]\s*(?P<vari>@.+?):(?P<varn>[^\[]+)\s*(?P<mod>\[.*?\]){0,1}')
- vardic = {}
- audic = {}
- vardic['endo'] = {}
- audic['endo'] = {}
- vardic['exo'] = {}
- audic['exo'] = {}
- vardic['con'] = {}
- audic['con'] = {}
- vardic['other'] = {}
- vardic['endo']['var'] = []
- vardic['endo']['mod'] = []
- vardic['exo']['var'] = []
- vardic['exo']['mod'] = []
- vardic['con']['var'] = []
- vardic['con']['mod'] = []
- vardic['other']['var'] = []
- vardic['other']['mod'] = []
- audic['endo']['var'] = []
- audic['endo']['mod'] = []
- audic['con']['var'] = []
- audic['con']['mod'] = []
- audic['exo']['var'] = []
- audic['exo']['mod'] = []
- for x in secs['varvec'][0]:
- if viiexp.search(x):
- ma = viiexp.search(x)
- vari = ma.group('vari').strip()
- viid = ma.group('viid').strip()
- varn = ma.group('varn').strip()
- vtype = ma.group('vtype').strip()
- mods = ma.group('mod')
- vardic[vtype]['var'].append([vari,varn,viid])
- if mods != None:
- mods = mods.strip()
- if ',' in mods:
- vardic[vtype]['mod'].append(mods[1:-1].strip().split(','))
- else:
- vardic[vtype]['mod'].append([mods[1:-1].strip(),])
- else:
- vardic[vtype]['mod'].append([])
- elif vtexp.search(x):
- ma = vtexp.search(x)
- vari = ma.group('vari').strip()
- varn = ma.group('varn').strip()
- vtype = ma.group('vtype').strip()
- mods = ma.group('mod')
- vardic[vtype]['var'].append([vari,varn])
- if mods != None:
- mods = mods.strip()
- if ',' in mods:
- vardic[vtype]['mod'].append(mods[1:-1].strip().split(','))
- else:
- vardic[vtype]['mod'].append([mods[1:-1].strip(),])
- else:
- vardic[vtype]['mod'].append([])
- elif voexp.search(x):
- ma = voexp.search(x)
- # Slice off the @
- vari = ma.group('vari')[1:].strip()
- varn = ma.group('varn').strip()
- mods = ma.group('mod')
- vardic['other']['var'].append([vari,varn])
- if mods != None:
- mods = mods.strip()
- if ',' in mods:
- vardic['other']['mod'].append(mods[1:-1].strip().split(','))
- else:
- vardic['other']['mod'].append([mods[1:-1].strip(),])
- else:
- vardic['other']['mod'].append([])
- self.nendo = len(vardic['endo']['var'])
- self.nexo = len(vardic['exo']['var'])
- self.ncon = len(vardic['con']['var'])
- self.nother = len(vardic['other']['var'])
- self.nstat = self.nendo+self.nexo
- self.nall = self.nstat+self.ncon
- self.vardic = vardic
- self.audic = audic
- # Save for template instantiation
- self.template_paramdic['vardic'] = deepcopy(vardic)
- else:
- self.template_paramdic['vardic'] = False
- # Extract the model name and description
- if all([False if 'None' in x else True for x in secs['info'][0]]):
- for x in secs['info'][0]:
- if 'Name' in x:
- self.mod_name = x.split('=')[1].replace(';','').strip()
- # Save for template instantiation
- self.template_paramdic['mod_name'] = deepcopy(self.mod_name)
- if 'Desc' in x:
- self.mod_desc = x.split('=')[1].replace(';','').strip()
- # Save for template instantiation
- self.template_paramdic['mod_desc'] = deepcopy(self.mod_desc)
- if not self.template_paramdic.has_key('mod_name'):
- self.template_paramdic['mod_name'] = False
- if not self.template_paramdic.has_key('mod_desc'):
- self.template_paramdic['mod_desc'] = False
- # Extract parameters into dictionary
- if all([False if 'None' in x else True for x in secs['params'][0]]):
- param = {}
- # need to do this so users don't have to worry about integer division
- # but preserves integer division for sympycore stuff
- safe_div = """
- from __future__ import division
- """
- for x in secs['params'][0]:
- if ']' in x: x = x.split(']')[1].lstrip()
- list_tmp = x.split(';')
- list_tmp = list_tmp[0].split('=')[:]
- str_tmp1 = list_tmp[0].strip()
- str_tmp2 = list_tmp[1].strip()
- #NOTE: this *should* be safe, but users should know what's
- # in the .mod file
- exec(safe_div + "param['"+str_tmp1+"']=" + str_tmp2, {}, locals())
- locals()[str_tmp1] = param[str_tmp1]
- self.paramdic = param
- # Save for template instantiation
- self.template_paramdic['paramdic'] = deepcopy(param)
- else:
- self.template_paramdic['paramdic'] = False
- # Collect information on manual (closed-form) steady state
- if all([False if 'None' in x else True for x in secs['closedformss'][0]]):
- # Join multiline steady state definitions
- mansys = secs['closedformss'][0]
- list_tmp1 = []
- i1=0
- counter=0
- for x in mansys:
- if '...' in x:
- counter = counter + 1
- elif '...' not in x:
- if counter == 0:
- # Just in case people have used [1] markers...
- if ']' in x: x = x.split(']')[1].lstrip().rstrip()
- list_tmp1.append(x)
- elif counter > 0:
- str_tmp = ''
- for y in mansys[i1-counter:i1+1]:
- str_tmp = str_tmp + y.replace('...','')
- # Just in case people have used [1] markers...
- if ']' in str_tmp: str_tmp = str_tmp.split(']')[1].lstrip().rstrip()
- list_tmp1.append(str_tmp)
- counter = 0
- i1=i1+1
- self.manss_sys = list_tmp1
- # Save for template instantiation
- self.template_paramdic['manss_sys'] = deepcopy(list_tmp1)
- else:
- self.template_paramdic['manss_sys'] = False
-
- # Collect info on numerical steady state
- if all([False if 'None' in x else True for x in secs['manualss'][0]]):
- _mreg_alt = '^\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
- _mreg = '\[\d+\]\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
- _mreg2 = '\[\d+\]\s*[a-zA-Z]*(?!=\+|-|\*|/])\s*=\s*[0-9]*\.[0-9]*'
- _mregfocs = 'USE_FOCS=\[.*?\]'
- mregfocs = re.compile(_mregfocs)
- use_focs = False
- for lino in secs['manualss'][0]:
- if mregfocs.search(lino):
- # Save as the list of equations the be used
- use_focs = eval(lino.split('=')[1].replace(';','').strip())
- self._internal_focs_used = True
- mreg = re.compile(_mreg_alt+'|'+_mreg+'|'+_mreg2)
- indx = []
- ssidic={}
- ssili = []
- list_tmp = []
- anyssi_found = False
- i1=0
- counter=0
- for x in secs['manualss'][0]:
- if mreg.search(x):
- raw_str = x.replace(';','')
- anyssi_found = True
- ma = mreg.search(raw_str)
- if ']' in ma.group(): str1 = ma.group().replace(';','').split('=')[0].split(']')[1].strip()
- else: str1 = ma.group().replace(';','').split('=')[0].lstrip().rstrip()
- str2 = ma.group().split('=')[1].strip()
- # Save the result as a string here, later in mk_mssidic_subs() method we do substitutions and evaluate then
- locals().update(self.paramdic)
- # This captures the case where we have only variables from parameters, but no substitutions
- if '@' not in str2:
- ssidic[str1] = str(eval(str2))
- locals()[str1] = eval(str2)
- else:
- ssidic[str1] = str2
- ssili.append([str1,str2])
- indx.append(i1)
- elif not mreg.search(x) and '...' in x:
- counter = counter + 1
- elif not mreg.search(x) and '...' not in x:
- if counter == 0:
- if ']' in x: list_tmp.append(x.replace(';','').split(']')[1].split('=')[0].strip())
- else: list_tmp.append(x.replace(';','').split('=')[0].strip())
- elif counter > 0:
- str_tmp = ''
- for y in secs['manualss'][0][i1-counter:i1+1]:
- str_tmp = str_tmp + y.replace('...','').strip()
- if ']' in str_tmp: list_tmp.append(str_tmp.split(']')[1].split('=')[0].replace(';','').strip())
- else: list_tmp.append(str_tmp.split('=')[0].replace(';','').strip())
- counter = 0
- i1=i1+1
- if anyssi_found:
- self.ssidic = deepcopy(ssidic)
- self.ssili = deepcopy(ssili)
- # Save for template instantiation
- self.template_paramdic['ssidic'] = deepcopy(ssidic)
- else:
- #Make empty to be filled by other procedure
- self.ssidic = {}
- self.ssili = []
- # Save for template instantiation
- self.template_paramdic['ssidic'] = False
- if not use_focs:
- self.ssys_list = deepcopy(list_tmp)
- # Save for template instantiation
- self.template_paramdic['ssys_list'] = deepcopy(list_tmp)
- self.template_paramdic['use_focs'] = False
- elif use_focs and anyssi_found:
- self._use_focs = deepcopy(use_focs)
- self._ssidic = deepcopy(ssidic)
- self.ssili = deepcopy(ssili)
- # Save for template instantiation
- self.template_paramdic['ssys_list'] = False
- self.template_paramdic['use_focs'] = deepcopy(use_focs)
- elif use_focs and not anyssi_found:
- self._use_focs = deepcopy(use_focs)
- # Save for template instantiation
- self.template_paramdic['ssys_list'] = False
- self.template_paramdic['use_focs'] = deepcopy(use_focs)
-
- else:
- # Save for template instantiation
- self.template_paramdic['ssidic'] = False
- self.template_paramdic['ssys_list'] = False
- self.template_paramdic['use_focs'] = False
-
- return self
- ############# BELOW HERE IS ALL FOR 2ND STAGE ###########
- def def_timing(self,exo=[-1,0],endo=[-1,0],con=[0,1]):
- '''
- A small method which can be used in order to set the timings in stone.
- This will then be used in other parts of the code, also in macrolab package
- '''
- self.vtiming = {}
- self.vtiming['endo'] = deepcopy(endo)
- self.vtiming['exo'] = deepcopy(exo)
- self.vtiming['con'] = deepcopy(con)
-
- return self
- def mkaug2(self,insys=None,othersys=None):
- # Timing definitions
- endotime = self.vtiming['endo']
- exotime = self.vtiming['exo']
- contime = self.vtiming['con']
- endosp = []
- for x in self.vardic['endo']['var']:
- endosp = endosp + [[x,deepcopy(endotime)]]
- exosp = []
- for x in self.vardic['exo']['var']:
- exosp = exosp + [[x,deepcopy(exotime)]]
- consp = []
- for x in self.vardic['con']['var']:
- consp = consp + [[x,deepcopy(contime)]]
- alldic = {}
- alldic.update(self.paramdic)
- alldic.update(self.sstate)
- spvdic = {}
- spvdic['endo'] = endosp
- spvdic['exo'] = exosp
- spvdic['con'] = consp
- spvdic2 = deepcopy(spvdic)
- spvdic3 = deepcopy(spvdic2)
- spvdic3['endo'] = {}
- spvdic3['con'] = {}
- spvdic3['exo'] = {}
- endoli = [x[0].split('(')[0].strip() for x in self.vardic['endo']['var']]
- exoli = [x[0].split('(')[0].strip() for x in self.vardic['exo']['var']]
- conli = [x[0].split('(')[0].strip() for x in self.vardic['con']['var']]
- patup = ('{-100,100}|None','all','{-100,100}')
- count = 0
-
- list_tmp1 = deepcopy(insys)
- for i1,line in enumerate(list_tmp1):
- iterob = self.vreg(patup,line,True,'max')
- if iterob:
- iterob = list(iterob)
- else:
- continue
- iterob.reverse()
- for vma in iterob:
- vtype = vma[1][0]
- vartime = vma[2][2]
- vari = vma[2][1]
- pos = vma[3][0]
- poe = vma[3][1]
-
- # In the following section we will replace time-shifted variables with their auxiliary counterparts
- # in the EXISTING equations of the FOCs, but no new definitions of auxiliary variables are being added
- # Depending on options passed, we may work on the FOCs or the items in NLSUBS_LIST
- if vtype == 'endo':
- indx = endoli.index(vari)
- if not spvdic3['endo'].has_key(vari):
- spvdic3['endo'][vari] = []
- if spvdic3['endo'][vari] == []:
- spvdic3['endo'][vari].append(int(vartime))
- spvdic3['endo'][vari].append(int(vartime))
- elif int(vartime) < spvdic3['endo'][vari][0]: spvdic3['endo'][vari][0] = int(vartime)
- elif int(vartime) > spvdic3['endo'][vari][1]: spvdic3['endo'][vari][1] = int(vartime)
- elif vtype == 'con':
- indx = conli.index(vari)
- if not spvdic3['con'].has_key(vari):
- spvdic3['con'][vari] = []
- if spvdic3['con'][vari] == []:
- spvdic3['con'][vari].append(int(vartime))
- spvdic3['con'][vari].append(int(vartime))
- elif int(vartime) < spvdic3['con'][vari][0]: spvdic3['con'][vari][0] = int(vartime)
- elif int(vartime) > spvdic3['con'][vari][1]: spvdic3['con'][vari][1] = int(vartime)
- elif vtype == 'exo':
- indx = exoli.index(vari)
- if not spvdic3['exo'].has_key(vari):
- spvdic3['exo'][vari] = []
- if spvdic3['exo'][vari] == []:
- spvdic3['exo'][vari].append(int(vartime))
- spvdic3['exo'][vari].append(int(vartime))
- elif int(vartime) < spvdic3['exo'][vari][0]: spvdic3['exo'][vari][0] = int(vartime)
- elif int(vartime) > spvdic3['exo'][vari][1]: spvdic3['exo'][vari][1] = int(vartime)
- else:
- continue
- # Check for endo
- if vtype == 'endo' and int(vartime) > spvdic['endo'][indx][1][1]:
- spvdic2['endo'][indx][1][1] = int(vartime)
- tind = (5-len(str(abs(endotime[1]-int(vartime)))))*'0'+str(abs(endotime[1]-int(vartime)))
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(endotime[1]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
- for i2 in range(abs(int(vartime)-spvdic['endo'][indx][1][1])):
- tind = (5-len(str(abs(i2+1))))*'0'+str(abs(i2+1))
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(i2+1))
- if [newvar,newname] not in self.vardic['con']['var']:
- self.vardic['con']['var'].append([newvar,newname])
- self.vardic['con']['mod'].append(self.vardic['endo']['mod'][indx])
- self.audic['con']['var'].append([newvar,newname])
- self.audic['con']['mod'].append(self.vardic['endo']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- elif vtype == 'endo' and int(vartime) < spvdic['endo'][indx][1][0]:
- spvdic2['endo'][indx][1][0] = int(vartime)
- tind = (5-len(str(abs(endotime[0]-int(vartime)))))*'0'+str(abs(endotime[0]-int(vartime)))
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(endotime[0]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
- for i2 in range(1,abs(int(vartime)-spvdic['endo'][indx][1][0])+1):
- tind = (5-len(str(abs(i2))))*'0'+str(abs(i2))
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(i2))
- if [newvar,newname] not in self.vardic['endo']['var']:
- self.vardic['endo']['var'].append([newvar,newname])
- self.vardic['endo']['mod'].append(self.vardic['endo']['mod'][indx])
- self.audic['endo']['var'].append([newvar,newname])
- self.audic['endo']['mod'].append(self.vardic['endo']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- # Check for exo
- if vtype == 'exo' and int(vartime) > spvdic['exo'][indx][1][1]:
- spvdic2['exo'][indx][1][1] = int(vartime)
- tind = (5-len(str(abs(exotime[1]-int(vartime)))))*'0'+str(abs(exotime[1]-int(vartime)))
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(exotime[1]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
- for i2 in range(abs(int(vartime)-spvdic['exo'][indx][1][1])):
- tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(i2+1))
- if [newvar,newname] not in self.vardic['con']['var']:
- self.vardic['con']['var'].append([newvar,newname])
- self.vardic['con']['mod'].append(self.vardic['exo']['mod'][indx])
- self.audic['con']['var'].append([newvar,newname])
- self.audic['con']['mod'].append(self.vardic['exo']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- elif vtype == 'exo' and int(vartime) < spvdic['exo'][indx][1][0]:
- spvdic2['exo'][indx][1][0] = int(vartime)
- tind = (5-len(str(abs(exotime[0]-int(vartime)))))*'0'+str(abs(exotime[0]-int(vartime)))
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(exotime[0]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
- for i2 in range(abs(int(vartime)-spvdic['exo'][indx][1][0])):
- tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(i2+1))
- if [newvar,newname] not in self.vardic['endo']['var']:
- self.vardic['endo']['var'].append([newvar,newname])
- self.vardic['endo']['mod'].append(self.vardic['exo']['mod'][indx])
- self.audic['endo']['var'].append([newvar,newname])
- self.audic['endo']['mod'].append(self.vardic['exo']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- # Check for con
- if vtype == 'con' and int(vartime) > spvdic['con'][indx][1][1]:
- spvdic2['con'][indx][1][1] = int(vartime)
- tind = (5-len(str(abs(contime[1]-int(vartime)))))*'0'+str(abs(contime[1]-int(vartime)))
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(contime[1]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t)'+list_tmp1[i1][poe:]
- for i2 in range(abs(int(vartime)-spvdic['con'][indx][1][1])):
- tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
- newvar = vari+'_F'+tind+'(t)'
- newname = vari+'_F'+str(abs(i2+1))
- if [newvar,newname] not in self.vardic['con']['var']:
- self.vardic['con']['var'].append([newvar,newname])
- self.vardic['con']['mod'].append(self.vardic['con']['mod'][indx])
- self.audic['con']['var'].append([newvar,newname])
- self.audic['con']['mod'].append(self.vardic['con']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- elif vtype == 'con' and int(vartime) < spvdic['con'][indx][1][0] and spvdic3['con'][vari][0] < contime[0]:
- spvdic2['con'][indx][1][0] = int(vartime)
- tind = (5-len(str(abs(contime[0]-int(vartime)))))*'0'+str(abs(contime[0]-int(vartime)))
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(contime[0]-int(vartime)))
- list_tmp1[i1] = list_tmp1[i1][:pos]+newvar.split('(')[0]+'(t-1)'+list_tmp1[i1][poe:]
- for i2 in range(abs(int(vartime)-spvdic['con'][indx][1][0])):
- tind = (5-len(str(abs(i2+2)-1)))*'0'+str(abs(i2+2)-1)
- newvar = vari+'_B'+tind+'(t)'
- newname = vari+'_B'+str(abs(i2+1))
- if [newvar,newname] not in self.vardic['endo']['var']:
- self.vardic['endo']['var'].append([newvar,newname])
- self.vardic['endo']['mod'].append(self.vardic['con']['mod'][indx])
- self.audic['endo']['var'].append([newvar,newname])
- self.audic['endo']['mod'].append(self.vardic['con']['mod'][indx])
- if self.sstate.has_key(vari+'_bar'):
- self.sstate[newvar.split('(')[0]+'_bar'] = self.sstate[vari+'_bar']
- else:
- self.sstate[newvar.split('(')[0]+'_bar'] = self.paramdic[vari+'_bar']
- continue
- # Save the timings which were found in the FOC equations, or update exisiting one
- if 'vtimings_found' not in dir(self):
- self.vtimings_found = deepcopy(spvdic3)
- self.vtimings_differ = deepcopy(self.vtimings_found)
- else:
- for keyo in spvdic3.keys():
- for keyo2 in spvdic3[keyo].keys():
- if spvdic3[keyo][keyo2][0] < self.vtimings_found[keyo][keyo2][0]:
- self.vtimings_found[keyo][keyo2][0] = spvdic3[keyo][keyo2][0]
- if spvdic3[keyo][keyo2][1] > self.vtimings_found[keyo][keyo2][1]:
- self.vtimings_found[keyo][keyo2][1] = spvdic3[keyo][keyo2][1]
- # Also add a second dictionary which shows the difference between what was found and the reference timing
- for keyo in self.vtimings_found.keys():
- for keyo2 in self.vtimings_found[keyo].keys():
- if keyo == 'endo': self.vtimings_differ[keyo][keyo2] =\
- list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(endotime)])
- elif keyo == 'exo': self.vtimings_differ[keyo][keyo2] =\
- list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(exotime)])
- elif keyo == 'con': self.vtimings_differ[keyo][keyo2] =\
- list([x for x in np.array(self.vtimings_found[keyo][keyo2]) - np.array(contime)])
-
- #################################################################################################
- ##
- ## In this section we will compute the declarations which have to be added to the nonlinear system
- ## in order to incorporate and include in derivations the auxiliare variables used throughout
- ##
- #################################################################################################
- list_added = []
- # Now change the system to include possible augmented variables
- endo_r = filter(lambda x: x[1] != endotime, spvdic2['endo'])
- if endo_r:
- endo_r = [[x[0],[abs(x[1][0]-endotime[0]),abs(x[1][1]-endotime[1])]] for x in endo_r ]
- # Create lags and forwards equations
- for vari in endo_r:
- varin = vari[0][0].split('(')[0]
- if vari[1][0] != 0:
- lagor = range(abs(spvdic3['endo'][varin][0]-endotime[0]))
- for lag in lagor:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
- tind = (5-len(str(lead)))*'0'+str(lead)
- tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
- tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
-
- # Define the beginning definition, needs to link up with the last variable define in endotime[1]
- if lag == lagor[0]:
- lag_endo_diff = spvdic3['endo'][varin][0]-endotime[0]
- if lag_endo_diff < 0:
- list_added.append(varin+'(t-'+str(abs(lag_endo_diff))+')'+' - '+varin+'_B00001(t-1)')
- if lag_endo_diff+1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
- elif lag_endo_diff+1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
- elif lag_endo_diff+1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
- elif lag_endo_diff == 0:
- list_added.append(varin+'(t)'+' - '+varin+'_B00001(t-1)')
- if lag_endo_diff-1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
- elif lag_endo_diff-1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
- elif lag_endo_diff-1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
- elif lag_endo_diff > 0:
- list_added.append(varin+'(t+'+str(lag_endo_diff)+')'+' - '+varin+'_B00001(t-1)')
- if lag_endo_diff-1 > 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t+'+str(lag_endo_diff-1)+')')
- elif lag_endo_diff-1 == 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t)')
- elif lag_endo_diff-1 < 0: list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'(t-'+str(abs(lag_endo_diff-1))+')')
- if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
- list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
-
- # For in between
- if lag != lagor[0] and lag != lagor[-1]:
- expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
- if expro not in list_added:
- list_added.append(expro)
- # Define the end tail definition
- if lag == lagor[-1] and len(lagor) != 1:
- if varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)' not in list_added:
- list_added.append(varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)')
- if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
- list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
-
- leador = range(abs(spvdic3['endo'][varin][1]-endotime[1]))
- if vari[1][1] != 0:
- for lead in leador:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
- tind = (5-len(str(lead)))*'0'+str(lead)
- tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
- tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
-
- # Define the beginning definition, needs to link up with the last variable define in endotime[1]
- if lead == leador[0]:
- if endotime[1] < 0:
- list_added.append(varin+'(t'+str(endotime[1])+')'+' - '+varin+'_F00001(t-1)')
- elif endotime[1] == 0:
- list_added.append(varin+'(t)'+' - '+varin+'_F00001(t-1)')
- elif endotime[1] > 0:
- list_added.append(varin+'(t+'+str(endotime[1])+')'+' - '+varin+'_F00001(t-1)')
- if endotime[1]+1 < 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t-'+str(abs(endotime[1]+1))+')')
- elif endotime[1]+1 == 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t)')
- elif endotime[1]+1 > 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t+'+str(abs(endotime[1]+1))+')')
-
- # For in between
- if lead != leador[0] and lead != leador[-1]:
- if varin+'_F'+tind+'(t)'+' - '+varin+'_F'+tind1+'(t-1)' not in list_added:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'_F'+tind1+'(t-1)')
-
- # Define the end tail definition
- if lead == leador[-1] and len(leador) != 1:
- if spvdic3['endo'][varin][1] > 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t+'+str(spvdic3['endo'][varin][1])+')')
- elif spvdic3['endo'][varin][1] == 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t)')
- elif spvdic3['endo'][varin][1] < 0:
- list_added.append(varin+'_F'+tind+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['endo'][varin][1]))+')')
- exo_r = filter(lambda x: x[1] != exotime, spvdic2['exo'])
- if exo_r:
- exo_r = [[x[0],[abs(x[1][0])-abs(exotime[0]),x[1][1]-abs(exotime[1])]] for x in exo_r ]
- # Create lags and forwards equations
- for vari in exo_r:
- varin = vari[0][0].split('(')[0]
- if vari[1][0] != 0:
- abstdiffer = abs(spvdic3['exo'][varin][0]-exotime[0])
- lagor = range(abstdiffer)
- for lag in lagor:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lag-1)))*'0'+str(lag-1)
- tind = (5-len(str(lag)))*'0'+str(lag)
- tind1 = (5-len(str(lag+1)))*'0'+str(lag+1)
- tind2 = (5-len(str(lag+2)))*'0'+str(lag+2)
-
- # Define the beginning definition, needs to link up with the last variable define in exotime[1]
- if lag == lagor[0]:
- lag_exo_diff = spvdic3['exo'][varin][0]-exotime[0]
- timor = spvdic3['exo'][varin][0]+exotime[0]
- if lag_exo_diff < 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
- elif lag_exo_diff == 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
- elif lag_exo_diff > 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
-
- # For in between
- if lag != lagor[0] and lag != lagor[-1] and len(lagor) != 1:
- expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
- if expro not in list_added:
- list_added.append(expro)
- # Define the end tail definition
- if lag == lagor[-1] and len(lagor) != 1:
- if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
- list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
-
- abstdiffer = abs(spvdic3['exo'][varin][1]-exotime[1])
- leador = range(abstdiffer)
- if vari[1][1] != 0:
- for lead in leador:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
- tind = (5-len(str(lead)))*'0'+str(lead)
- tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
- tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
-
- # Define the beginning definition, needs to link up with the last variable define in endotime[1]
- if lead == leador[0]:
- if exotime[1]+1 < 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(exotime[1]+1))+')')
- elif exotime[1]+1 == 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
- elif exotime[1]+1 > 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(abs(exotime[1]+1))+')')
-
- # For in between
- if lead != leador[0] and lead != leador[-1]:
- if varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)' not in list_added:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)')
-
- # Define the end tail definition
- if lead == leador[-1] and len(leador) != 1:
- if spvdic3['exo'][varin][1] > 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(spvdic3['exo'][varin][1])+')')
- elif spvdic3['exo'][varin][1] == 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
- elif spvdic3['exo'][varin][1] < 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['exo'][varin][1]))+')')
-
- con_r = filter(lambda x: x[1] != contime, spvdic2['con'])
- if con_r:
- con_r = [[x[0],[abs(x[1][0])-abs(contime[0]),x[1][1]-abs(contime[1])]] for x in con_r ]
- # Create lags and forwards equations
- for vari in con_r:
- varin = vari[0][0].split('(')[0]
- if vari[1][0] != 0:
- abstdiffer = abs(spvdic3['con'][varin][0]-contime[0])
- lagor = range(abstdiffer)
- for lag in lagor:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lag-1)))*'0'+str(lag-1)
- tind = (5-len(str(lag)))*'0'+str(lag)
- tind1 = (5-len(str(lag+1)))*'0'+str(lag+1)
- tind2 = (5-len(str(lag+2)))*'0'+str(lag+2)
-
- # Define the beginning definition, needs to link up with the last variable define in contime[1]
- if lag == lagor[0]:
- lag_con_diff = spvdic3['con'][varin][0]-contime[0]
- timor = spvdic3['con'][varin][0]+contime[0]+1
- if lag_con_diff < 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
- elif lag_con_diff == 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
- elif lag_con_diff > 0:
- if timor > 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(timor)+')')
- elif timor == 0: list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'(t)')
- elif timor < 0: list_added.append(+'_B'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(timor))+')')
-
- # For in between
- if lag != lagor[0] and lag != lagor[-1] and len(lagor) != 1:
- expro = varin+'_B'+tind+'(t)'+' - '+varin+'_B'+tindm1+'(t-1)'
- if expro not in list_added:
- list_added.append(expro)
- # Define the end tail definition
- if lag == lagor[-1] and len(lagor) != 1:
- if varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)' not in list_added:
- list_added.append(varin+'_B'+tind1+'(t)'+' - '+varin+'_B'+tind+'(t-1)')
-
- abstdiffer = abs(spvdic3['con'][varin][1]-contime[1])
- leador = range(abstdiffer)
- if vari[1][1] != 0:
- for lead in leador:
-
- # Define some indices to be used
- tindm1 = (5-len(str(lead-1)))*'0'+str(lead-1)
- tind = (5-len(str(lead)))*'0'+str(lead)
- tind1 = (5-len(str(lead+1)))*'0'+str(lead+1)
- tind2 = (5-len(str(lead+2)))*'0'+str(lead+2)
-
-
- # Define the beginning definition, needs to link up with the last variable define in endotime[1]
- if lead == leador[0]:
- if contime[1]+1 < 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(contime[1]+1))+')')
- elif contime[1]+1 == 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
- elif contime[1]+1 > 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(abs(contime[1]+1))+')')
-
- # For in between
- if lead != leador[0] and lead != leador[-1]:
- if varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)' not in list_added:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'_F'+tind2+'(t-1)')
-
- # Define the end tail definition
- if lead == leador[-1] and len(leador) != 1:
- if spvdic3['con'][varin][1] > 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+'E(t)|'+varin+'(t+'+str(spvdic3['con'][varin][1])+')')
- elif spvdic3['con'][varin][1] == 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t)')
- elif spvdic3['con'][varin][1] < 0:
- list_added.append(varin+'_F'+tind1+'(t)'+' - '+varin+'(t-'+str(abs(spvdic3['con'][varin][1]))+')')
- # If only on system was passed in then we just return the modified equations with the added equations attached at bottom
- # If two systems were passed, then we return the substituted out system of equations (in nlsubs_list) and the declarations added
- # to the bottom of the usual FOC system of equations, BUT ONLY if they are not already included
- if othersys == None:
- for lino in list_added:
- if lino not in list_tmp1: list_tmp1.append(lino)
- return self, deepcopy(list_tmp1)
- elif othersys != None:
- for lino in list_added:
- if lino not in othersys:
- othersys.append(lino)
- return self, (list_tmp1,othersys)
- def mk_subs_dic(self, secs):
- # Make the substitution system by joining lines and stripping
- list_tmp2 = []
- # This list is used to catch the @ALL instructions and store them
- list_tmp3 = []
- list_tmp3_ind = []
- # A list which collects all elements, to be handed to the template_paramdic for template parsing
- list_tmp4 = []
- i1=0
- linecounter=0
- for x in secs['vsfocs'][0]:
- if x.endswith(("...","\\")):
- linecounter += 1
- else:
- if linecounter == 0:
- ################# Catch @ALL expressions and store################
- if "@ALL" in x:
- intor = []
- intor1 = x.split('@ALL')[1].replace(';','')
- intor.append('@ALL')
- intor.append(intor1)
- list_tmp4.append(intor)
- raw_str = x.split(';')[0].split('@ALL')[1].split('{')[1].split('}')[0]
- list_tmp3.append(raw_str.split(','))
- list_tmp3_ind.append(i1)
- continue
- ##################################################################
- line = x.replace(';','').split(']')[1].strip()
- elif linecounter > 0: # have a multiline equation
- str_tmp = ''
- for y in secs['vsfocs'][0][i1-linecounter:i1+1]:
- str_tmp += y.replace('...','').replace(';','').replace('//','').strip()
- ################# Catch @ALL expressions and store################
- if "@ALL" in str_tmp:
- intor = []
- intor1 = x.split('@ALL')[1].replace(';','')
- intor.append('@ALL')
- intor.append(intor1)
- list_tmp4.append(intor)
- raw_str = str_tmp.split('@ALL')[1].split('{')[1].split('}')[0]
- list_tmp3.append(raw_str.split(','))
- list_tmp3_ind.append(i1)
- continue
- ##################################################################
- if ']' in str_tmp:
- line = str_tmp.split(']')[1].strip()
- else:
- line = str_tmp.strip()
- linecounter = 0
- i1 += 1
- splitline = line.split('=')
- # Only consider the first split of = found, this is used because of subs_ind
- if len(splitline) > 2:
- tmpstr = ''
- for elem in splitline[1:]:
- tmpstr = tmpstr+'='+elem
- tmpstr = tmpstr[1:]
- splitline = [splitline[0],tmpstr]
- list_tmp4.append([splitline[0].strip(), splitline[1].strip()])
- list_tmp2.append([splitline[0].strip(), splitline[1].strip()])
- self.allsubs_raw1 = deepcopy(list_tmp3)
- self.allsubs_index = deepcopy(list_tmp3_ind)
- self.nlsubs_raw1 = deepcopy(list_tmp2)
- self.nlsubsdic = dict(list_tmp2)
- if list_tmp4 != []: self.template_paramdic['subs_list'] = deepcopy(list_tmp4)
- else: self.template_paramdic['subs_list'] = False
- return self
- def subs_in_subs_all(self):
- list_tmp3 = deepcopy(self.allsubs_raw1)
- list_tmp2 = deepcopy(self.nlsubs_raw1)
- # Replace substitutions inside substitutions, for both time-subscripted and steady state vars!
- mreg = re.compile('@DISCOUNT|@(E\(t.*?\)\|){0,1}.*?\(t.*?\)|@(E\(t.*?\)\|){0,1}.*?_bar')
- variables = [x[0] for x in list_tmp2] # do this once
- for i,x in enumerate(list_tmp3):
- expr = list_tmp3[i][0]
- while mreg.search(expr):
- ma = mreg.search(expr)
- indx = variables.index(ma.group())
- expr = list_tmp2[indx][1]
- list_tmp3[i][0] = expr
- self.allsubs_raw2 = deepcopy(list_tmp3)
- return self
- def mk_all(self):
- list_tmp1 = deepcopy(self.allsubs_raw2)
- list_tmp2 = deepcopy(self.allsubs_raw1)
- list_tmp3 = deepcopy(self.nlsubs_raw1)
- subsli = [x[0] for x in list_tmp3]
- repldic_li = []
- do_ss = False
- for i1,elem in enumerate(list_tmp1):
- repldic = {}
- if 'SS' in elem: do_ss = True
- stem = list_tmp2[i1][0].split('(')[0]
- stem_time = '('+list_tmp2[i1][0].split('(')[1]
- # Do the simplest SS conversion
- if stem+'_bar' not in subsli: repldic[stem+'_bar'] = 'SS{'+stem+stem_time+'}'
- if '-' in elem[1]:
- chron = range(int(elem[1].split('-')[0].split('[')[1]),int(elem[1].split('-')[1].split(']')[0])+1)
- else:
- chron = elem[2].split('[')[1].split(']')[0].split(',')
- chron = [int(x) for x in chron]
- # Do current-period differentiation and SS jobs first
- patup = ('{-10,10}|None','endo|con|exo|other','{-10,10}')
- varli = self.vreg(patup,list_tmp1[i1][0],True,'max')
- for chrono in chron:
- if chrono == 0:
- for varo in varli:
- if varo[1][0] == 'con' and int(varo[2][2]) == 0:
- if stem+varo[2][1]+stem_time not in subsli:
- repldic[stem+varo[2][1]+stem_time] = 'DIFF{'+stem+stem_time+','+varo[0]+'}'
- if stem+varo[2][1]+'_bar' not in subsli:
- repldic[stem+varo[2][1]+'_bar'] = 'SS{'+stem+varo[2][1]+stem_time+'}'
- elif varo[1][0] == 'endo' and int(varo[2][2]) == -1:
- if stem+varo[2][1]+stem_time not in subsli:
- repldic[stem+varo[2][1]+stem_time] = 'DIFF{'+stem+stem_time+','+varo[0]+'}'
- …
Large files files are truncated, but you can click here to view the full file