def modelprint(ind, title=' A model', udfil='', short=0): ''' prettyprinter for a a model. :udfil: if present is output file :short: if present condences the model Can handle both model templates and models ''' import sys f = sys.stdout if udfil: f = open(udfil, 'w+') maxlenfnavn, maxlenlhs, maxlenrhs = 0, 0, 0 for comment, command, value in find_statements(ind): if command.upper() == 'FRML': a, fr, n, udtryk = split_frml(command.upper() + ' ' + value) lhs, rhs = udtryk.split('=', 1) maxlenfnavn = max(maxlenfnavn, len(n)) # Finds the max length of frml name maxlenlhs = max( maxlenlhs, len(lhs)) # finds the max length of left hand variable print('! ' + title, file=f) dolevel = 0 for comment, command, value in find_statements(ind): print(' ' * dolevel, end='', file=f) if comment: print(comment, file=f) else: if command.upper() == 'FRML': a, fr, n, udtryk = split_frml(command.upper() + ' ' + value) lhs, rhs = udtryk.split('=', 1) if short: print(fr.ljust(5), 'X', lhs.strip().ljust(maxlenlhs), '=', rhs, file=f) else: rhs = re.sub(' +', ' ', rhs) print(fr.ljust(5), n.strip().ljust(maxlenfnavn), lhs.strip().ljust(maxlenlhs), '=', rhs.replace( '\n', '\n' + (' ' * dolevel) + (' ' * (10 + maxlenfnavn + maxlenlhs))), file=f) elif command.upper() == 'DO': print(command, ' ', value, file=f) dolevel = dolevel + 1 elif command.upper() == 'ENDDO': print(command, ' ', value, file=f) dolevel = dolevel - 1 else: print(command, ' ', value, file=f)
def normalizesym(in_equations): ''' Normalizes equations by using sympy ''' nymodel = [] equations = in_equations[:] # we want do change the e # modelprint(equations) for comment, command, value in find_statements(equations.upper()): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) elif command == 'FRML': a, fr, n, udtryk = split_frml((command + ' ' + value).upper()) while 'DLOG(' in udtryk.upper(): fordlog, dlogudtryk, efterdlog = find_arg('dlog', udtryk) udtryk = fordlog + 'diff(log(' + dlogudtryk + '))' + efterdlog while 'LOGIT(' in udtryk.upper(): forlogit, logitudtryk, efterlogit = find_arg( 'LOGIT', udtryk) udtryk = forlogit + '(log(' + logitudtryk + '/(1.0 -' + logitudtryk + ')))' + efterlogit while 'DIFF(' in udtryk.upper(): fordif, difudtryk, efterdif = find_arg('diff', udtryk) udtryk = fordif + '((' + difudtryk + ')-(' + lagone( difudtryk + '', funks=funks) + '))' + efterdif nymodel.append(command + ' ' + n + ' ' + findendo(udtryk)) else: nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) # modelprint(equations) return equations
def kaedeunroll(in_equations, funks=[]): ''' unrolls a chain (kaede) expression - used in the SMEC moedel ''' nymodel = [] equations = in_equations[:] # we want do change the e # modelprint(equations) for comment, command, value in find_statements(equations.upper()): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) elif command == 'FRML': a, fr, n, udtryk = split_frml((command + ' ' + value).upper()) while 'KAEDE(' in udtryk.upper(): forkaede, kaedeudtryk, efterkaede = find_arg('KAEDE', udtryk) arg = kaedeudtryk.split(',') taller, navner = '(', '(' for i in range(len(arg) / 2): j = i * 2 taller = taller + arg[j] + '*(' + lagone( arg[j + 1] + '/' + arg[j], funks=funks) + ')+' navner = navner + lagone(arg[j + 1], funks=funks) + '+' navner = navner[:-1] + ')' taller = taller[:-1] + ')' #print(taller,'/',navner) udtryk = forkaede + '(' + taller + '/' + navner + ')' + efterkaede while 'KAEDEP(' in udtryk.upper(): forkaede, kaedeudtryk, efterkaede = find_arg('KAEDEP', udtryk) arg = kaedeudtryk.split(',') #print(arg,len(arg)/2) taller, navner = '(', '(' for i in range(len(arg) / 2): j = i * 2 taller = taller + arg[j] + '*' + lagone(arg[j + 1], funks=funks) + '+' navner = navner + lagone( arg[j], funks=funks) + '+' + lagone(arg[j + 1], funks=funks) + '+' navner = navner[:-1] + ')' taller = taller[:-1] + ')' #print(taller,'/',navner) udtryk = forkaede + '(' + taller + '/' + navner + ')' + efterkaede while 'MOVAVG(' in udtryk.upper(): forkaede, kaedeudtryk, efterkaede = find_arg('MOVAVG', udtryk) arg = kaedeudtryk.split(',', 1) avg = '((' term = arg[1] #print(arg,len(arg)/2) antal = int(arg[0]) for i in range(antal): avg = avg[:] + term[:] + '+' term = lagone(term, funks=funks) avg = avg[:-1] + ')/' + str(antal) + '.0)' #print(taller,'/',navner) udtryk = forkaede + avg + efterkaede nymodel.append(command + ' ' + n + ' ' + udtryk) else: nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
def check_syntax_frml(frml): ''' check syntax of frml ''' try: a, fr, n, udtryk = split_frml(frml) ast.parse(re.sub(r'\n', '', re.sub(' ', '', udtryk[:-1]))) return True except: return False
def find_hist_model(equations): ''' takes a unrolled model and create a model which can be run for historic periode \n The model calculates residuals for equations with a <res= > clause and \n and the identities are also calculeted''' hist = [] for f in find_frml(equations): hist.append(find_res(f)) a, fr, n, udtryk = split_frml(f.upper()) if kw_frml_name(n, 'IDENT') or kw_frml_name(n, 'I'): # identites are just replicated in order to calculate backdata hist.append(f) return (' '.join(hist))
def normalizehift(in_equations): ''' Normalizes equations by shuffeling terms around \n can handel LOG, DLOG and DIF in the left hans side of = ''' nymodel=[] equations=in_equations[:] # we want do change the e # modelprint(equations) for comment,command,value in find_statements(equations.upper()): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) elif command=='FRML': a,fr,n,udtryk=split_frml((command+' '+value).upper()) lhs,rhs=udtryk.split('=',1) lhsterms=udtryk_parse(lhs,funks=funks) if len(lhsterms) == 1: # only one term on the left hand side, no need to shuffel around pass elif len(lhsterms) == 4: # We need to normalixe expect funk(x) on the levt hand side funk=LOG,DLOG or DIFF rhs=rhs[:-1].strip() # discharge the $ strip blanks for nice look lhs=lhsterms[2].var # name of the dependent variablem, no syntax check here if lhsterms[0].op == 'LOG': rhs='EXP('+rhs+')' udtryk=lhs+'='+rhs+'$' # now the equation is normalized elif lhsterms[0].op == 'DIFF': rhs=lagone(lhs,funks=funks)+'+('+rhs+')' udtryk=lhs+'='+rhs+'$' # now the equation is normalized elif lhsterms[0].op == 'DLOG': rhs='EXP(LOG('+lagone(lhs,funks=funks)+')+'+rhs+')' udtryk=lhs+'='+rhs+'$' # now the equation is normalized elif lhsterms[0].op == 'LOGIT': rhs='(exp('+rhs+')/(1+EXP('+rhs+')))' udtryk=lhs+'='+rhs+'$' # now the equation is normalized # else: # print('*** ERROR operand not allowed left of =',lhs) # print(lhsterms) else: pass # print('*** Try to normalize relation for:',lhs) # now the right hand side is expanded for DLOG and DIFF while 'DLOG(' in udtryk.upper(): fordlog,dlogudtryk,efterdlog=find_arg('dlog',udtryk) udtryk=fordlog+'diff(log('+dlogudtryk+'))'+efterdlog while 'DIFF(' in udtryk.upper(): fordif,difudtryk,efterdif=find_arg('diff',udtryk) udtryk=fordif+'(('+difudtryk+')-('+lagone(difudtryk+'',funks=funks)+'))'+efterdif nymodel.append(command+' '+n+' '+udtryk) else: nymodel.append(command+' '+value) equations='\n'.join(nymodel) # modelprint(in_equations,'Before normalization and expansion') # modelprint(equations, 'After normalization and expansion') return equations
def adam_exounroll(in_equations): ''' takes a model and makes a new model by enhancing frml's with <exo=,j=,jr=> in their frml name. :exo: the value can be fixed in to a value valuename_x by setting valuename_d=1 :jled: a additiv adjustment element is added to the frml :jrled: a multiplicativ adjustment element is added to the frml ''' nymodel = [] equations = in_equations[:] # we want do change the e for comment, command, value in find_statements(equations.upper()): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) elif command == 'FRML': a, fr, n, udtryk = split_frml((command + ' ' + value).upper()) #print(fr,n, kw_frml_name(n.upper(),'EXO')) # we want a relatov adjustment if kw_frml_name(n, 'JRLED') or kw_frml_name(n, 'JR'): lhs, rhs = udtryk.split('=', 1) udtryk = lhs + \ '= (' + rhs[:-1] + ')*(1+JR' + lhs.strip() + ' )' + '$' if kw_frml_name(n, 'JD'): lhs, rhs = udtryk.split('=', 1) udtryk = lhs + \ '= (' + rhs[:-1] + ')+(JD' + lhs.strip() + ' )' + '$' if kw_frml_name(n, 'JLED') or kw_frml_name(n, 'J'): lhs, rhs = udtryk.split('=', 1) # we want a absolute adjustment udtryk = lhs + '=' + rhs[:-1] + '+ J' + lhs.strip() + '$' if kw_frml_name(n, 'EXO'): lhs, rhs = udtryk.split('=', 1) endogen = lhs.strip() dummy = 'D' + endogen exogen = 'Z' + endogen udtryk = lhs + \ '=(' + rhs[:-1] + ')*(1-' + dummy + ')+' + exogen + '*' + dummy + '$' nymodel.append(command + ' ' + n + ' ' + udtryk) else: nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
def find_res_dynare_new(equations): ''' equations to calculat _res formulas FRML <> x=a*b+c +x_RES $ -> FRML <> x_res =x-a*b+c $ not finished to speed time up ''' out = [] for f in find_frml(equations): a, fr, n, udtryk = split_frml(f.upper()) lhs, rhs = udtryk.split('=', 1) lhs = lhs.strip() rhs = rhs.strip()[:-1] res = lhs + '_RES' if res in rhs: rep = rhs.replace(res, '').strip()[:-1] new = f'frml <> {res} = {lhs} - ({rep}) $' out.append(new) return '\n'.join(out)
def find_res(f): ''' Finds the expression which calculates the residual in a formel. FRML <res=a,endo=b> x=a*b+c $ ''' from sympy import solve, sympify a, fr, n, udtryk = split_frml(f.upper()) udres = '' tres = kw_frml_name(n, 'RES') if tres: lhs, rhs = udtryk.split('=', 1) res = lhs.strip() + '_J' if tres == 'J' else lhs.strip() + \ '_JR' if tres == 'JR' else tres # we take the the $ out kat = sympify('Eq(' + lhs + ',' + rhs[0:-1] + ')') res_frml = sympify('res_frml') res_frml = solve(kat, res) udres = 'FRML ' + 'RES' + ' ' + \ res.ljust(25) + ' = ' + str(res_frml)[1:-1] + ' $' return udres
def find_res_dynare(equations): ''' equations to calculat _res formulas FRML <> x=a*b+c +x_RES $ -> FRML <> x_res =x-a*b+c $''' from sympy import solve, sympify out=[] for f in find_frml(equations): a, fr, n, udtryk = split_frml(f.upper()) lhs, rhs = udtryk.split('=', 1) res= lhs.strip()+'_RES' if res in rhs: # we take the the $ out kat = sympify('Eq(' + lhs + ',' + rhs[0:-1] + ')') res_frml = sympify('res_frml') res_frml = solve(kat, res) udres = 'FRML ' + 'RES' + ' ' + res + ' = ' + str(res_frml)[1:-1] + ' $' out.append(udres) return '\n'.join(out)
def frml_code_translate(in_equations): ''' takes a model and makes a new model by translating PCIM frml_codes to ModelFlow frml_names :exo: the value can be fixed in to a value valuename_x by setting valuename_d=1 :jled: a additiv adjustment element is added to the frml :jrled: a multiplicativ adjustment element is added to the frml ''' nymodel = [] equations = in_equations[:] # we want do change the e for comment, command, value in find_statements(equations.upper()): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) elif command == 'FRML': a, fr, n, udtryk = split_frml((command + ' ' + value).upper()) #print(fr,n, kw_frml_name(n.upper(),'EXO')) # we want a relatov adjustment newn = [n.strip()] nt = n + ' ' # an quick way to ensure length if n.startswith('_'): if 'J_' == nt[2:4]: newn.append('J') elif 'JR' == nt[2:4]: newn.append('JR') elif 'JD' == nt[2:4]: newn.append('JD') if 'D' == nt[4:5]: newn.append('EXO') if 'Z' == nt[5:6] or 'S' == nt[1]: newn.append('DAMP') outn = '<' + ','.join(newn) + '>' else: outn = n.strip() nymodel.append(command + ' ' + outn + ' ' + udtryk) else: nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
def frml_as_latex(frml_in,funks=[],allign= True, name=True,disp=True): ''' Display formula :funks: local functions :allign: allign = :name: also display the frml name ''' frmls = frml_in if type(frml_in) == list else [frml_in ] out = [] for frml in frmls: a,fr,n,udtryk= pt.split_frml(frml) out_udtryk = an_expression_to_latex(udtryk,funks = funks) out_frmlname = vtol(n) if name and n != '<>' else '' if allign: out_udtryk = out_udtryk.replace('=',' & = & ',1) out.append(f'{out_frmlname} {out_udtryk}') latex_out = r'\\'.join(out) if allign: latex_out = r'\begin{eqnarray*}'+latex_out+r'\end{eqnarray*}' if disp: display(Latex('$'+latex_out+'$')) else: return latex_out
list countrydanske = country : uk , DK, IR $ list countrynordea = country: SE , DK, AT $ do bankdic $ frml x {bank}_income = {bank}_a +{bank}_b $ do country{bank} $ frml x {bank}_{country} = 4242 $ enddo $ do countrydic $ frml x {bank}_{country}_all = 42 $ enddo $ enddo $ ''' print(dounloop(fmodel)) #%% print(stripstring(pastestring('a+b+log(x)', '_xx'), '_xx')) split_frml('FRML x ib =1+gris $') split_frml('FRML <res> ib =1+gris $') find_statements(' FRML x ib =1+gris $ frml <exo> hane= 27*ged$') find_statements('! FRML x ib =1+gris $ \n frml <exo> hane=27*ged $') find_statements( 'FRML x ib =1+gris*(ko+1) $ ! Comment \n frml <exo> hane= ged $') sub('O {who} of {from}', {'who': 'Knights', 'from': 'Ni'}) sub('O {who} of {from}, , we have brought you your {weed}', { 'who': 'Knights', 'from': 'Ni' }) sub_frml({'weed': ['scrubbery', 'herring']}, 'we have brought you your {weed}') sub_frml({ 'weed': ['scrubbery', 'herring'], 'where': ['land', 'sea']