用python求解同时多元多项式方程

时间:2012-12-11 15:40:22

标签: python math scipy polynomial-math sympy

编辑:我从我的方程中得到的参考包含了几个错误。我在这里修好了。解决方案现在可能真的有意义了!

当两层流体流过地形时,存在一个数字 取决于流的相对大小的不同解决方案 速度和流体中的波速。

critical-flow

这些被称为'超临界','次临界'和'批判'( 前两个我在这里称之为“额外关键”。)

以下等式定义了临界点之间的界限 和(h,U0)参数空间中的超临界行为:

eq1

eq2

我想消除d_1c(即我不在乎它是什么)并找到 (h, U_0)中这些方程的解。

简化因素:

  • 我只需要给出 d_0
  • 的答案
  • 我不需要确切的解决方案,只是解决方案的大纲 曲线,所以这可以通过分析或数字解决。
  • 我只想绘制区域(h,U0)=(0,0)到(0.5,1)。

我想使用Enthought中提供的模块来解决这个问题 分配(numpy,scipy,sympy),但真的不知道在哪里 开始。这是消除真正混淆的变量d1c 我。

以下是python中的等式:

def eq1(h, U0, d1c, d0=0.1):
    f = (U0) ** 2 * ((d0 ** 2 / d1c ** 3) + (1 - d0) ** 2 / (1 - d1c - d0) ** 3) - 1
    return f

def eq2(h, U0, d1c, d0=0.1):
    f = 0.5 * (U0) ** 2 * ((d0 ** 2 / d1c ** 2) - (1 - d0) ** 2 / (1 - d1c - d0) ** 2) + d1c + (h - d_0)
    return f

我期待一个有许多解决方案分支的解决方案(不是 总是身体,但不要担心)并且粗略地看 像这样:

critical-regime-diagram

我该如何实施?

3 个答案:

答案 0 :(得分:4)

半正式地,您要解决的问题如下:给定d0,求解逻辑公式“存在d1c使得eq1(h,U0,d1c,d0)= eq2(h,U0,d1c,对于h和U0,d0)= 0“。

存在一种将公式简化为多项式方程“P(h,U0)= 0”的算法,它被称为“量词消除”,它通常依赖于另一种算法“圆柱代数分解”。不幸的是,这尚未在sympy中实现。

但是,由于U0很容易被淘汰,因此您可以通过同情来找到答案。从

开始
h, U0, d1c, d0 = symbols('h, U0, d1c, d0')
f1 = (U0) ** 2 * ((d0 ** 2 / d1c ** 3) + (1 - d0) ** 2 / (1 - d1c - d0 * h) ** 3) - 1
f2 = U0**2 / 2 * ((d0 ** 2 / d1c ** 2) + (1 - d0) ** 2 / (1 - d1c - d0 * h)) + d1c + d0 * (h - 1)

现在,从f1中删除U0并将值插入f2(我正在“手动”而不是使用solve()来获取更漂亮的表达式):

U2_val = ((f1 + 1)/U0**2)**-1
f3 = f2.subs(U0**2, U2_val)

f3仅取决于h和d1c。此外,由于它是一个有理分数,我们只关心它的分子何时变为0,所以我们得到一个2个变量的多项式方程:

p3 = fraction(cancel(f3))

现在,对于给定的d0,您应该能够以数字方式反转p3.subs(d0,.1)以获得h(d1c),将其插回U0并将(h,U0)的参数图绘制为d1c的功能。

答案 1 :(得分:3)

让我先讨论消除d1c。想象一下,你设法按下第一个等式,得到d1c = f(U, h, d0)形式。然后,您将其替换为第二个等式,并在Uhd0之间建立一定的关系。固定d0后,这会定义两个变量Uh的单个等式,原则上,您可以从中找到任何给定U的变量h }。根据您的上一个草图,这似乎是您所谓的解决方案。 坏消息是从你的任何一个方程中得到d1c并不容易。好消息是你不需要。

fsolve可以采用一个方程组,比如说两个方程依赖于两个变量并给出解决方案。在这种情况下:修复h(已d0已修复),并将fsolve系统提供给您,将其视为变量U0d1c。记录U0的值,重复h的下一个值,依此类推。

请注意,与@duffymo的建议相反,我建议使用fsolve,或者至少从它开始,并且只有在它失去动力时才寻找其他求解器。

可能需要注意的是,对于U0 h,您需要一个以上的解决方案:fsolve需要一个初始猜测,并且没有简单的方法可以告诉它收敛到其中一个解决方案分支。如果结果证明是个问题,请查看brentq求解器。

另一种方法是观察您可以轻松地从系统中消除U0。这样,您将获得hd1c的单个等式,为d1c的每个值求解h,然后使用您的原始等式中的任何一个来计算U0 d1ch。{/ p>

使用fsolve

的示例
>>> from scipy.optimize import fsolve
>>> def f(x, p):
...   return x**2 -p
... 
>>> fsolve(f, 0.5, args=(2,))
array([ 1.41421356])
>>> 

此处args=(2,)是告诉fsolve如果f(x,2)=0您想要解决的问题,0.5x值的起始猜测的语法}}。

答案 2 :(得分:0)

使用非线性求解器(如Newton Raphson或BFGS)来求解同时的非线性方程。他们对初始条件和对基础的调节敏感,因此需要一些护理。