如何使用SymPy消去中间变量化简线性方程组,推导输出out关于输入inp的表达式
如何使用SymPy消去中间变量化简线性方程组,推导输出out关于输入inp的表达式
嘿,我来帮你搞定这个问题~你遇到的情况其实是SymPy的solve函数用法的小细节问题,咱们一步步来解决它。
首先,先明确你的目标:从这三个线性方程里消去err和fb,得到out关于inp的表达式,也就是最终的闭环传递函数 out = \frac{a}{1+af} \times inp。
为什么你的代码返回空列表?
当你调用solve(eqns, [out])时,SymPy没办法直接从方程组里单独解出out——因为out的表达式依赖于err和fb,而这两个变量又互相依赖,所以需要让SymPy同时求解这几个相关变量,再提取out的结果。
方法一:同时求解所有相关变量再提取
你可以让solve求解out、err、fb这三个变量,然后从结果字典里取出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




