我正在寻找一种通用的python方法来将文本处理成可解的方程。在
例如:
可能有一些常量要初始化
e1,e2=0.58,0.62
ma1,ma2=0.85,1.15
mw=0.8
Cpa,Cpw=1.023,4.193
dba,dbr=0.0,25.0
以及一组方程式(这里写的是为了可读性,而不是为了解算器)
^{pr2}$这就留下了5个未知数,所以推测这个系统可以被解决。在
Q, dbo, dbr, tw1, tw2
实际系统是非线性的,而且要复杂得多。在
我已经用scipy,Delphi,Sage解决了这个简单的例子。。。所以我不是在寻找解决问题的部分。在
方程直接输入到文本编辑器中,我需要一个Python程序给我一个未知数组和一个错误函数数组。在
y = mysolver.fsolve(f, x)
对于上面的例子
x=[Q,dbo,dbr,tw1,tw2]
f=[Q-e1*ma1*Cpa*(tw1-dba), Q-ma1*Cpa*(dbs-dba), Q-mw*Cpw*(tw1-tw2),
Q-e2*ma2*Cpa*(dbr-tw2), Q-ma2*Cpa*(dbr-dbo)]
我只是不知道如何提取未知量并创建错误函数。在
我试过了编译.解析()功能,它似乎给出了一个结构化的分解。在
谁能给我一些关于最佳方法的想法吗。在
如果您不想为自己的表达式语言编写解析器,那么可以尝试使用Python语法。不要使用编译器模块;而是使用某种抽象语法。从2.5开始,您可以使用-ast模块:
在早期版本中,必须使用解析器.suite,这为您提供了一个更难处理的具体语法树。在
实际上,我在python中实现了完全相同的东西。我也熟悉尤里卡和你提到的其他项目。您可以在xyzsolve.appspot.com网站(为无耻的插头感到抱歉)。实现是用所有python实现的。我将列出代码所经历的迭代:
迭代0:对等式中的每个变量进行简单的搜索和替换,并用变量的值替换变量。例如,如果x和y的值为1.1和2.2,x*y将变成1.1*2.2。在得到转换后的字符串之后,可以使用eval并将其值放入残差(或者在您的例子中是f向量)。Scipy的fsolve/fmin函数允许您向残差函数传递额外的参数,因此请充分利用它。一、 传递包含每个命名变量的索引的字典。你的dict应该包含类似{'x':0,'y':1}的内容,然后你可以对每个等式进行搜索和替换。这是可行的,但是非常慢,因为每次调用剩余函数时都要进行搜索替换。在
迭代1:与迭代0相同,只是直接用x数组元素替换变量,所以“y”将变成“x[1]”。实际上,您可以通过这些来生成一个函数字符串;类似于“def f(x):return x[0]+x[1],x[0]-x[1]”。然后可以使用python中的exec函数创建要传递给fsolve/fmin的函数。如果您的方程是有效的python语法形式,那么您可以在这一点上停止。如果您想支持更广泛的表达式输入格式,那么这种方法做不了太多。在
迭代2:实现一个定制的lexer和解析器。这并不像听起来那么难。我用http://www.evanfosmark.com/2009/02/sexy-lexing-with-python/表示lexer。我创建了一个递归下降解析器(这一点也不难,大约100行代码)来解析每个等式。这为您提供了方程格式的完全灵活性。我只需要在不同的列表中记录变量,等式两边的常量。当解析器解析等式时,它构建一个类似于“var_000+var_001*var_002”的表达式字符串,依此类推。最后,我只需用x向量的适当索引替换“var_000”。所以“var_000”变成“x[0]”,依此类推。如果你想的话,你可以构建一个AST并做很多更复杂的转换,但是我在这里停了下来。在
最后,您可能还需要考虑输入方程的类型。有很多无害的非线性方程不能用fsolve来求解(它使用MINPACK hybrdj)。您可能还需要一种输入初始猜测的方法。在
我很想知道有没有其他的替代方法。在
相关问题 更多 >
编程相关推荐