重新排列s的方程式

2024-04-28 12:56:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种通用的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)]

我只是不知道如何提取未知量并创建错误函数。在

我试过了编译.解析()功能,它似乎给出了一个结构化的分解。在

谁能给我一些关于最佳方法的想法吗。在


Tags: 方法系统dbatw2mw方程dbodbr
2条回答

如果您不想为自己的表达式语言编写解析器,那么可以尝试使用Python语法。不要使用编译器模块;而是使用某种抽象语法。从2.5开始,您可以使用-ast模块:

py> import _ast                                                                     
py> tree = compile("e1,e2=0.58,0.62", "<string>", "exec", _ast.PyCF_ONLY_AST)
py> tree
<_ast.Module object at 0xb7cd5fac>                                    
py> tree.body[0]
<_ast.Assign object at 0xb7cd5fcc>
py> tree.body[0].targets[0]
<_ast.Tuple object at 0xb7cd5fec>
py> tree.body[0].targets[0].elts
[<_ast.Name object at 0xb7cd5e4c>, <_ast.Name object at 0xb7cd5f6c>]
py> tree.body[0].targets[0].elts[0].id
'e1'
py> tree.body[0].targets[0].elts[1].id
'e2'

在早期版本中,必须使用解析器.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)。您可能还需要一种输入初始猜测的方法。在

我很想知道有没有其他的替代方法。在

相关问题 更多 >