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 createarray(in_equations, listin=False): ''' expands all to_array(list) in a model returns a new model''' nymodel = [] equations = in_equations[:].upper() # we want do change the e liste_dict = listin if listin else list_extract( equations) # Search the whold model for lists for comment, command, value in find_statements(equations): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) else: while 'TO_ARRAY(' in value.upper(): forcreate, createudtryk, eftercreate = find_arg( 'TO_ARRAY', value.upper()) temp = createudtryk.split(',', 2) mat_name = temp[-1] create_row = temp[0] row_dict = liste_dict[create_row] if len(temp) == 2: ibsud = '[' + sub_frml(row_dict, mat_name, ',', '', sep='') + ']' else: create_column = temp[1] column_dict = liste_dict[create_column] ibsud0 = '[' + sub_frml( column_dict, mat_name, ',', '', sep='') + ']' ibsud = '[' + sub_frml(row_dict, ibsud0, ',\n', '', sep='') + ']' value = forcreate + 'array(\n' + ibsud + ')' + eftercreate nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
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 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 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 argunroll(in_equations,listin=False): ''' expands all ARGEXPAND(list,'expression') in a model returns a new model''' nymodel = [] equations = in_equations[:].upper() # we want do change the e liste_dict = listin if listin else list_extract(equations) # Search the whold model for lists for comment, command, value in find_statements(equations): # print('>>',comment,'<',command,'>',value) if comment: nymodel.append(comment) else: while 'ARGEXPAND(' in value.upper(): forsum, sumudtryk, eftersum = find_arg('ARGEXPAND', value.upper()) sumover, sumled = sumudtryk.split(',', 1) current_dict = liste_dict[sumover] ibsud = sub_frml(current_dict, sumled, ',', '', sep='') value = forsum + '' + ibsud + '' + eftersum nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
def dounloop(in_equations, listin=False): ''' Expands (unrolls do loops in a model template goes trough a model template until there is no more nested do loops ''' equations = in_equations[:].upper() # we want do change the equations liste_dict = listin if listin else list_extract( equations) # Search the whold model for lists rest = 1 while rest: # We want to eat all doo loops nymodel = [] domodel = [] dolevel = 0 rest = 0 liste_name, liste_key, liste_select = '', '', '' for comment, command, value in find_statements(equations): # print('>>',comment,'<',command,'>',value) if command.upper() == 'DO': dolevel = dolevel + 1 if dolevel >= 2: rest = 1 # do we have more doolops domodel.append(command + ' ' + value) #========================================================================= # else: # find listname key=select #========================================================================= elif dolevel == 1: liste_name = [ t.strip().upper() for t in re.split(r'[\s,]\s*', value[:-1]) if t != '' ] current_dict = liste_dict[liste_name[0]] #print('listenavn ',liste_name, current_dict) #ibdic, text, plus='', xvar='', lig='', sep='\n',selectlist=None,match='' if len(liste_name) == 1: liste_key, liste_select = '', '' elif len(liste_name) == 4: liste_key, liste_select = liste_name[1], liste_name[3] # current_dict=liste_dict[value[0:-2].strip()] # find the name of the list else: assert 1 == 2, print( ' *** error in DO statement either 1 or 4 arguments:', comment, command, value) domodel = [] elif (command.upper() == 'ENDDO'): dolevel = dolevel - 1 if dolevel == 0: if len(liste_name) == 1 or len(liste_name) == 4 or len( liste_name) == 5: ibsud = sub_frml(current_dict, '\n'.join(domodel), plus='', sep='\n', xvar=liste_key, lig=liste_select) else: print('Fejl i liste', liste_name) print('Ibsud>', ibsud) nymodel.append('\n' + ibsud + '\n') elif dolevel >= 1: domodel.append(command + ' ' + value + '\n') elif dolevel >= 1: # a command to store for do looping if comment: domodel.append(comment + '') else: domodel.append(command + ' ' + value) else: # a command outside a dooloop if comment: nymodel.append(comment) else: nymodel.append(command + ' ' + value) equations = '\n'.join(nymodel) return equations
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'] }, 'we have brought you your {weed} from {where} ') sub_frml({