You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用SymPy消去中间变量化简线性方程组,推导输出out关于输入inp的表达式

如何使用SymPy消去中间变量化简线性方程组,推导输出out关于输入inp的表达式

嘿,我来帮你搞定这个问题~你遇到的情况其实是SymPy的solve函数用法的小细节问题,咱们一步步来解决它。

首先,先明确你的目标:从这三个线性方程里消去errfb,得到out关于inp的表达式,也就是最终的闭环传递函数 out = \frac{a}{1+af} \times inp

为什么你的代码返回空列表?

当你调用solve(eqns, [out])时,SymPy没办法直接从方程组里单独解出out——因为out的表达式依赖于errfb,而这两个变量又互相依赖,所以需要让SymPy同时求解这几个相关变量,再提取out的结果。

方法一:同时求解所有相关变量再提取

你可以让solve求解outerrfb这三个变量,然后从结果字典里取出out的表达式:

from sympy import symbols, Eq, solve

inp, err, out, fb, a, f = symbols("inp err out fb a f")

eqns = [
    Eq(err, inp - fb),
    Eq(out, a * err),
    Eq(fb, f * out),
]

# 求解所有三个变量,返回字典形式的解
solution = solve(eqns, [out, err, fb], dict=True)[0]
# 提取out的表达式
print(solution[out])

运行这段代码,你会得到a*inp/(a*f + 1),也就是你想要的化简结果。

方法二:手动代入化简

如果你想更直观地看到消元过程,可以用subs方法一步步替换中间变量:

from sympy import symbols, Eq, solve, simplify

inp, err, out, fb, a, f = symbols("inp err out fb a f")

# 第一步:把fb用f*out代入第一个方程,得到err关于inp和out的表达式
err_expr = Eq(err, inp - fb).subs(fb, f*out).rhs
# 第二步:把err的表达式代入第二个方程,得到只含out和inp的方程
final_eq = Eq(out, a * err_expr)
# 第三步:求解这个方程的out
solution = solve(final_eq, out)[0]
# 可选:化简表达式
print(simplify(solution))

这种方法更贴近手动推导的过程,也能得到同样的正确结果。

方法三:用线性方程组专用的linsolve

因为你的方程组是线性的,用linsolve会更高效,它专门处理线性方程组的求解:

from sympy import symbols, Eq, linsolve

inp, err, out, fb, a, f = symbols("inp err out fb a f")

# 先把方程整理成标准线性形式(所有项移到左边)
eqns = [
    Eq(err + fb, inp),
    Eq(-a*err + out, 0),
    Eq(-f*out + fb, 0)
]

# 求解(out, err, fb)
solution = linsolve(eqns, (out, err, fb))
# 提取out的表达式
print(solution.args[0][0])

这个方法同样能得到a*inp/(a*f + 1)的结果。

验证结果

咱们可以把结果代回原方程验证:

  • 假设out = a*inp/(1+af),那么fb = f*out = a*f*inp/(1+af)
  • 计算err = inp - fb = inp - a*f*inp/(1+af) = inp*(1+af - af)/(1+af) = inp/(1+af)
  • 再计算a*err = a*inp/(1+af) = out,完全符合第二个方程,说明结果是对的!

备注:内容来源于stack exchange,提问作者August West

火山引擎 最新活动