使用SymPy消除变量以关联Python中的两个函数

时间:2018-10-31 22:18:54

标签: python sympy equation equation-solving

我有两个由变量“ t”参数化的方程式。这些看起来像:

X = p(t) 
Y = q(t)

其中p和q是t中的多项式。我想使用Python的SymPy库消除t变量,并为某些函数X表示Y = F(X)。我曾尝试在SymPy中使用Solve(),但这不能很好地工作。我知道Maple和Mathematica都具有可以完成此操作的exclude()函数,但是我想知道Python是否可能具有执行此操作的通用函数。

3 个答案:

答案 0 :(得分:2)

我从https://reference.wolfram.com/language/ref/Eliminate.html的“范围”部分引用了此示例。

消除[2 x + 3 y + 4 z == 1 && 9 x + 8 y + 7 z == 2,z]

	

<div class="table-stats order-table ov-h">
    		<table class="table">
    			<thead>
    				<tr>
    					<th class="serial">NSN</th>
    					<th>Nomenclature</th>
    					<th>Award Date</th>
    					<th>Award #</th>
    					<th>Quantity</th>
    					<th>Price per Unit</th>
    				</tr>
    			</thead>
    			<tbody id="inventoryContainer">
    				<tr>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    				</tr>
    				<tr>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    					<td>test</td>
    				</tr>

    			</tbody>

    		</table><button class="btn"> Save </button>
    	</div>
  • 求解>>> from sympy import * >>> var('x y z') (x, y, z) >>> solve(2*x+3*y+4*z-1, z) [-x/2 - 3*y/4 + 1/4] >>> solve(9*x+8*y+7*z-2, z) [-9*x/7 - 8*y/7 + 2/7] >>> (-9*x/7 - 8*y/7 + Rational(2,7))-(-x/2 - 3*y/4 + Rational(1,4)).simplify() -11*x/14 - 11*y/28 + 1/28 >>> 28*((-9*x/7 - 8*y/7 + Rational(2,7))-(-x/2 - 3*y/4 + Rational(1,4)).simplify()) -22*x - 11*y + 1 的每个方程式。
  • 从另一个中减去z的一个表达式。
  • 仅注意,数字小数部分需要进行编码-我使用了z,因为我忘记了其他方法-因此使用了分数算术。
  • 我乘以除去分母。
  • 此方法仅适用于消除单个变量。我没有考虑第二个及后续示例。

我希望这是有用的。

答案 1 :(得分:2)

这是一个经过严格测试的简单例程

def eliminate(eqs, z):
    """return eqs with parameter z eliminated from each equation; the first
    element in the returned list will be the definition of z that was used
    to eliminate z from the other equations.

    Examples
    ========

    >>> eqs = [Eq(2*x + 3*y + 4*z, 1),
    ...        Eq(9*x + 8*y + 7*z, 2)]
    >>> eliminate(eqs, z)
    [Eq(z, -x/2 - 3*y/4 + 1/4), Eq(11*x/2 + 11*y/4 + 7/4, 2)]
    >>> Eq(y,solve(_[1], y)[0])
    Eq(y, -2*x + 1/11)
    """
    from sympy.solvers.solveset import linsolve
    Z = Dummy()
    rv = []
    for i, e in enumerate(eqs):
        if z not in e.free_symbols:
            continue
        e = e.subs(z, Z)
        if z in e.free_symbols:
            break
        try:
            s = linsolve([e], Z)
            if s:
                zi = list(s)[0][0]
                rv.append(Eq(z, zi))
                rv.extend([eqs[j].subs(z, zi)
                    for j in range(len(eqs)) if j != i])
                return rv
        except ValueError:
            continue
    raise ValueError('only a linear parameter can be eliminated')

this issue中有一个更复杂的例程。

答案 2 :(得分:0)

假设您要求解eqs的方程

z_o

作为z的函数。可以通过解决两者 z_o theta

solve(
    [
        Eq(z, sin(theta)),
        Eq(z_o, cos(theta))
    ],
    [z_o, theta],
    dict=True
)

产生

res

然后,您可以丢弃theta的结果并使用其余的结果。

这并非在所有情况下都有效-它要求中间变量是sympy可以直接解决的问题。