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 pastestring(ind,post,funks=[]): ''' All variable names in a in a string **ind** is pasted with the string **post** This function can be used to awoid variable name conflict with the internal variable names in sympy. an advanced function ''' nt=udtryk_parse(ind,funks=funks) fib=[] for t in nt: if t.op: ud=t.op elif t.number: ud=t.number elif t.var: ud= t.var+ post+ ('('+(str(int(t.lag)))+')' if t.lag else '') fib.append(ud) return ''.join(fib)
def lagone(ind, funks=[]): ''' All variables in a string i s lagged one more time ''' nt = udtryk_parse(ind, funks=funks) fib = [] for t in nt: if t.op: ud = t.op elif t.number: ud = t.number elif t.var: lag = t.lag if t.lag else '0' org_lag = int(lag) new_lag = org_lag - 1 if lag == '+1': ud = t.var else: ud = t.var + f'({new_lag:+})' fib.append(ud) return ''.join(fib)
def stripstring(ind,post,funks=[]): ''' All variable names in a in a string is **ind** is stripped of the string **post**. This function reverses the pastestring process ''' nt=udtryk_parse(ind,funks=funks) fib=[] lenpost=len(post) for t in nt: if t.op: ud=t.op elif t.number: ud=t.number elif t.var: if t.var.endswith(post.upper()): ud= t.var[:-lenpost]+ ('('+(str(int(t.lag)))+')' if t.lag else '') else: print('Tryes to strip '+post +' from '+ind) fib.append(ud) return ''.join(fib)
def findendo(ind): ''' finds the equation for the first variable of a string''' def endovar(f): # Finds the first variable in a expression for t in udtryk_parse(f,funks=funks): if t.var: ud=t.var break return ud ind=re.sub(r'LOG\(','log(',ind) # sypy uses lover case for log and exp ind=re.sub(r'EXP\(','exp(',ind) lhs,rhs=ind.split('=',1) if len(udtryk_parse(lhs,funks=funks)) >=2: # we have an expression on the left hand side # print('Before >>',ind) endo=sympify(endovar(lhs)) kat=sympify('Eq('+lhs+','+rhs[0:-1]+')') # we take the the $ out endo_frml=solve(kat,endo,simplify=False,rational=False) # print('After >>', str(endo)+'=' + str(endo_frml[0])+'$') return str(endo)+'=' + str(endo_frml[0])+'$' else: # no need to solve this equation return ind
def an_expression_to_latex(exp,funks=[]): ''' Returns a latex string from a list of terms (defined in the modelpattern module) funks is a list of localy defines functions ''' def t_to_latex(t): if t.var: var =vtol(t.var) if t.lag: return f'{var}_{{t{t.lag}}}' else: return f'{var}_t' elif t.number: return t.number else: if t.op == '*': op=r'\times' elif t.op == '$': op='' else: op = t.op return op return ' '.join([t_to_latex(t) for t in pt.udtryk_parse(exp,funks=funks)])
# -*- coding: utf-8 -*- import modelpattern as mp import re def f(a): return a * 2 def t_to_latex(t): if t.var: var = re.sub(r'_', r'\_', t.var) if t.lag: return f'{var}_{{t{t.lag}}}' else: return f'{var}_t' elif t.number: return t.number else: return t.op.lower() p = mp.udtryk_parse('a+b__e+d(-1)+g(+1)+f(3) ', funks=[f]) temp = ' '.join([t_to_latex(t) for t in p])
def endovar(f): # Finds the first variable in a expression for t in udtryk_parse(f, funks=funks): if t.var: ud = t.var break return ud