modelflowib 2.73__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modelBLfunk.py +180 -0
- model_Excel.py +332 -0
- model_cvx.py +139 -0
- model_dynare.py +173 -0
- model_financial_stability.py +88 -0
- model_latex.py +497 -0
- model_latex_class.py +808 -0
- model_parquet_mixin.py +424 -0
- modelclass.py +9828 -0
- modelconstruct.py +1496 -0
- modelconstruct_estimation.py +2872 -0
- modeldash.py +265 -0
- modeldashboot.py +202 -0
- modeldashsidebar.py +456 -0
- modeldekom.py +651 -0
- modeldiff.py +561 -0
- modeldisplay.py +550 -0
- modelestimation.py +1776 -0
- modelestimator_new.py +2613 -0
- modelflowib-2.73.dist-info/METADATA +156 -0
- modelflowib-2.73.dist-info/RECORD +44 -0
- modelflowib-2.73.dist-info/WHEEL +5 -0
- modelflowib-2.73.dist-info/licenses/license.md +10 -0
- modelflowib-2.73.dist-info/top_level.txt +39 -0
- modelgrab.py +318 -0
- modelgrabgdx.py +584 -0
- modelgrabwf2.py +1107 -0
- modelhelp.py +543 -0
- modelhtml.py +606 -0
- modelinvert.py +250 -0
- modeljupyter.py +824 -0
- modeljupytermagic.py +813 -0
- modelmacrograb.py +98 -0
- modelmanipulation.py +1461 -0
- modelmf.py +349 -0
- modelnet.py +114 -0
- modelnewton.py +2178 -0
- modelnormalize.py +430 -0
- modelpattern.py +428 -0
- modelreport.py +2187 -0
- modeluserfunk.py +97 -0
- modelvis.py +1038 -0
- modelwidget.py +718 -0
- modelwidget_input.py +1933 -0
modeldiff.py
ADDED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Tue Oct 22 22:47:37 2013
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Developement Module - only for the adventeous
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
This module handels symbolic differentiation of models \n
|
|
10
|
+
calculates the values of all the partial differentialkoifficients
|
|
11
|
+
and creates matrices for each lag
|
|
12
|
+
|
|
13
|
+
@author: Ib Hansen
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
#from makrostart import smecstart,adamstart,monastart
|
|
18
|
+
import matplotlib.pyplot as plt
|
|
19
|
+
import re
|
|
20
|
+
from matplotlib import colors
|
|
21
|
+
from matplotlib import cm,patches
|
|
22
|
+
import itertools
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import pandas as pd
|
|
26
|
+
from collections import defaultdict
|
|
27
|
+
from math import exp, log
|
|
28
|
+
import numpy as np
|
|
29
|
+
from sympy import sympify,Symbol
|
|
30
|
+
from sympy.abc import _clash1,_clash
|
|
31
|
+
from sympy import pprint
|
|
32
|
+
from IPython.display import display, Math ,Latex
|
|
33
|
+
from sympy import latex
|
|
34
|
+
import re
|
|
35
|
+
import networkx as nx
|
|
36
|
+
import numpy as np
|
|
37
|
+
import numpy.linalg as linalg
|
|
38
|
+
import sys
|
|
39
|
+
|
|
40
|
+
from modelmanipulation import split_frml,udtryk_parse,find_arg,stripstring,pastestring
|
|
41
|
+
from modelclass import model
|
|
42
|
+
from modelmanipulation import normalize
|
|
43
|
+
import modelclass as mc
|
|
44
|
+
from modelpattern import nterm,udtrykre
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# in order to use theese reserved words from sympy as variables
|
|
48
|
+
_clash['im']=Symbol('im')
|
|
49
|
+
_clash['li']=Symbol('li')
|
|
50
|
+
_clash['if']=Symbol('if')
|
|
51
|
+
_clash['IF']=Symbol('IF')
|
|
52
|
+
_clash['pi']=Symbol('pi')
|
|
53
|
+
_clash['PI']=Symbol('PI')
|
|
54
|
+
_clash['PCT']=Symbol('PCT')
|
|
55
|
+
_clash['pct']=Symbol('pct')
|
|
56
|
+
_clash['QP']=Symbol('QP')
|
|
57
|
+
_clash['qp']=Symbol('qp')
|
|
58
|
+
_clash['QQ']=Symbol('QQ')
|
|
59
|
+
_clash['qq']=Symbol('qq')
|
|
60
|
+
_clash['E']=Symbol('E')
|
|
61
|
+
_clash['e']=Symbol('e')
|
|
62
|
+
_clash['i']=Symbol('i')
|
|
63
|
+
_clash['I']=Symbol('I')
|
|
64
|
+
_clash['lt']=Symbol('lt')
|
|
65
|
+
_clash['LT']=Symbol('LT')
|
|
66
|
+
_clash['EX']=Symbol('EX')
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
#print(_clash)
|
|
70
|
+
|
|
71
|
+
def findallvar(model,v):
|
|
72
|
+
'''Finds all endogenous variables which is on the right side of = in the expresion for variable v
|
|
73
|
+
lagged variables are included '''
|
|
74
|
+
terms= model.allvar[v]['terms'][model.allvar[v]['assigpos']:-1]
|
|
75
|
+
rhsvar={(nt.var+('('+nt.lag+')' if nt.lag != '' else '')) for nt in terms if nt.var and nt.var in model.endogene}
|
|
76
|
+
var2=sorted(list(rhsvar))
|
|
77
|
+
return var2
|
|
78
|
+
|
|
79
|
+
def findendocur(model,v):
|
|
80
|
+
'''Finds all endegenoujs variables which is on the right side of = in the expresion for variable v
|
|
81
|
+
lagged variables are **not** included '''
|
|
82
|
+
terms= model.allvar[v]['terms'][model.allvar[v]['assigpos']:-1]
|
|
83
|
+
rhsvar={nt.var for nt in terms if nt.var and nt.var in model.endogene and nt.lag =='' and nt.var != v}
|
|
84
|
+
var2=sorted(list(rhsvar))
|
|
85
|
+
return var2
|
|
86
|
+
|
|
87
|
+
def modeldiff(model,silent=False,onlyendocur=False,endovar= None, maxdif=9999999999999999,forcenum=False):
|
|
88
|
+
''' Differentiate all relations with respect to all variable
|
|
89
|
+
The result is placed in a dictory in the model instanse: model.diffendocur
|
|
90
|
+
'''
|
|
91
|
+
with model.timer('Find espressions for partial derivatives',not silent):
|
|
92
|
+
model.diffendocur={} #defaultdict(defaultdict) #here we wanmt to store the derivativs
|
|
93
|
+
i=0
|
|
94
|
+
for nvar,v in enumerate(model.endogene):
|
|
95
|
+
if nvar >= maxdif:
|
|
96
|
+
break
|
|
97
|
+
if not silent:
|
|
98
|
+
print(f'Now differentiating {v} {nvar}')
|
|
99
|
+
|
|
100
|
+
if onlyendocur:
|
|
101
|
+
endocur=findendocur(model,v)
|
|
102
|
+
else:
|
|
103
|
+
endocur=findallvar(model,v)
|
|
104
|
+
model.diffendocur[v]={}
|
|
105
|
+
t=model.allvar[v]['frml'].upper()
|
|
106
|
+
a,fr,n,udtryk=split_frml(t)
|
|
107
|
+
udtryk=udtryk
|
|
108
|
+
udtryk=re.sub(r'LOG\(','log(',udtryk) # sympy uses lover case for log and exp
|
|
109
|
+
udtryk=re.sub(r'EXP\(','exp(',udtryk)
|
|
110
|
+
lhs,rhs=udtryk.split('=',1)
|
|
111
|
+
try:
|
|
112
|
+
kat=sympify(rhs[0:-1], _clash) # we take the the $ out _clash1 makes I is not taken as imiganary
|
|
113
|
+
except:
|
|
114
|
+
print('* Problem sympify ',lhs,'=',rhs[0:-1])
|
|
115
|
+
for rhv in endocur:
|
|
116
|
+
try:
|
|
117
|
+
if not forcenum:
|
|
118
|
+
ud=kat.diff(sympify(rhv,_clash))
|
|
119
|
+
if forcenum or 'Derivative(' in str(ud) :
|
|
120
|
+
ud = numdif(model,v,rhv,silent=silent)
|
|
121
|
+
if not silent: print('numdif of {rhv}')
|
|
122
|
+
model.diffendocur[v.upper()][rhv.upper()]=str(ud)
|
|
123
|
+
|
|
124
|
+
except:
|
|
125
|
+
print('we have a serous problem deriving:',lhs,'|',rhv,'\n',lhs,'=',rhs)
|
|
126
|
+
i+=1
|
|
127
|
+
if not silent:
|
|
128
|
+
print('Model :',model.name)
|
|
129
|
+
print('Number of variables :',len(model.allvar))
|
|
130
|
+
print('Number of endogeneus variables :',len(model.diffendocur))
|
|
131
|
+
print('Number of derivatives :',i)
|
|
132
|
+
|
|
133
|
+
def diffout(model):
|
|
134
|
+
l=model.maxnavlen
|
|
135
|
+
llhs = max( len(lhsvar) for lhsvar in model.diffendocur)
|
|
136
|
+
lrhs = max( len(rhsvar) for lhsvar in model.diffendocur
|
|
137
|
+
for rhsvar in model.diffendocur[lhsvar])
|
|
138
|
+
out = [f'{lhsvar:>{llhs}} {rhsvar:>{lrhs}} {model.diffendocur[lhsvar][rhsvar]} '
|
|
139
|
+
for lhsvar in sorted(model.diffendocur)
|
|
140
|
+
for rhsvar in sorted(model.diffendocur[lhsvar])
|
|
141
|
+
]
|
|
142
|
+
return out
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def diffprint(model,udfil=''):
|
|
146
|
+
f=sys.stdout
|
|
147
|
+
if udfil:f=open(udfil,'w+')
|
|
148
|
+
i=0
|
|
149
|
+
l=model.maxnavlen
|
|
150
|
+
for v in sorted(model.diffendocur):
|
|
151
|
+
for e in sorted(model.diffendocur):
|
|
152
|
+
print(v.ljust(l),e.ljust(l+5),model.diffendocur[v][e],file=f)
|
|
153
|
+
i+=1
|
|
154
|
+
print('Number of variables :',len(model.allvar),file=f)
|
|
155
|
+
print('Number of endogeneus variables :',len(model.diffendocur),file=f)
|
|
156
|
+
print('Number of derivatives :',i,file=f)
|
|
157
|
+
def vardiff(model,var='*'):
|
|
158
|
+
''' Displays espressions for differential koifficients for a variable
|
|
159
|
+
if var ends with * all matchning variables are displayes'''
|
|
160
|
+
l=model.maxnavlen
|
|
161
|
+
if var.endswith('*'):
|
|
162
|
+
for v in sorted(model.diffendocur):
|
|
163
|
+
if v.startswith(var[:-1]):
|
|
164
|
+
print(model.allvar[v]['frml'])
|
|
165
|
+
for e in sorted(model.diffendocur[v]):
|
|
166
|
+
print(v.ljust(l),e.ljust(l+5),model.diffendocur[v][e])
|
|
167
|
+
print(' ')
|
|
168
|
+
else:
|
|
169
|
+
for v in sorted(model.diffendocur):
|
|
170
|
+
if v == var:
|
|
171
|
+
print(model.allvar[v]['frml'])
|
|
172
|
+
for e in sorted(model.diffendocur[v]):
|
|
173
|
+
print(v.ljust(l),e.ljust(l+5),model.diffendocur[v][e])
|
|
174
|
+
def invdiff(model,var):
|
|
175
|
+
''' Displays espressions for differential koifficients for a variable
|
|
176
|
+
if var ends with * all matchning variables are displayes'''
|
|
177
|
+
l=model.maxnavlen
|
|
178
|
+
for v in sorted(model.diffendocur):
|
|
179
|
+
for e in sorted(model.diffendocur[v]):
|
|
180
|
+
if e == var:
|
|
181
|
+
print(model.allvar[v]['frml'])
|
|
182
|
+
print(v.ljust(l),e.ljust(l),model.diffendocur[v][e])
|
|
183
|
+
def rettet(ind):
|
|
184
|
+
print(ind)
|
|
185
|
+
print(ind.group(0))
|
|
186
|
+
print(ind.group(1))
|
|
187
|
+
|
|
188
|
+
def fouteval(model,databank):
|
|
189
|
+
''' takes a dict of derivatives for a model and makes a function which returns a function which evaluates the
|
|
190
|
+
derivatives in a period.
|
|
191
|
+
The derivatives is both returned from the function and places in \n
|
|
192
|
+
:model.difvalue'''
|
|
193
|
+
columnsnr=model.get_columnsnr(databank)
|
|
194
|
+
fib=[]
|
|
195
|
+
fib.append('def make_diffcalculate():\n')
|
|
196
|
+
fib.append(' def diffcalculate(model,databank,periode):\n')
|
|
197
|
+
fib.append(' '+'from math import exp, log \n')
|
|
198
|
+
fib.append(' '+'import sys\n')
|
|
199
|
+
fib.append(' '+'row=databank.index.get_loc(periode)\n')
|
|
200
|
+
fib.append(' '+'values=databank.values\n')
|
|
201
|
+
fib.append(' '+'diffvalue={} \n')
|
|
202
|
+
fib.append(' '+'try :\n')
|
|
203
|
+
for i,v in enumerate(sorted(model.diffendocur)):
|
|
204
|
+
# print(v)
|
|
205
|
+
if i>= 20000000: # to make small tests calculations
|
|
206
|
+
break
|
|
207
|
+
fib.append(' '+'diffvalue["'+v+'"]={} \n')
|
|
208
|
+
for e in sorted(model.diffendocur[v]):
|
|
209
|
+
# print(' ',e)
|
|
210
|
+
if e == 'D'+v or e == 'Z'+v :continue
|
|
211
|
+
if e == v+'_D' :continue # dont want dummyes
|
|
212
|
+
# print(v.ljust(l),e.ljust(l),model.diffendocur[v][e],file=f)
|
|
213
|
+
fib.append(' '+'diffvalue["'+v+'"]["'+e+'"]=')
|
|
214
|
+
terms=udtryk_parse(settozero(str(model.diffendocur[v][e])))
|
|
215
|
+
for t in terms:
|
|
216
|
+
if t.op:
|
|
217
|
+
ud=t.op.lower()
|
|
218
|
+
elif t.number:
|
|
219
|
+
ud=t.number
|
|
220
|
+
elif t.var:
|
|
221
|
+
if t.lag== '':
|
|
222
|
+
ud= 'values[row,'+str(columnsnr[t.var])+']'
|
|
223
|
+
else :
|
|
224
|
+
ud= 'values[row'+t.lag+','+str(columnsnr[t.var])+']'
|
|
225
|
+
fib.append(ud)
|
|
226
|
+
fib.append('\n')
|
|
227
|
+
fib.append(' '+'except :\n')
|
|
228
|
+
fib.append(' '+' '+'print("Error in",sys.exc_info())\n')
|
|
229
|
+
fib.append(' '+' '+'raise\n')
|
|
230
|
+
fib.append(' '+'model.diffvalue=diffvalue\n')
|
|
231
|
+
fib.append(' '+'return diffvalue\n')
|
|
232
|
+
fib.append(' return diffcalculate\n')
|
|
233
|
+
# print('Function to evaluate derivatives of',model.name,'created')
|
|
234
|
+
# print (fib)
|
|
235
|
+
return ''.join(fib)
|
|
236
|
+
|
|
237
|
+
def calculate_diffvalue(model,bank,per):
|
|
238
|
+
''' calculates the numeric value of derivatives.
|
|
239
|
+
the values are returnes and also places in model.diffvalue'''
|
|
240
|
+
funk=fouteval(model,bank)
|
|
241
|
+
exec(funk,globals())
|
|
242
|
+
xx=make_diffcalculate()
|
|
243
|
+
res=xx(model,bank,per)
|
|
244
|
+
return res
|
|
245
|
+
def calculate_delta(databank):
|
|
246
|
+
''' calculates the standard deviation of the change in all variable in a databank
|
|
247
|
+
returns a panda series'''
|
|
248
|
+
delta=databank.data['2000':'2013'].diff()
|
|
249
|
+
return delta.std()
|
|
250
|
+
def calculate_impact(model,bank):
|
|
251
|
+
'''Calculate the impact of every variable in equation on the result based on
|
|
252
|
+
the standard deviation and differential coefficient'''
|
|
253
|
+
impact={}
|
|
254
|
+
temp=calculate_delta(bank)
|
|
255
|
+
for v in sorted(model.diffvalue):
|
|
256
|
+
impact[v]={}
|
|
257
|
+
for e in sorted(model.diffvalue[v]):
|
|
258
|
+
evar=e.split('(')[0] # evar= variable name without lag - to find the standard error
|
|
259
|
+
impact[v][e]=abs(model.diffvalue[v][e]*temp[evar])
|
|
260
|
+
model.impact=impact
|
|
261
|
+
def calculate_diffvalue_d3d(model):
|
|
262
|
+
""" creates a 3D dictonary derivatives for each lag"""
|
|
263
|
+
tree = lambda: defaultdict(tree) # crates a nested dict
|
|
264
|
+
res=tree()
|
|
265
|
+
for v in model.diffvalue:
|
|
266
|
+
for e in model.diffvalue[v]:
|
|
267
|
+
ee=e.split('(')
|
|
268
|
+
evar=ee[0] # evar= variable name without lag - to find the standard error
|
|
269
|
+
lag=0 if 1==len(ee) else int(ee[1][:-1]) # extract the lag
|
|
270
|
+
d=model.diffvalue[v][e]
|
|
271
|
+
if np.isinf(d) or np.isnan(d):
|
|
272
|
+
print('Differentialkoifficienten mellen',v,'og',e,'kan ikke beregnes')
|
|
273
|
+
res[lag][v][evar]=d
|
|
274
|
+
model.diffvalue_d3d=res
|
|
275
|
+
return res
|
|
276
|
+
|
|
277
|
+
def calculate_mat(model,lag=0):
|
|
278
|
+
''' calcultae matrix of derivative values.
|
|
279
|
+
very slow should be reworked
|
|
280
|
+
|
|
281
|
+
'''
|
|
282
|
+
rowname=sorted(model.endogene)
|
|
283
|
+
colname=sorted(model.endogene) + sorted(model.exogene)
|
|
284
|
+
ud=pd.DataFrame(0,index=rowname,columns=colname)
|
|
285
|
+
|
|
286
|
+
for pcol in colname:
|
|
287
|
+
for prow in rowname:
|
|
288
|
+
try:
|
|
289
|
+
ud.loc[prow,pcol] = model.diffvalue_d3d[lag][prow][pcol]
|
|
290
|
+
except:
|
|
291
|
+
pass
|
|
292
|
+
return ud
|
|
293
|
+
|
|
294
|
+
def calculate_endocurmat(model,df,per):
|
|
295
|
+
''' for Newton solution find jacobi'''
|
|
296
|
+
with model.timer('Finding derivatives') as t:
|
|
297
|
+
_ = modeldiff(model,silent=True,onlyendocur =True)
|
|
298
|
+
with model.timer('Calculating derivatives') as t:
|
|
299
|
+
res = calculate_diffvalue(model,df,per)
|
|
300
|
+
df = pd.DataFrame.from_dict(madam.diffvalue)
|
|
301
|
+
return df
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def calculate_allmat(model,df,per,show=False):
|
|
305
|
+
''' Calculate and return a dictionary with a matrix of derivative values for each lag'''
|
|
306
|
+
with model.timer('Finding derivatives',show) as t:
|
|
307
|
+
_ = modeldiff(model,silent=True)
|
|
308
|
+
with model.timer('Calculating derivatives',show) as t:
|
|
309
|
+
res = calculate_diffvalue(model,df,per)
|
|
310
|
+
with model.timer('creating dataframe',show) as t:
|
|
311
|
+
res2 = calculate_diffvalue_d3d(model)
|
|
312
|
+
return {l:calculate_mat(model,l) for l in range(0,model.maxlag-1,-1)}
|
|
313
|
+
|
|
314
|
+
def calculate_matold(model,lag=0,endo=True):
|
|
315
|
+
''' calcultae matrix of derivative values.
|
|
316
|
+
endo deteriins if it is with respect to endogeneous og exogeneous variables
|
|
317
|
+
'''
|
|
318
|
+
rowname=sorted(model.endogene)
|
|
319
|
+
colname=rowname if endo else sorted(model.exogene)
|
|
320
|
+
col=len(colname)
|
|
321
|
+
row=len(rowname)
|
|
322
|
+
ud=np.zeros((row,col))
|
|
323
|
+
placdirrow={v:i for i,v in enumerate(rowname)}
|
|
324
|
+
placdircol={v:i for i,v in enumerate(colname)}
|
|
325
|
+
for vx in [m for m in model.diffvalue_d3d[lag].keys() if m in colname]:
|
|
326
|
+
for vy in [m for m in model.diffvalue_d3d[lag][vx].keys() if m in rowname]:
|
|
327
|
+
ud[placdirrow[vx],placdircol[vy]]=model.diffvalue_d3d[lag][vx][vy]
|
|
328
|
+
return pd.DataFrame(ud,index=rowname,columns=colname)
|
|
329
|
+
def modelnet_dict(d,model,lag):
|
|
330
|
+
''' creates a network where weight is determined by a 3d dict of impacts
|
|
331
|
+
d: 3 d dictinorary '''
|
|
332
|
+
g=nx.DiGraph()
|
|
333
|
+
for lag in d:
|
|
334
|
+
for v in d[lag]:
|
|
335
|
+
for e in d[lag][v]:
|
|
336
|
+
if v in model.endogene and e in model.endogene:
|
|
337
|
+
g.add_edge(e,v,weight=d[lag][v][e])
|
|
338
|
+
return g
|
|
339
|
+
def pagerank(g):
|
|
340
|
+
''' ranks the equations in a model according to the pagerank algoritme
|
|
341
|
+
returns order in pagerank'''
|
|
342
|
+
xx=nx.pagerank(g)
|
|
343
|
+
sorteret=sorted(zip(xx.values(),xx.keys()),reverse=True)
|
|
344
|
+
rankorder=[yy for xxx,yy in sorteret]
|
|
345
|
+
return rankorder
|
|
346
|
+
def display_diff(model,bank,var=''):
|
|
347
|
+
temp=calculate_delta(bank)
|
|
348
|
+
l=model.maxnavlen
|
|
349
|
+
for v in sorted(model.diffvalue):
|
|
350
|
+
if var and not v==var:continue
|
|
351
|
+
f=re.sub(r' |\n','',split_frml(model.allvar[v]['frml'])[3])
|
|
352
|
+
print(f)
|
|
353
|
+
for e,w in sorted(model.impact[v].items(), key=lambda x: x[1]):
|
|
354
|
+
evar=e.split('(')[0]
|
|
355
|
+
diffvalue = '{:12.3f}'.format(model.diffvalue[v][e])
|
|
356
|
+
delta = '{:12.3f}'.format(temp[evar])
|
|
357
|
+
timpact = '{:12.1f}% '.format(model.impact[v][e]/temp[v]*100.)
|
|
358
|
+
print(v.ljust(l),e.ljust(l),diffvalue,delta,timpact,model.diffendocur[v][e])
|
|
359
|
+
def display_ip_old(model,ivar):
|
|
360
|
+
var=ivar.upper()
|
|
361
|
+
a,fr,n,udtryk= split_frml(model.allvar[var]['frml'])
|
|
362
|
+
udtryk2=re.sub(r'_',r'\_',udtryk[:-1]) # get rid of _
|
|
363
|
+
udtryk3=re.sub(r'(?P<var>[a-zA-Z_]\w*)\((?P<lag>-[0-9]+)\)','\g<var>_{\g<lag>}',udtryk2)
|
|
364
|
+
udtryk3 = re.sub(r'delta_',r'\Delta ',udtryk3)
|
|
365
|
+
totud=[udtryk3]
|
|
366
|
+
for i in sorted(model.diffendocur[var].keys()):
|
|
367
|
+
ud=r'\frac{\partial '+var+'}{\partial '+i+'} = '+str(model.diffendocur[var][i])
|
|
368
|
+
ud = re.sub(r'delta_',r'\Delta ',ud)
|
|
369
|
+
|
|
370
|
+
ud=re.sub(r'_',r'\_',ud)
|
|
371
|
+
ud2=re.sub(r'(?P<var>[a-zA-Z_]\w*)\((?P<lag>-[0-9]+)\)','\g<var>_{\g<lag>}',ud)
|
|
372
|
+
totud.append(r''+ud2+r'')
|
|
373
|
+
# print(' ')
|
|
374
|
+
ud=r'\\'.join(totud)
|
|
375
|
+
ud2=re.sub(r'=',r' & = &',ud)
|
|
376
|
+
ud3=r'$\begin{eqnarray}'+r' \\'+ud2+r'\end{eqnarray}$'
|
|
377
|
+
return ud3
|
|
378
|
+
|
|
379
|
+
def display_all(model,df,per):
|
|
380
|
+
res = calculate_diffvalue(model,df,per)
|
|
381
|
+
res2 = calculate_diffvalue_d3d(model)
|
|
382
|
+
for v in sorted(model.endogene):
|
|
383
|
+
display_ip(model,v)
|
|
384
|
+
|
|
385
|
+
def display_ip(model,ivar):
|
|
386
|
+
var=ivar.upper()
|
|
387
|
+
a,fr,n,udtryk= split_frml(model.allvar[var]['frml'])
|
|
388
|
+
udtryk2=re.sub(r'_',r'\_',udtryk[:-1]) # get rid of _
|
|
389
|
+
udtryk3=re.sub(r'(?P<var>[a-zA-Z_]\w*)\((?P<lag>-[0-9]+)\)','\g<var>_{\g<lag>}',udtryk2)
|
|
390
|
+
udtryk4=re.sub(r'=',r' & = &',udtryk3,1)
|
|
391
|
+
totud=['Formula:'+udtryk4+r'\\']
|
|
392
|
+
|
|
393
|
+
for i in sorted(model.diffendocur[var].keys()):
|
|
394
|
+
ud=r'\frac{\partial '+var+'}{\partial '+i+'} = '+str(model.diffendocur[var][i])
|
|
395
|
+
ud=re.sub(r'_',r'\_',ud)
|
|
396
|
+
ud2=re.sub(r'(?P<var>[a-zA-Z_]\w*)\((?P<lag>-[0-9]+)\)','\g<var>_{\g<lag>}',ud)
|
|
397
|
+
ud2=re.sub(r'=',r' & = &',ud2,1)
|
|
398
|
+
|
|
399
|
+
totud.append(r''+ud2+r'')
|
|
400
|
+
try:
|
|
401
|
+
totud.append(f'& = & {model.diffvalue[var][i]}')
|
|
402
|
+
except:
|
|
403
|
+
pass
|
|
404
|
+
# print(' ')
|
|
405
|
+
ud=r'\\'.join(totud)
|
|
406
|
+
# display(Latex(r'\begin{align}'+r' \\'+ud+r'\end{align}'))
|
|
407
|
+
display(Latex(r'\begin{eqnarray*}'+ud+r'\end{eqnarray*} '))
|
|
408
|
+
# print( (r'\begin{eqnarray}'+ud+r'\end{eqnarray} '))
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def settozero(instring):
|
|
412
|
+
''' sets subst() or Derivative() to zero in string
|
|
413
|
+
the purpose is to get rid of derivatives of logical espressions
|
|
414
|
+
'''
|
|
415
|
+
value=instring[:].upper()
|
|
416
|
+
try:
|
|
417
|
+
while 'SUBS(' in value:
|
|
418
|
+
forsum, sumudtryk, eftersum = find_arg('SUBS', value)
|
|
419
|
+
value = forsum + '0' + eftersum
|
|
420
|
+
while 'DERIVATIVE(' in value:
|
|
421
|
+
forsum, sumudtryk, eftersum = find_arg('DERIVATIVE', value)
|
|
422
|
+
value = forsum + '0' + eftersum
|
|
423
|
+
except:
|
|
424
|
+
print('*** Error i settozero:',value)
|
|
425
|
+
return value
|
|
426
|
+
|
|
427
|
+
def get_A(model,df,per):
|
|
428
|
+
jacobi = calculate_allmat(model,df,per) # calculate derivative matrix for all lags
|
|
429
|
+
names = sorted(model.endogene)
|
|
430
|
+
A = {l:j.loc[names,names] for l,j in jacobi.items()}
|
|
431
|
+
return A
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def get_AINV(A):
|
|
435
|
+
I=np.eye(A[0].shape[0]) # a idendity matrix
|
|
436
|
+
AINV=linalg.inv(I-A[0])
|
|
437
|
+
out = pd.DataFrame(AINV,index=A[0].index,columns=A[0].columns)
|
|
438
|
+
return out
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def get_compagnion(model,df,per,show=False) :
|
|
442
|
+
|
|
443
|
+
A = get_A(model,df,per)
|
|
444
|
+
AINV=get_AINV(A)
|
|
445
|
+
names = AINV.columns# print(A[0]) # inverse(A)
|
|
446
|
+
# print(AINV) # inverse(A)
|
|
447
|
+
C={lag:np.dot(AINV,A[lag]) for lag in A.keys() if lag < 0} # calculate A**-1*A(lag)
|
|
448
|
+
# print(C)
|
|
449
|
+
dim=AINV.shape[0]
|
|
450
|
+
lags=[lag for lag in sorted(C.keys(),reverse=True)]
|
|
451
|
+
# print('Lags ',lags)
|
|
452
|
+
number= len(lags)
|
|
453
|
+
top=np.eye((number-1)*dim,number*dim,dim)
|
|
454
|
+
bottom=np.bmat([C[tlag] for tlag in sorted(lags) ])
|
|
455
|
+
# print('Top shape ',top.shape)
|
|
456
|
+
# print('Bottom shape',bottom.shape)
|
|
457
|
+
ib2=np.bmat([[top],[bottom]])
|
|
458
|
+
newnames = [c+'('+str(l)+')' for l in sorted(lags,reverse=False) for c in names]
|
|
459
|
+
|
|
460
|
+
out = pd.DataFrame(ib2,index=newnames,columns=newnames)
|
|
461
|
+
# breakpoint()
|
|
462
|
+
return out
|
|
463
|
+
|
|
464
|
+
def get_eigen(model,df,per) :
|
|
465
|
+
comp = get_compagnion(model,df,per)
|
|
466
|
+
compeig=np.linalg.eig(comp) # find the eigenvalues
|
|
467
|
+
return compeig
|
|
468
|
+
|
|
469
|
+
def eigplot0(w):
|
|
470
|
+
fig = plt.figure(figsize=(8,9))
|
|
471
|
+
ax = fig.add_subplot(2, 2,1 , projection='polar')
|
|
472
|
+
ax.set_title('Eigenvalues',loc='left')
|
|
473
|
+
for x in w:
|
|
474
|
+
ax.plot([0,np.angle(x)],[0,np.abs(x)],marker='o',)
|
|
475
|
+
ax.set_rticks([0.5, 1, 1.5])
|
|
476
|
+
langde =[np.abs(x) for x in w if np.abs(x)> -0.00000000000000000000000000000000000000001]
|
|
477
|
+
return fig
|
|
478
|
+
# ax = fig.add_subplot(2,2, 2 )# , projection='polar')
|
|
479
|
+
# ax.hist(langde)
|
|
480
|
+
# ax.set_title('Numbers')
|
|
481
|
+
def eigplot(w,size=(3,3)):
|
|
482
|
+
fig, ax = plt.subplots(figsize=size,subplot_kw={'projection': 'polar'}) #A4
|
|
483
|
+
ax.set_title(' Eigenvalues',loc='right')
|
|
484
|
+
for x in w:
|
|
485
|
+
ax.plot([0,np.angle(x)],[0,np.abs(x)],marker='o')
|
|
486
|
+
ax.set_rticks([0.5, 1, 1.5])
|
|
487
|
+
langde =[np.abs(x) for x in w if np.abs(x)> -0.00000000000000000000000000000000000000001]
|
|
488
|
+
return fig
|
|
489
|
+
# ax = fig.add_subplot(2,2, 2 )# , projection='polar')
|
|
490
|
+
# ax.hist(langde)
|
|
491
|
+
# ax.set_title('Numbers')
|
|
492
|
+
|
|
493
|
+
def stabilitet(model,minnumber=8,maxnumber=8):
|
|
494
|
+
A={lag:modeldiff.calculate_mat(model,lag,endo=True) for lag in val3d.keys()} # calculate derivative matrix for all lags
|
|
495
|
+
I=np.eye(np.shape(A[0])[0]) # a idendity matrix
|
|
496
|
+
AINV=linalg.inv(I-A[0]) # inverse(A)
|
|
497
|
+
C={lag:np.dot(AINV,A[lag]) for lag in A.keys() if lag < 0} # calculate A**-1*A(lag)
|
|
498
|
+
dim=A[0].shape[0]
|
|
499
|
+
lags=[lag for lag in sorted(C.keys(),reverse=True)]
|
|
500
|
+
# print('Lags ',lags)
|
|
501
|
+
eigenval={}
|
|
502
|
+
eigenvec={}
|
|
503
|
+
for number,lag in enumerate(lags):
|
|
504
|
+
if minnumber <= number <= maxnumber:
|
|
505
|
+
print(number,lag)
|
|
506
|
+
top=np.eye(number*dim,(number+1)*dim,dim)
|
|
507
|
+
bottom=np.bmat([C[tlag] for tlag in sorted(lags) if tlag >= lag])
|
|
508
|
+
#print('Top shape ',top.shape)
|
|
509
|
+
#print('Bottom shape',bottom.shape)
|
|
510
|
+
ib2=np.bmat([[top],[bottom]])
|
|
511
|
+
zzz=np.linalg.eig(ib2)
|
|
512
|
+
w,v=zzz # w=egenværdien , v= egenvektorer
|
|
513
|
+
eigenval[lag]=w
|
|
514
|
+
eigenvec[lag]=v
|
|
515
|
+
return eigenval,eigenvec
|
|
516
|
+
|
|
517
|
+
def tout(t):
|
|
518
|
+
if t.lag:
|
|
519
|
+
return f'{t.var}({t.lag})'
|
|
520
|
+
return t.op+t.number+t.var
|
|
521
|
+
|
|
522
|
+
def numdif(model,v,rhv,delta = 0.005,silent=True) :
|
|
523
|
+
# print('**',model.allvar[v]['terms']['frml'])
|
|
524
|
+
def tout(t):
|
|
525
|
+
if t.lag:
|
|
526
|
+
return f'{t.var}({t.lag})'
|
|
527
|
+
return t.op+t.number+t.var
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
nt = model.allvar[v]['terms']
|
|
531
|
+
assignpos = nt.index(model.aequalterm) # find the position of =
|
|
532
|
+
rhsterms = nt[assignpos+1:-1]
|
|
533
|
+
vterm = udtryk_parse(rhv)[0]
|
|
534
|
+
plusterm = udtryk_parse(f'({rhv}+{delta/2})',funks=model.funks)
|
|
535
|
+
minusterm = udtryk_parse(f'({rhv}-{delta/2})',funks=model.funks)
|
|
536
|
+
plus = itertools.chain.from_iterable([plusterm if t == vterm else [t] for t in rhsterms])
|
|
537
|
+
minus = itertools.chain.from_iterable([minusterm if t == vterm else [t] for t in rhsterms])
|
|
538
|
+
eplus = f'({"".join(tout(t) for t in plus)})'
|
|
539
|
+
eminus = f'({"".join(tout(t) for t in minus)})'
|
|
540
|
+
expression = f'({eplus}-{eminus})/{delta}'
|
|
541
|
+
if not silent:
|
|
542
|
+
print(expression)
|
|
543
|
+
return expression
|
|
544
|
+
|
|
545
|
+
if __name__ == '__main__':
|
|
546
|
+
#%%
|
|
547
|
+
def recode(condition,yes,no):
|
|
548
|
+
'''Function which recratetes the functionality of @recode from eviews '''
|
|
549
|
+
return yes if condition else no
|
|
550
|
+
|
|
551
|
+
ftest = '''\
|
|
552
|
+
a= b*2*c**3
|
|
553
|
+
b = a(-1)
|
|
554
|
+
d = recode(a>3,a(-1))
|
|
555
|
+
c= (a>3)
|
|
556
|
+
'''
|
|
557
|
+
mtest = model(ftest,funks=[recode])
|
|
558
|
+
dmodel = diffmodel(mtest,forcenum=1)
|
|
559
|
+
zz = dmodel.equations
|
|
560
|
+
print(zz)
|
|
561
|
+
|