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
model_latex.py
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Sun Dec 3 19:07:03 2017
|
|
4
|
+
|
|
5
|
+
@author: hanseni
|
|
6
|
+
|
|
7
|
+
Mostly to eat latex models and translate to business logic
|
|
8
|
+
|
|
9
|
+
The routines are specific to a style of latex and should be inspected before use
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
from IPython.display import display, Math, Latex, Markdown , Image
|
|
13
|
+
import re
|
|
14
|
+
from IPython.lib.latextools import latex_to_png
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
import modelmanipulation as mp
|
|
19
|
+
import modelclass as mc
|
|
20
|
+
import modelpattern as pt
|
|
21
|
+
def rebank(model):
|
|
22
|
+
''' All variable names are decorated by a {bank}
|
|
23
|
+
The {bank} is injected as the first dimension '''
|
|
24
|
+
|
|
25
|
+
ypat = re.compile(pt.namepat+pt.lagpat)
|
|
26
|
+
funk = set(pt.funkname) | {'SUM'}
|
|
27
|
+
nobank = set('N S T __{bank} NORM PPF CDF'.split()) # specific variable names not to be decorated
|
|
28
|
+
notouch = funk | nobank # names not to be decorated
|
|
29
|
+
def trans(matchobj):
|
|
30
|
+
''' The function recieves a matchobj entity. The matching groups can be accesed by matchobj.group()
|
|
31
|
+
it returns a string with a bankname added at the end or at the first __ which marks dimensions '''
|
|
32
|
+
var = matchobj.group(1)
|
|
33
|
+
lag = '(' + matchobj.group(2) + ')'if matchobj.group(2) else ''
|
|
34
|
+
if var.upper() in notouch:
|
|
35
|
+
return var+lag
|
|
36
|
+
else:
|
|
37
|
+
if '__' in var:
|
|
38
|
+
pre,post = var.split('__',1)
|
|
39
|
+
post = ''+post
|
|
40
|
+
else:
|
|
41
|
+
pre = var
|
|
42
|
+
post = ''
|
|
43
|
+
|
|
44
|
+
return (pre+'__{bank}'+post + lag)
|
|
45
|
+
|
|
46
|
+
banked = ypat.sub(trans, model)
|
|
47
|
+
return banked
|
|
48
|
+
|
|
49
|
+
#print(rebank('a+b'))
|
|
50
|
+
#print(rebank('a(-1)+yyy+cc+bb__x'))
|
|
51
|
+
|
|
52
|
+
def txttolatex(model):
|
|
53
|
+
# takes a template model to latex
|
|
54
|
+
tpoc2 = model[:]
|
|
55
|
+
#tpoc2 = re.sub(r'((list)|(do)|(enddo)|(ppppend))[^$]+[$]','',tpoc2)
|
|
56
|
+
tpoc2 = re.sub(r'((list)|(do)|(enddo)|(ppppend))([^$]*) [$]',r' \\mbox{\1 \6} \\\\ \n',tpoc2)
|
|
57
|
+
tpoc2 = re.sub(r'__{bank}',r'^{bank}',tpoc2)
|
|
58
|
+
tpoc2 = re.sub(r'diff()',r'\Delta ',tpoc2)
|
|
59
|
+
tpoc2 = re.sub(r'norm.ppf',r'\Phi ',tpoc2)
|
|
60
|
+
tpoc2 = re.sub(r'norm.cdf',r'\Phi^{-1} ',tpoc2)
|
|
61
|
+
tpoc2 = re.sub(r'__{CrCountry}__{PortSeg}' ,r'_{CrCountry,PortSeg}',tpoc2) # two subscribt indexes
|
|
62
|
+
tpoc2 = re.sub(r'__{CrModelGeo}__{CrModel}',r'_{CrModelGeo,CrModel}',tpoc2) # two subscribt indexes
|
|
63
|
+
tpoc2 = re.sub(r'\$',r' \\\\[10pt] ',tpoc2)
|
|
64
|
+
tpoc2 = re.sub(r'!([^\n]*\n)',r' & \mbox{ ! \1 } & \\\\[10pt]',tpoc2)
|
|
65
|
+
#tpoc2 = re.sub(r'\n',r'',tpoc2) # remove all linebreaks
|
|
66
|
+
tpoc2 = re.sub(r'frml <>','',tpoc2)
|
|
67
|
+
tpoc2 = re.sub(r'sum\(([a-zA-Z{}]+),',r'\\sum_{\mbox{\1 }}',tpoc2)
|
|
68
|
+
tpoc2 = re.sub(r'[(]-1[)]',r'{\small[t-1]}',tpoc2)
|
|
69
|
+
tpoc2 = re.sub(r'=',r' &=',tpoc2)
|
|
70
|
+
tpoc2 = re.sub(r'([a-zA-Z])_([a-zA-Z])',r'\1\_\2',tpoc2)
|
|
71
|
+
tpoc2 = re.sub(r'([a-zA-Z])__([a-zA-Z])',r'\1\_\_\2',tpoc2)
|
|
72
|
+
tpoc2 = r'\begin{align*}'+tpoc2+r'\end{align*}'
|
|
73
|
+
return(tpoc2)
|
|
74
|
+
|
|
75
|
+
def defrack(streng):
|
|
76
|
+
'''
|
|
77
|
+
\frac{xxx}{yyy} = ((xxx)/(yyy))
|
|
78
|
+
|
|
79
|
+
'''
|
|
80
|
+
tstreng = streng[:]
|
|
81
|
+
tfunk = r'\frac{'
|
|
82
|
+
while tfunk in tstreng:
|
|
83
|
+
start = tstreng.find(tfunk)
|
|
84
|
+
# first find the first matching {}
|
|
85
|
+
match = tstreng[start + len(tfunk):] # the rest of the string in which we have to match }
|
|
86
|
+
open = 1 # we already found the first {
|
|
87
|
+
for index1 in range(len(match)):
|
|
88
|
+
if match[index1] in '{}':
|
|
89
|
+
open = (open + 1) if match[index1] == '{' else (open - 1)
|
|
90
|
+
if not open:
|
|
91
|
+
break
|
|
92
|
+
# now find the second matching {}
|
|
93
|
+
match2 = match[index1 + 1+1:] # the string from the location of second { to the end of string
|
|
94
|
+
open=1
|
|
95
|
+
for index2 in range(len(match2)):
|
|
96
|
+
if match2[index2] in '{}':
|
|
97
|
+
open = (open + 1) if match2[index2] == '{' else (open - 1)
|
|
98
|
+
if not open:
|
|
99
|
+
break
|
|
100
|
+
tstreng = tstreng[:start]+ '(('+ match[:index1] +')/('+ match2[:index2]+'))'+match2[index2+1:]
|
|
101
|
+
return tstreng
|
|
102
|
+
def debrace(streng):
|
|
103
|
+
'''
|
|
104
|
+
Eliminates underbrace{xxx}_{yyy} in a string
|
|
105
|
+
underbrace{xxx}_{yyy} => (xxx)
|
|
106
|
+
As there can be nested {} we need to match the braces
|
|
107
|
+
|
|
108
|
+
'''
|
|
109
|
+
tstreng = streng[:]
|
|
110
|
+
tfunk = r'\underbrace{'
|
|
111
|
+
while tfunk in tstreng:
|
|
112
|
+
start = tstreng.find(tfunk)
|
|
113
|
+
match = tstreng[start + len(tfunk):]
|
|
114
|
+
open = 1
|
|
115
|
+
for index1 in range(len(match)):
|
|
116
|
+
if match[index1] in '{}':
|
|
117
|
+
open = (open + 1) if match[index1] == '{' else (open - 1)
|
|
118
|
+
if not open:
|
|
119
|
+
break
|
|
120
|
+
goodstuf = tstreng[:start]+match[index1]
|
|
121
|
+
match2 = match[index1 + 1+2:]
|
|
122
|
+
open=1
|
|
123
|
+
for index2 in range(len(match2)):
|
|
124
|
+
if match2[index2] in '{}':
|
|
125
|
+
open = (open + 1) if match2[index2] == '{' else (open - 1)
|
|
126
|
+
if not open:
|
|
127
|
+
break
|
|
128
|
+
tstreng = tstreng[:start]+ ''+ match[:index1] +''+ match2[index2+1:]
|
|
129
|
+
return tstreng
|
|
130
|
+
|
|
131
|
+
def defunk(funk, subs , streng,startp='{',slutp='}'):
|
|
132
|
+
'''
|
|
133
|
+
\funk{xxx} => subs(xxx)
|
|
134
|
+
|
|
135
|
+
in a string
|
|
136
|
+
'''
|
|
137
|
+
tfunk, tstreng = funk[:] , streng[:]
|
|
138
|
+
tfunk = tfunk + startp
|
|
139
|
+
while tfunk in tstreng:
|
|
140
|
+
start = tstreng.find(tfunk)
|
|
141
|
+
match = tstreng[start + len(tfunk):]
|
|
142
|
+
open = 1
|
|
143
|
+
for index in range(len(match)):
|
|
144
|
+
if match[index] in startp+slutp:
|
|
145
|
+
open = (open + 1) if match[index] == startp else (open - 1)
|
|
146
|
+
if not open:
|
|
147
|
+
break
|
|
148
|
+
tstreng = tstreng[:start]+subs+'(' + match[:index] +')' + match[index + 1:]
|
|
149
|
+
return tstreng
|
|
150
|
+
#print(defunk(r'\sqrt',r'sqrt',r'a=\sqrt{b+ \sqrt{f+y}}'))
|
|
151
|
+
#print(defunk(r'\log',r'log',r'a=\log(b(-1)+ \log({f+y}))',startp='(',slutp=')'))
|
|
152
|
+
|
|
153
|
+
def findindex(ind):
|
|
154
|
+
''' find the index variables on the left hand side. meaning variables braced by {} '''
|
|
155
|
+
lhs=ind.split('=')[0]
|
|
156
|
+
return re.findall(r'\{([A-Za-z][\w]*)\}',lhs ) # all the index variables
|
|
157
|
+
|
|
158
|
+
def doable(ind,show=False):
|
|
159
|
+
''' find all dimensions in the left hand side of = and and decorate with the nessecary do .. enddo '''
|
|
160
|
+
|
|
161
|
+
xxy = findindex(ind) # all the index variables
|
|
162
|
+
xxx = ['n_{bank}' if index == 'n' else index for index in xxy]
|
|
163
|
+
if xxx :
|
|
164
|
+
pre = ' $ '.join(['Do '+i for level,i in enumerate(xxx)])+' $ \n '
|
|
165
|
+
post = '\n' + 'enddo $ '*len(xxx)
|
|
166
|
+
out = pre+ind + post
|
|
167
|
+
if show:
|
|
168
|
+
print('Before doable',ind,sep='\n')
|
|
169
|
+
print('After doable',out,sep='\n')
|
|
170
|
+
print()
|
|
171
|
+
else:
|
|
172
|
+
out=ind
|
|
173
|
+
return out
|
|
174
|
+
|
|
175
|
+
def findlists(input):
|
|
176
|
+
'''extracte liste from latex'''
|
|
177
|
+
relevant = re.findall(r'LIST \s*\$[^$]*\$',input.upper())
|
|
178
|
+
temp1 = [l.replace('$','').replace('\\','').replace(',',' ')
|
|
179
|
+
.replace('{','').replace('}','')
|
|
180
|
+
for l in relevant]
|
|
181
|
+
temp2 = [l.split('=')[0]+' = '
|
|
182
|
+
+ l.split('=')[0][4:]
|
|
183
|
+
+' : '+ l.split('=')[1]+'$' for l in temp1]
|
|
184
|
+
return temp2
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def findlistsnew(input):
|
|
188
|
+
'''extracte list with sublist from latex'''
|
|
189
|
+
# relevant = re.findall(r'LIST \s*\$[^$]*\$',input.upper())
|
|
190
|
+
relevant = re.findall(r'\$LIST\s*\\;\s*[^$]*\$',input.upper())
|
|
191
|
+
|
|
192
|
+
print(f'{relevant=}')
|
|
193
|
+
temp1 = [l.replace('$','').replace('\\','').replace(',',' ')
|
|
194
|
+
.replace('{','').replace('}','').replace('\n','/ \n')
|
|
195
|
+
for l in relevant]
|
|
196
|
+
print(f'{temp1=}')
|
|
197
|
+
temp2 = [l.split('=')[0]+' = '
|
|
198
|
+
+ l.split('=')[0][4:]
|
|
199
|
+
+' : '+ l.split('=')[1]+'$' for l in temp1]
|
|
200
|
+
return temp2
|
|
201
|
+
|
|
202
|
+
def findlistsx(input):
|
|
203
|
+
'''extracte list with sublist from latex'''
|
|
204
|
+
relevant = re.findall(r'\$LIST\s*\\;\s*[^$]*\$',input.upper())
|
|
205
|
+
print(f'{relevant=}')
|
|
206
|
+
temp1 = [l.replace('$','').replace('\\','')
|
|
207
|
+
.replace(',',' ').replace(';',' ')
|
|
208
|
+
.replace('{','').replace('}','').replace('\n','/ \n')
|
|
209
|
+
for l in relevant]
|
|
210
|
+
print(f'{temp1=}')
|
|
211
|
+
temp2 = ['LIST ' + l.split('=')[0][4:].strip() +' = '
|
|
212
|
+
+ l.split('=')[0][4:]
|
|
213
|
+
+' : '+ l.split('=')[1]+'$' for l in temp1]
|
|
214
|
+
|
|
215
|
+
print(f'{temp2=}')
|
|
216
|
+
return ('\n'.join(temp2)+'\n')
|
|
217
|
+
|
|
218
|
+
if 0:
|
|
219
|
+
listtest=r'''
|
|
220
|
+
$List \; stage=\{s1, s2,s3\} \\
|
|
221
|
+
stagened:\{ 0, 0, 1,\} $
|
|
222
|
+
'''
|
|
223
|
+
print(findlists(listtest))
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def latextotxt(input,dynare=False,bankadd=False):
|
|
228
|
+
'''
|
|
229
|
+
Translates a latex input to a BL output
|
|
230
|
+
|
|
231
|
+
'''
|
|
232
|
+
# breakpoint()
|
|
233
|
+
ex12 = re.findall(r'\\label\{eq:(.*?)\}\n(.*?)\\end\{',input,re.DOTALL) # select the relevant equations
|
|
234
|
+
org = [(name,eq.replace('\n','')) for name,ex in ex12 for eq in ex.split('\\\\')
|
|
235
|
+
if 2 == len(eq.split('='))]
|
|
236
|
+
# ex15 = [('frml '+name+' '+eq) for (name,ex) in ex12 for eq in ex.splitlines()]
|
|
237
|
+
ex15 = [eq.strip() for (name,eq) in org]
|
|
238
|
+
temp = '\n'.join(ex15)
|
|
239
|
+
trans={r'\left':'',
|
|
240
|
+
r'\right':'',
|
|
241
|
+
r'\min':'min',
|
|
242
|
+
r'\max':'max',
|
|
243
|
+
r'\rho':'rho',
|
|
244
|
+
r'\tau':'tau',
|
|
245
|
+
r'\sigma':'sigma',
|
|
246
|
+
r'&':'',
|
|
247
|
+
r'\\':'',
|
|
248
|
+
r'[':'(',
|
|
249
|
+
r']':')',
|
|
250
|
+
r'&':'',
|
|
251
|
+
r'\nonumber' : '',
|
|
252
|
+
r'\_' : '_',
|
|
253
|
+
r'{n}' : '__{n}',
|
|
254
|
+
r'_{t}' : '',
|
|
255
|
+
r'{n,s}' : '__{n}__{s}',
|
|
256
|
+
r'{n,s,t}' : '__{n}__{s}__{t}',
|
|
257
|
+
'logit^{-1}' : 'logit_inverse',
|
|
258
|
+
r'\{' : '{',
|
|
259
|
+
r'\}' : '}',
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
ftrans = {
|
|
264
|
+
r'\sqrt':'sqrt',
|
|
265
|
+
r'\Delta':'diff',
|
|
266
|
+
r'\sum_':'sum',
|
|
267
|
+
r'\Phi':'NORM.CDF',
|
|
268
|
+
r'\Phi^{-1}':'NORM.PDF'
|
|
269
|
+
}
|
|
270
|
+
regtrans = {
|
|
271
|
+
r'\\Delta ([A-Za-z_][\w{},\^]*)':r'diff(\1)', # \Delta xy => diff(xy)
|
|
272
|
+
r'_{t-([1-9])}' : r'(-\1)', # _{t-x} => (-x)
|
|
273
|
+
|
|
274
|
+
# r'\^([\w])' : r'_\1', # ^x => _x
|
|
275
|
+
# r'\^\{([\w]+)\}(\w)' : r'_\1_\2', # ^{xx}y => _xx_y
|
|
276
|
+
r'\^\{([\w]+)\}' : r'_{\1}', # ^{xx} => _xx
|
|
277
|
+
r'\^\{([\w]+),([\w]+)\}' : r'_{\1}_{\2}', # ^{xx,yy} => _xx_yy
|
|
278
|
+
r'\s*\\times\s*':'*' ,
|
|
279
|
+
}
|
|
280
|
+
# breakpoint()
|
|
281
|
+
for before,to in ftrans.items():
|
|
282
|
+
temp = defunk(before,to,temp)
|
|
283
|
+
for before,to in trans.items():
|
|
284
|
+
temp = temp.replace(before,to)
|
|
285
|
+
for before,to in regtrans.items():
|
|
286
|
+
temp = re.sub(before,to,temp)
|
|
287
|
+
temp = debrace(temp)
|
|
288
|
+
temp = defrack(temp)
|
|
289
|
+
if bankadd:
|
|
290
|
+
temp = rebank(temp)
|
|
291
|
+
|
|
292
|
+
# breakpoint()
|
|
293
|
+
temp = re.sub(r'sum\(n,s,t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
294
|
+
temp = re.sub(r'sum\(n\)sum\(s\)sum\(t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
295
|
+
temp = re.sub(r'sum\(n\)'+(pt.namepat),r'sum(n_{bank},\1)',temp)
|
|
296
|
+
temp = re.sub(fr'sum\({pt.namepat}\)\(',r'sum(\1,',temp)
|
|
297
|
+
|
|
298
|
+
ltemp = [b.strip().split('=') for b in temp.splitlines()] # remove blanks in the ends and split each line at =
|
|
299
|
+
# breakpoint()
|
|
300
|
+
ltemp = [lhs + ' = '+ rhs.replace(' ','') for lhs,rhs in ltemp] # change ' ' to * on the rhs.
|
|
301
|
+
ltemp = ['Frml '+fname + ' ' + eq + ' $ 'for eq,(fname,__) in zip(ltemp,org)]
|
|
302
|
+
|
|
303
|
+
ltemp = [doable(l) for l in ltemp]
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
out = '\n'.join(ltemp+findlists(input))
|
|
307
|
+
return out
|
|
308
|
+
|
|
309
|
+
def latextotxtnew(input):
|
|
310
|
+
'''
|
|
311
|
+
Translates a latex input to a BL output
|
|
312
|
+
|
|
313
|
+
'''
|
|
314
|
+
# breakpoint()
|
|
315
|
+
ex12 = re.findall(r'\\label\{eq:(.*?)\}\n(.*?)\\end\{',input,re.DOTALL) # select the relevant equations
|
|
316
|
+
org = [(name,eq.replace('\n','')) for name,ex in ex12 for eq in ex.split('\\\\')
|
|
317
|
+
if 2 == len(eq.split('='))]
|
|
318
|
+
# ex15 = [('frml '+name+' '+eq) for (name,ex) in ex12 for eq in ex.splitlines()]
|
|
319
|
+
ex15 = [eq.strip() for (name,eq) in org]
|
|
320
|
+
temp = '\n'.join(ex15)
|
|
321
|
+
trans={r'\left':'',
|
|
322
|
+
r'\right':'',
|
|
323
|
+
r'\min':'min',
|
|
324
|
+
r'\max':'max',
|
|
325
|
+
r'\rho':'rho',
|
|
326
|
+
r'&':'',
|
|
327
|
+
r'\\':'',
|
|
328
|
+
r'[':'(',
|
|
329
|
+
r']':')',
|
|
330
|
+
r'&':'',
|
|
331
|
+
r'\nonumber' : '',
|
|
332
|
+
r'\_' : '_',
|
|
333
|
+
r'{n}' : '__{n}',
|
|
334
|
+
r'_{t}' : '',
|
|
335
|
+
r'{n,s}' : '__{n}__{s}',
|
|
336
|
+
r'{n,s,t}' : '__{n}__{s}__{t}',
|
|
337
|
+
'logit^{-1}' : 'logit_inverse',
|
|
338
|
+
r'\{' : '{',
|
|
339
|
+
r'\}' : '}',
|
|
340
|
+
r'\sigma' :'sigma',
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
}
|
|
344
|
+
ftrans = {
|
|
345
|
+
r'\sqrt':'sqrt',
|
|
346
|
+
r'\Delta':'diff',
|
|
347
|
+
r'\sum_':'sum',
|
|
348
|
+
r'\Phi':'NORM.CDF',
|
|
349
|
+
r'\Phi^{-1}':'NORM.PDF'
|
|
350
|
+
}
|
|
351
|
+
regtrans = {
|
|
352
|
+
r'\\Delta ([A-Za-z_][\w{},\^]*)':r'diff(\1)', # \Delta xy => diff(xy)
|
|
353
|
+
r'_{t-([1-9])}' : r'(-\1)', # _{t-x} => (-x)
|
|
354
|
+
|
|
355
|
+
# r'\^([\w])' : r'_\1', # ^x => _x
|
|
356
|
+
# r'\^\{([\w]+)\}(\w)' : r'_\1_\2', # ^{xx}y => _xx_y
|
|
357
|
+
r'\^\{([\w]+)\}' : r'_{\1}', # ^{xx} => _xx
|
|
358
|
+
r'\^\{([\w]+),([\w]+)\}' : r'_{\1}_{\2}', # ^{xx,yy} => _xx_yy
|
|
359
|
+
r'\s*\\times\s*':'*' ,
|
|
360
|
+
}
|
|
361
|
+
# breakpoint()
|
|
362
|
+
for before,to in ftrans.items():
|
|
363
|
+
temp = defunk(before,to,temp)
|
|
364
|
+
for before,to in trans.items():
|
|
365
|
+
temp = temp.replace(before,to)
|
|
366
|
+
for before,to in regtrans.items():
|
|
367
|
+
temp = re.sub(before,to,temp)
|
|
368
|
+
temp = debrace(temp)
|
|
369
|
+
temp = defrack(temp)
|
|
370
|
+
if bankadd:
|
|
371
|
+
temp = rebank(temp)
|
|
372
|
+
|
|
373
|
+
# breakpoint()
|
|
374
|
+
temp = re.sub(r'sum\(n,s,t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
375
|
+
temp = re.sub(r'sum\(n\)sum\(s\)sum\(t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
376
|
+
temp = re.sub(r'sum\(n\)'+(pt.namepat),r'sum(n_{bank},\1)',temp)
|
|
377
|
+
temp = re.sub(fr'sum\({pt.namepat}\)\(',r'sum(\1,',temp)
|
|
378
|
+
|
|
379
|
+
ltemp = [b.strip().split('=') for b in temp.splitlines()] # remove blanks in the ends and split each line at =
|
|
380
|
+
# breakpoint()
|
|
381
|
+
ltemp = [lhs + ' = '+ rhs.replace(' ','') for lhs,rhs in ltemp] # change ' ' to * on the rhs.
|
|
382
|
+
ltemp = ['Frml '+fname + ' ' + eq + ' $ 'for eq,(fname,__) in zip(ltemp,org)]
|
|
383
|
+
|
|
384
|
+
ltemp = [doable(l) for l in ltemp]
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
out = '\n'.join(ltemp+findlists(input))
|
|
388
|
+
return out
|
|
389
|
+
|
|
390
|
+
def dynlatextotxt(input,show=False):
|
|
391
|
+
'''
|
|
392
|
+
Translates a latex input to a BL output
|
|
393
|
+
The latex input is the latex output of Dynare
|
|
394
|
+
|
|
395
|
+
'''
|
|
396
|
+
with mc.ttimer('Findall',show):
|
|
397
|
+
ex12 = re.findall(r'\\begin{dmath}\n(.*?)\n\\end{dmath}',input,re.DOTALL) # select the relevant equations
|
|
398
|
+
|
|
399
|
+
with mc.ttimer('Split',show):
|
|
400
|
+
org = [' = '.join([side[:] for side in e.split('=',1)]) for e in ex12]
|
|
401
|
+
# ex15 = [('frml '+name+' '+eq) for (name,ex) in ex12 for eq in ex.splitlines()]
|
|
402
|
+
with mc.ttimer('Strip',show):
|
|
403
|
+
ex15 = [defrack(eq.strip()) for eq in org]
|
|
404
|
+
with mc.ttimer('join',show):
|
|
405
|
+
temp = '\n'.join(ex15)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
trans={r'\left':'',
|
|
409
|
+
r'\right':'',
|
|
410
|
+
r'\min':'min',
|
|
411
|
+
r'\max':'max',
|
|
412
|
+
r'&':'',
|
|
413
|
+
r'\\':'',
|
|
414
|
+
r'\_':'_',
|
|
415
|
+
r'[':'(',
|
|
416
|
+
r']':')',
|
|
417
|
+
r'&':'',
|
|
418
|
+
r'_{t}': '',
|
|
419
|
+
r'\,': ' *',
|
|
420
|
+
r'\leq': ' <= ',
|
|
421
|
+
r'\neq': ' != ',
|
|
422
|
+
r'\geq': ' >= ',
|
|
423
|
+
|
|
424
|
+
}
|
|
425
|
+
ftrans = { # before{expression} ==> after(expression)
|
|
426
|
+
r'\sqrt':'sqrt',
|
|
427
|
+
r'\Delta':'diff',
|
|
428
|
+
r'^':'^',
|
|
429
|
+
r'\sum_':'sum'
|
|
430
|
+
}
|
|
431
|
+
ftransp = {
|
|
432
|
+
r'\log':'log',
|
|
433
|
+
}
|
|
434
|
+
regtrans = {
|
|
435
|
+
r'\\Delta ([A-Za-z][\w{},\^]*)':r'diff(\1)', # \Delta xy => diff(xy)
|
|
436
|
+
r'_{t-([1-9])}' : r'(-\1)', # _{t-x} => (-x)
|
|
437
|
+
'{'+pt.namepat+'}' : r'\1', #
|
|
438
|
+
'{'+pt.namepat+'(?:\\(([+-][0-9]+)\\))}' : r'\1(\2)',
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
# with mc.ttimer('Defrac',show):
|
|
442
|
+
# temp = defrack(temp)
|
|
443
|
+
for before,to in trans.items():
|
|
444
|
+
with mc.ttimer(f'replace {before}',show):
|
|
445
|
+
temp = temp.replace(before,to)
|
|
446
|
+
|
|
447
|
+
for before,to in ftrans.items():
|
|
448
|
+
with mc.ttimer(f'defunk {before}',show):
|
|
449
|
+
temp = defunk(before,to,temp)
|
|
450
|
+
|
|
451
|
+
for before,to in ftransp.items():
|
|
452
|
+
with mc.ttimer(f'defunk {before}',show):
|
|
453
|
+
temp = defunk(before,to,temp,'(',')')
|
|
454
|
+
|
|
455
|
+
for before,to in regtrans.items():
|
|
456
|
+
with mc.ttimer(f'Regtrans {before}'):
|
|
457
|
+
temp = re.sub(before,to,temp)
|
|
458
|
+
# temp = debrace(temp)
|
|
459
|
+
|
|
460
|
+
if show: print('Translation from Latex to BLL finished')
|
|
461
|
+
# temp = re.sub(r'sum\(n,s,t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
462
|
+
# temp = re.sub(r'sum\(n\)sum\(s\)sum\(t\)'+(pt.namepat),r'sum(n_{bank},sum(s,sum(t,\1)))',temp)
|
|
463
|
+
# temp = re.sub(r'sum\(n\)'+(pt.namepat),r'sum(n_{bank},\1)',temp)
|
|
464
|
+
|
|
465
|
+
ltemp = ['Frml <> ' + eq + ' $ 'for eq in temp.splitlines() ]
|
|
466
|
+
|
|
467
|
+
# ltemp = [doable(l) for l in ltemp]
|
|
468
|
+
|
|
469
|
+
out = '\n'.join(ltemp)
|
|
470
|
+
return out
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
if __name__ == '__main__' :
|
|
474
|
+
if 0:
|
|
475
|
+
test = r'''\
|
|
476
|
+
Loans can be in 3 stages, 1,2 3.
|
|
477
|
+
New loans will be generated and loans will mature.
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
\begin{equation}
|
|
481
|
+
\label{eq:Norm}
|
|
482
|
+
TR^{stage\_from,stage} = \frac{TR\_U^{stage\_from,stage}}{1+0*\sum_{stage\_from2}(TR\_U^{stage\_from2,stage})}
|
|
483
|
+
\times(1-M^{stage}-WRO^{stage})
|
|
484
|
+
\end{equation}
|
|
485
|
+
|
|
486
|
+
List $stage=\{s1, s2,s3\}$
|
|
487
|
+
|
|
488
|
+
List $stage\_from=\{s1, s2,s3\}$
|
|
489
|
+
|
|
490
|
+
List $stage\_from2=\{s1, s2,s3\}$
|
|
491
|
+
|
|
492
|
+
List $stage\_to=\{s1, s2,s3\}$
|
|
493
|
+
|
|
494
|
+
'''
|
|
495
|
+
res = latextotxt(test)
|
|
496
|
+
|
|
497
|
+
|