如何动态生成一条python符号语句?

2022-04-06 00:00:00 python sympy

问题描述

我正在尝试编写一个例程来规格化(重写)LHS上可能有多个符号的数学方程式,以便它只有一个符号。

以下代码说明了我想要做的事情

假设我有一个等式

ln(x)-ln(x1)= -(a+by)

我要求解x或返回

x=x1*exp(-a+by)

使用sympy我可以执行以下操作

from sympy import *

formula=' log(x)-log(x1) =-(a+b*y)'
lhs,rhs=formula.split('=',1)
x,x_1,y,a,b,y=symbols('x x_1 y a b y')    
r=sympy.solve(eval(lhs)-eval(rhs),x)
r

==> 
Output: [x1*exp(-a - b*y)]

我正在尝试为一系列输入行自动执行此操作,如下所示

from sympy import *
import re

# eventually to be read ina loop from a file
formula="DLOG(SAUMMCREDBISCN/SAUNECONPRVTXN) =-0.142368233181-0.22796245228*(LOG(SAUMMCREDBISCN(-1)/SAUNECONPRVTXN(-1))+0.2*((SAUMMLOANINTRCN(-1)-SAUINTR(-1))/100)-LOG(SAUNYGDPMKTPKN(-1)))+0.576050997065*SAUNYGDPGAP_/100"

#try to convert formula into a string containing just the synbols
sym1=formula.replace("*"," ")
sym1=sym1.replace("DLOG"," ")
sym1=sym1.replace("LOG"," ")
sym1=sym1.replace("EXP"," ")
sym1=sym1.replace("RECODE"," ")


sym1=re.sub('[()/+-=]',' ',sym1)
sym1=re.sub(' +',' ',sym1)
#This logic works for this particular formula
sym1

#now generate a string that has, instead of spaces between symbols
ss2=sym1.replace(' ',',')

#This is the part that does not work I want to generate a command that effectively says
#symbol,symbol2,..,symboln=symbols('symbol1 symbol2 ... symboln')

#tried this but it fails
eval(ss2)=symbols(sym1)

生成结果

    eval(ss2)=symbols(sym1)
                           ^
SyntaxError: can't assign to function call

如对此py新手有任何帮助,我们将不胜感激。


解决方案

我的一位同事(Ib Hansen)为我提供了一个非常好的、优雅的解决方案,解决了最初的问题(如何解决复杂的表达式),绕过了我最初的问题正在努力解决的字符串操作解决方案,也就是大多数答案得到了解决。

他的解决方案是使用渐近和从渐变求解

from sympy import sympify, solve
import re

def normalize(var,eq,simplify=False,manual=False):  
    '''normalize an equation with respect to var using sympy'''
    lhs, rhs = eq.split('=')
    kat = sympify(f'Eq({lhs},{rhs})')
    var_sym = sympify(var)
    out = str(solve(kat, var_sym,simplify=simplify,manual=manual))[1:-1] 
    return f'{var} = {out}'

这非常有效

from sympy import sympify, solve
import re

def norm(var,eq,simplify=False,manual=False):  
    '''normalize an equation with respect to var using sympy'''
    lhs, rhs = eq.split('=')
    kat = sympify(f'Eq({lhs},{rhs})')
    var_sym = sympify(var)
    out = str(solve(kat, var_sym,simplify=simplify,manual=manual))[1:-1] # simplify takes for ever
    return f'{var} = {out}'

``` Re write equation spelling out the dlog (delta log) function that python does no know, and putting log into lowe case '''

test8=norm('saummcredbiscn','log(saummcredbiscn/sauneconprvtxn) -log(saummcredbiscn(-1)/sauneconprvtxn(-1)) =-0.142368233181-0.22796245228*(log(saummcredbiscn(-1)/sauneconprvtxn(-1))+0.2*((saummloanintrcn(-1)-sauintr(-1))/100)-log(saunygdpmktpkn(-1)))+0.576050997065*saunygdpgap_/100')
print (test8)

结果

saummcredbiscn = 0.867301828366361*sauneconprvtxn*(saummcredbiscn(-1.0)/sauneconprvtxn(-1.0))**(19300938693/25000000000)*saunygdpmktpkn(-1.0)**(5699061307/25000000000)*exp(0.00576050997065*saunygdpgap_ + 0.00045592490456*sauintr(-1.0) - 0.00045592490456*saummloanintrcn(-1.0)

相关文章